Переглянути джерело

feat: remove cloud backups (#574)

Karol Sójko 2 роки тому
батько
коміт
484f554339

+ 8 - 70
packages/auth/bin/backup.ts

@@ -14,10 +14,9 @@ import { Env } from '../src/Bootstrap/Env'
 import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
 import { DomainEventFactoryInterface } from '../src/Domain/Event/DomainEventFactoryInterface'
 import { SettingRepositoryInterface } from '../src/Domain/Setting/SettingRepositoryInterface'
-import { MuteFailedBackupsEmailsOption, MuteFailedCloudBackupsEmailsOption, SettingName } from '@standardnotes/settings'
+import { MuteFailedBackupsEmailsOption, SettingName } from '@standardnotes/settings'
 import { RoleServiceInterface } from '../src/Domain/Role/RoleServiceInterface'
 import { PermissionName } from '@standardnotes/features'
-import { SettingServiceInterface } from '../src/Domain/Setting/SettingServiceInterface'
 
 const inputArgs = process.argv.slice(2)
 const backupProvider = inputArgs[0]
@@ -26,46 +25,13 @@ const backupFrequency = inputArgs[1]
 const requestBackups = async (
   settingRepository: SettingRepositoryInterface,
   roleService: RoleServiceInterface,
-  settingService: SettingServiceInterface,
   domainEventFactory: DomainEventFactoryInterface,
   domainEventPublisher: DomainEventPublisherInterface,
 ): Promise<void> => {
-  let settingName: SettingName,
-    permissionName: PermissionName,
-    muteEmailsSettingName: string,
-    muteEmailsSettingValue: string,
-    providerTokenSettingName: SettingName
-  switch (backupProvider) {
-    case 'email':
-      settingName = SettingName.create(SettingName.NAMES.EmailBackupFrequency).getValue()
-      permissionName = PermissionName.DailyEmailBackup
-      muteEmailsSettingName = SettingName.NAMES.MuteFailedBackupsEmails
-      muteEmailsSettingValue = MuteFailedBackupsEmailsOption.Muted
-      break
-    case 'dropbox':
-      settingName = SettingName.create(SettingName.NAMES.DropboxBackupFrequency).getValue()
-      permissionName = PermissionName.DailyDropboxBackup
-      muteEmailsSettingName = SettingName.NAMES.MuteFailedCloudBackupsEmails
-      muteEmailsSettingValue = MuteFailedCloudBackupsEmailsOption.Muted
-      providerTokenSettingName = SettingName.create(SettingName.NAMES.DropboxBackupToken).getValue()
-      break
-    case 'one_drive':
-      settingName = SettingName.create(SettingName.NAMES.OneDriveBackupFrequency).getValue()
-      permissionName = PermissionName.DailyOneDriveBackup
-      muteEmailsSettingName = SettingName.NAMES.MuteFailedCloudBackupsEmails
-      muteEmailsSettingValue = MuteFailedCloudBackupsEmailsOption.Muted
-      providerTokenSettingName = SettingName.create(SettingName.NAMES.OneDriveBackupToken).getValue()
-      break
-    case 'google_drive':
-      settingName = SettingName.create(SettingName.NAMES.GoogleDriveBackupFrequency).getValue()
-      permissionName = PermissionName.DailyGDriveBackup
-      muteEmailsSettingName = SettingName.NAMES.MuteFailedCloudBackupsEmails
-      muteEmailsSettingValue = MuteFailedCloudBackupsEmailsOption.Muted
-      providerTokenSettingName = SettingName.create(SettingName.NAMES.GoogleDriveBackupToken).getValue()
-      break
-    default:
-      throw new Error(`Not handled backup provider: ${backupProvider}`)
-  }
+  const settingName = SettingName.create(SettingName.NAMES.EmailBackupFrequency).getValue()
+  const permissionName = PermissionName.DailyEmailBackup
+  const muteEmailsSettingName = SettingName.NAMES.MuteFailedBackupsEmails
+  const muteEmailsSettingValue = MuteFailedBackupsEmailsOption.Muted
 
   const stream = await settingRepository.streamAllByNameAndValue(settingName, backupFrequency)
 
@@ -94,39 +60,14 @@ const requestBackups = async (
               userHasEmailsMuted = emailsMutedSetting.value === muteEmailsSettingValue
             }
 
-            if (backupProvider === 'email') {
-              await domainEventPublisher.publish(
-                domainEventFactory.createEmailBackupRequestedEvent(
-                  setting.setting_user_uuid,
-                  emailsMutedSetting?.uuid as string,
-                  userHasEmailsMuted,
-                ),
-              )
-
-              callback()
-
-              return
-            }
-
-            const cloudBackupProviderToken = await settingService.findSettingWithDecryptedValue({
-              settingName: providerTokenSettingName,
-              userUuid: setting.setting_user_uuid,
-            })
-            if (cloudBackupProviderToken === null || cloudBackupProviderToken.value === null) {
-              callback()
-
-              return
-            }
-
             await domainEventPublisher.publish(
-              domainEventFactory.createCloudBackupRequestedEvent(
-                backupProvider.toUpperCase() as 'DROPBOX' | 'ONE_DRIVE' | 'GOOGLE_DRIVE',
-                cloudBackupProviderToken.value,
+              domainEventFactory.createEmailBackupRequestedEvent(
                 setting.setting_user_uuid,
                 emailsMutedSetting?.uuid as string,
                 userHasEmailsMuted,
               ),
             )
+
             callback()
           },
         }),
@@ -149,13 +90,10 @@ void container.load().then((container) => {
 
   const settingRepository: SettingRepositoryInterface = container.get(TYPES.SettingRepository)
   const roleService: RoleServiceInterface = container.get(TYPES.RoleService)
-  const settingService: SettingServiceInterface = container.get(TYPES.SettingService)
   const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.DomainEventFactory)
   const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.DomainEventPublisher)
 
-  Promise.resolve(
-    requestBackups(settingRepository, roleService, settingService, domainEventFactory, domainEventPublisher),
-  )
+  Promise.resolve(requestBackups(settingRepository, roleService, domainEventFactory, domainEventPublisher))
     .then(() => {
       logger.info(`${backupFrequency} ${backupProvider} backup requesting complete`)
 

+ 0 - 28
packages/auth/src/Domain/Event/DomainEventFactory.ts

@@ -7,7 +7,6 @@ import {
   UserRegisteredEvent,
   UserRolesChangedEvent,
   EmailBackupRequestedEvent,
-  CloudBackupRequestedEvent,
   ListedAccountRequestedEvent,
   UserDisabledSessionUserAgentLoggingEvent,
   SharedSubscriptionInvitationCreatedEvent,
@@ -254,33 +253,6 @@ export class DomainEventFactory implements DomainEventFactoryInterface {
     }
   }
 
-  createCloudBackupRequestedEvent(
-    cloudProvider: 'DROPBOX' | 'ONE_DRIVE' | 'GOOGLE_DRIVE',
-    cloudProviderToken: string,
-    userUuid: string,
-    muteEmailsSettingUuid: string,
-    userHasEmailsMuted: boolean,
-  ): CloudBackupRequestedEvent {
-    return {
-      type: 'CLOUD_BACKUP_REQUESTED',
-      createdAt: this.timer.getUTCDate(),
-      meta: {
-        correlation: {
-          userIdentifier: userUuid,
-          userIdentifierType: 'uuid',
-        },
-        origin: DomainEventService.Auth,
-      },
-      payload: {
-        cloudProvider,
-        cloudProviderToken,
-        userUuid,
-        userHasEmailsMuted,
-        muteEmailsSettingUuid,
-      },
-    }
-  }
-
   createEmailBackupRequestedEvent(
     userUuid: string,
     muteEmailsSettingUuid: string,

+ 0 - 8
packages/auth/src/Domain/Event/DomainEventFactoryInterface.ts

@@ -2,7 +2,6 @@ import { ProtocolVersion, JSONString } from '@standardnotes/common'
 import { Predicate, PredicateVerificationResult } from '@standardnotes/predicates'
 import {
   AccountDeletionRequestedEvent,
-  CloudBackupRequestedEvent,
   UserRegisteredEvent,
   UserRolesChangedEvent,
   UserEmailChangedEvent,
@@ -42,13 +41,6 @@ export interface DomainEventFactoryInterface {
     muteEmailsSettingUuid: string,
     userHasEmailsMuted: boolean,
   ): EmailBackupRequestedEvent
-  createCloudBackupRequestedEvent(
-    cloudProvider: 'DROPBOX' | 'ONE_DRIVE' | 'GOOGLE_DRIVE',
-    cloudProviderToken: string,
-    userUuid: string,
-    muteEmailsSettingUuid: string,
-    userHasEmailsMuted: boolean,
-  ): CloudBackupRequestedEvent
   createAccountDeletionRequestedEvent(dto: {
     userUuid: string
     userCreatedAtTimestamp: number

+ 1 - 118
packages/auth/src/Domain/Setting/SettingInterpreter.spec.ts

@@ -1,5 +1,4 @@
 import {
-  CloudBackupRequestedEvent,
   DomainEventPublisherInterface,
   EmailBackupRequestedEvent,
   MuteEmailsSettingChangedEvent,
@@ -9,7 +8,6 @@ import {
   EmailBackupFrequency,
   LogSessionUserAgentOption,
   MuteMarketingEmailsOption,
-  OneDriveBackupFrequency,
   SettingName,
 } from '@standardnotes/settings'
 import 'reflect-metadata'
@@ -30,8 +28,7 @@ describe('SettingInterpreter', () => {
   let settingDecrypter: SettingDecrypterInterface
   let logger: Logger
 
-  const createInterpreter = () =>
-    new SettingInterpreter(domainEventPublisher, domainEventFactory, settingRepository, settingDecrypter, logger)
+  const createInterpreter = () => new SettingInterpreter(domainEventPublisher, domainEventFactory, settingRepository)
 
   beforeEach(() => {
     user = {
@@ -53,9 +50,6 @@ describe('SettingInterpreter', () => {
     domainEventFactory.createEmailBackupRequestedEvent = jest
       .fn()
       .mockReturnValue({} as jest.Mocked<EmailBackupRequestedEvent>)
-    domainEventFactory.createCloudBackupRequestedEvent = jest
-      .fn()
-      .mockReturnValue({} as jest.Mocked<CloudBackupRequestedEvent>)
     domainEventFactory.createUserDisabledSessionUserAgentLoggingEvent = jest
       .fn()
       .mockReturnValue({} as jest.Mocked<UserDisabledSessionUserAgentLoggingEvent>)
@@ -124,70 +118,6 @@ describe('SettingInterpreter', () => {
     expect(domainEventFactory.createEmailBackupRequestedEvent).not.toHaveBeenCalled()
   })
 
-  it('should trigger cloud backup if dropbox backup setting is created', async () => {
-    settingRepository.findOneByNameAndUserUuid = jest.fn().mockReturnValue(null)
-
-    await createInterpreter().interpretSettingUpdated(SettingName.NAMES.DropboxBackupToken, user, 'test-token')
-
-    expect(domainEventPublisher.publish).toHaveBeenCalled()
-    expect(domainEventFactory.createCloudBackupRequestedEvent).toHaveBeenCalledWith(
-      'DROPBOX',
-      'test-token',
-      '4-5-6',
-      '',
-      false,
-    )
-  })
-
-  it('should trigger cloud backup if dropbox backup setting is created - muted emails', async () => {
-    settingRepository.findOneByNameAndUserUuid = jest.fn().mockReturnValue({
-      name: SettingName.NAMES.MuteFailedCloudBackupsEmails,
-      uuid: '6-7-8',
-      value: 'muted',
-    } as jest.Mocked<Setting>)
-
-    await createInterpreter().interpretSettingUpdated(SettingName.NAMES.DropboxBackupToken, user, 'test-token')
-
-    expect(domainEventPublisher.publish).toHaveBeenCalled()
-    expect(domainEventFactory.createCloudBackupRequestedEvent).toHaveBeenCalledWith(
-      'DROPBOX',
-      'test-token',
-      '4-5-6',
-      '6-7-8',
-      true,
-    )
-  })
-
-  it('should trigger cloud backup if google drive backup setting is created', async () => {
-    settingRepository.findOneByNameAndUserUuid = jest.fn().mockReturnValue(null)
-
-    await createInterpreter().interpretSettingUpdated(SettingName.NAMES.GoogleDriveBackupToken, user, 'test-token')
-
-    expect(domainEventPublisher.publish).toHaveBeenCalled()
-    expect(domainEventFactory.createCloudBackupRequestedEvent).toHaveBeenCalledWith(
-      'GOOGLE_DRIVE',
-      'test-token',
-      '4-5-6',
-      '',
-      false,
-    )
-  })
-
-  it('should trigger cloud backup if one drive backup setting is created', async () => {
-    settingRepository.findOneByNameAndUserUuid = jest.fn().mockReturnValue(null)
-
-    await createInterpreter().interpretSettingUpdated(SettingName.NAMES.OneDriveBackupToken, user, 'test-token')
-
-    expect(domainEventPublisher.publish).toHaveBeenCalled()
-    expect(domainEventFactory.createCloudBackupRequestedEvent).toHaveBeenCalledWith(
-      'ONE_DRIVE',
-      'test-token',
-      '4-5-6',
-      '',
-      false,
-    )
-  })
-
   it('should trigger mute subscription emails rejection if mute setting changed', async () => {
     settingRepository.findOneByNameAndUserUuid = jest.fn().mockReturnValue(null)
 
@@ -204,51 +134,4 @@ describe('SettingInterpreter', () => {
       username: 'test@test.te',
     })
   })
-
-  it('should trigger cloud backup if backup frequency setting is updated and a backup token setting is present', async () => {
-    settingRepository.findLastByNameAndUserUuid = jest.fn().mockReturnValueOnce({
-      name: SettingName.NAMES.OneDriveBackupToken,
-      serverEncryptionVersion: 1,
-      value: 'encrypted-backup-token',
-      sensitive: true,
-    } as jest.Mocked<Setting>)
-
-    await createInterpreter().interpretSettingUpdated(SettingName.NAMES.OneDriveBackupFrequency, user, 'daily')
-
-    expect(domainEventPublisher.publish).toHaveBeenCalled()
-    expect(domainEventFactory.createCloudBackupRequestedEvent).toHaveBeenCalledWith(
-      'ONE_DRIVE',
-      'decrypted',
-      '4-5-6',
-      '',
-      false,
-    )
-  })
-
-  it('should not trigger cloud backup if backup frequency setting is updated as disabled', async () => {
-    settingRepository.findLastByNameAndUserUuid = jest.fn().mockReturnValueOnce({
-      name: SettingName.NAMES.OneDriveBackupToken,
-      serverEncryptionVersion: 1,
-      value: 'encrypted-backup-token',
-      sensitive: true,
-    } as jest.Mocked<Setting>)
-
-    await createInterpreter().interpretSettingUpdated(
-      SettingName.NAMES.OneDriveBackupFrequency,
-      user,
-      OneDriveBackupFrequency.Disabled,
-    )
-
-    expect(domainEventPublisher.publish).not.toHaveBeenCalled()
-    expect(domainEventFactory.createCloudBackupRequestedEvent).not.toHaveBeenCalled()
-  })
-
-  it('should not trigger cloud backup if backup frequency setting is updated and a backup token setting is not present', async () => {
-    settingRepository.findLastByNameAndUserUuid = jest.fn().mockReturnValueOnce(null)
-
-    await createInterpreter().interpretSettingUpdated(SettingName.NAMES.OneDriveBackupFrequency, user, 'daily')
-
-    expect(domainEventPublisher.publish).not.toHaveBeenCalled()
-    expect(domainEventFactory.createCloudBackupRequestedEvent).not.toHaveBeenCalled()
-  })
 })

+ 1 - 103
packages/auth/src/Domain/Setting/SettingInterpreter.ts

@@ -1,44 +1,21 @@
 import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
 import { EmailLevel } from '@standardnotes/domain-core'
 import {
-  DropboxBackupFrequency,
   EmailBackupFrequency,
-  GoogleDriveBackupFrequency,
   LogSessionUserAgentOption,
   MuteFailedBackupsEmailsOption,
-  MuteFailedCloudBackupsEmailsOption,
-  OneDriveBackupFrequency,
   SettingName,
 } from '@standardnotes/settings'
 import { inject, injectable } from 'inversify'
-import { Logger } from 'winston'
+
 import TYPES from '../../Bootstrap/Types'
 import { DomainEventFactoryInterface } from '../Event/DomainEventFactoryInterface'
 import { User } from '../User/User'
-import { SettingDecrypterInterface } from './SettingDecrypterInterface'
 import { SettingInterpreterInterface } from './SettingInterpreterInterface'
 import { SettingRepositoryInterface } from './SettingRepositoryInterface'
 
 @injectable()
 export class SettingInterpreter implements SettingInterpreterInterface {
-  private readonly cloudBackupTokenSettings = [
-    SettingName.NAMES.DropboxBackupToken,
-    SettingName.NAMES.GoogleDriveBackupToken,
-    SettingName.NAMES.OneDriveBackupToken,
-  ]
-
-  private readonly cloudBackupFrequencySettings = [
-    SettingName.NAMES.DropboxBackupFrequency,
-    SettingName.NAMES.GoogleDriveBackupFrequency,
-    SettingName.NAMES.OneDriveBackupFrequency,
-  ]
-
-  private readonly cloudBackupFrequencyDisabledValues = [
-    DropboxBackupFrequency.Disabled,
-    GoogleDriveBackupFrequency.Disabled,
-    OneDriveBackupFrequency.Disabled,
-  ]
-
   private readonly emailSettingToSubscriptionRejectionLevelMap: Map<string, string> = new Map([
     [SettingName.NAMES.MuteFailedBackupsEmails, EmailLevel.LEVELS.FailedEmailBackup],
     [SettingName.NAMES.MuteFailedCloudBackupsEmails, EmailLevel.LEVELS.FailedCloudBackup],
@@ -50,8 +27,6 @@ export class SettingInterpreter implements SettingInterpreterInterface {
     @inject(TYPES.DomainEventPublisher) private domainEventPublisher: DomainEventPublisherInterface,
     @inject(TYPES.DomainEventFactory) private domainEventFactory: DomainEventFactoryInterface,
     @inject(TYPES.SettingRepository) private settingRepository: SettingRepositoryInterface,
-    @inject(TYPES.SettingDecrypter) private settingDecrypter: SettingDecrypterInterface,
-    @inject(TYPES.Logger) private logger: Logger,
   ) {}
 
   async interpretSettingUpdated(
@@ -67,10 +42,6 @@ export class SettingInterpreter implements SettingInterpreterInterface {
       await this.triggerEmailBackup(user.uuid)
     }
 
-    if (this.isEnablingCloudBackupSetting(updatedSettingName, unencryptedValue)) {
-      await this.triggerCloudBackup(updatedSettingName, user.uuid, unencryptedValue)
-    }
-
     if (this.isDisablingSessionUserAgentLogging(updatedSettingName, unencryptedValue)) {
       await this.triggerSessionUserAgentCleanup(user)
     }
@@ -109,16 +80,6 @@ export class SettingInterpreter implements SettingInterpreterInterface {
     )
   }
 
-  private isEnablingCloudBackupSetting(settingName: string, newValue: string | null): boolean {
-    return (
-      (this.cloudBackupFrequencySettings.includes(settingName) ||
-        this.cloudBackupTokenSettings.includes(settingName)) &&
-      !this.cloudBackupFrequencyDisabledValues.includes(
-        newValue as DropboxBackupFrequency | OneDriveBackupFrequency | GoogleDriveBackupFrequency,
-      )
-    )
-  }
-
   private isDisablingSessionUserAgentLogging(settingName: string, newValue: string | null): boolean {
     return SettingName.NAMES.LogSessionUserAgent === settingName && LogSessionUserAgentOption.Disabled === newValue
   }
@@ -145,67 +106,4 @@ export class SettingInterpreter implements SettingInterpreterInterface {
       }),
     )
   }
-
-  private async triggerCloudBackup(
-    settingName: string,
-    userUuid: string,
-    unencryptedValue: string | null,
-  ): Promise<void> {
-    let cloudProvider
-    let tokenSettingName
-    switch (settingName) {
-      case SettingName.NAMES.DropboxBackupToken:
-      case SettingName.NAMES.DropboxBackupFrequency:
-        cloudProvider = 'DROPBOX'
-        tokenSettingName = SettingName.NAMES.DropboxBackupToken
-        break
-      case SettingName.NAMES.GoogleDriveBackupToken:
-      case SettingName.NAMES.GoogleDriveBackupFrequency:
-        cloudProvider = 'GOOGLE_DRIVE'
-        tokenSettingName = SettingName.NAMES.GoogleDriveBackupToken
-        break
-      case SettingName.NAMES.OneDriveBackupToken:
-      case SettingName.NAMES.OneDriveBackupFrequency:
-        cloudProvider = 'ONE_DRIVE'
-        tokenSettingName = SettingName.NAMES.OneDriveBackupToken
-        break
-    }
-
-    let backupToken = null
-    if (this.cloudBackupFrequencySettings.includes(settingName)) {
-      const tokenSetting = await this.settingRepository.findLastByNameAndUserUuid(tokenSettingName as string, userUuid)
-      if (tokenSetting !== null) {
-        backupToken = await this.settingDecrypter.decryptSettingValue(tokenSetting, userUuid)
-      }
-    } else {
-      backupToken = unencryptedValue
-    }
-
-    if (!backupToken) {
-      this.logger.error(`Could not trigger backup. Missing backup token for user ${userUuid}`)
-
-      return
-    }
-
-    let userHasEmailsMuted = false
-    let muteEmailsSettingUuid = ''
-    const muteFailedCloudBackupSetting = await this.settingRepository.findOneByNameAndUserUuid(
-      SettingName.NAMES.MuteFailedCloudBackupsEmails,
-      userUuid,
-    )
-    if (muteFailedCloudBackupSetting !== null) {
-      userHasEmailsMuted = muteFailedCloudBackupSetting.value === MuteFailedCloudBackupsEmailsOption.Muted
-      muteEmailsSettingUuid = muteFailedCloudBackupSetting.uuid
-    }
-
-    await this.domainEventPublisher.publish(
-      this.domainEventFactory.createCloudBackupRequestedEvent(
-        cloudProvider as 'DROPBOX' | 'GOOGLE_DRIVE' | 'ONE_DRIVE',
-        backupToken,
-        userUuid,
-        muteEmailsSettingUuid,
-        userHasEmailsMuted,
-      ),
-    )
-  }
 }

+ 0 - 7
packages/domain-events/src/Domain/Event/CloudBackupRequestedEvent.ts

@@ -1,7 +0,0 @@
-import { DomainEventInterface } from './DomainEventInterface'
-import { CloudBackupRequestedEventPayload } from './CloudBackupRequestedEventPayload'
-
-export interface CloudBackupRequestedEvent extends DomainEventInterface {
-  type: 'CLOUD_BACKUP_REQUESTED'
-  payload: CloudBackupRequestedEventPayload
-}

+ 0 - 7
packages/domain-events/src/Domain/Event/CloudBackupRequestedEventPayload.ts

@@ -1,7 +0,0 @@
-export interface CloudBackupRequestedEventPayload {
-  cloudProvider: 'DROPBOX' | 'ONE_DRIVE' | 'GOOGLE_DRIVE'
-  cloudProviderToken: string
-  userUuid: string
-  userHasEmailsMuted: boolean
-  muteEmailsSettingUuid: string
-}

+ 0 - 2
packages/domain-events/src/Domain/index.ts

@@ -1,7 +1,5 @@
 export * from './Event/AccountDeletionRequestedEvent'
 export * from './Event/AccountDeletionRequestedEventPayload'
-export * from './Event/CloudBackupRequestedEvent'
-export * from './Event/CloudBackupRequestedEventPayload'
 export * from './Event/DiscountApplyRequestedEvent'
 export * from './Event/DiscountApplyRequestedEventPayload'
 export * from './Event/DiscountWithdrawRequestedEvent'

+ 0 - 5
packages/settings/src/Domain/CloudProvider/CloudProvider.ts

@@ -1,5 +0,0 @@
-export enum CloudProvider {
-  Dropbox = 'Dropbox',
-  Google = 'Google Drive',
-  OneDrive = 'OneDrive',
-}

+ 0 - 5
packages/settings/src/Domain/DropboxBackupFrequency/DropboxBackupFrequency.ts

@@ -1,5 +0,0 @@
-export enum DropboxBackupFrequency {
-  Disabled = 'disabled',
-  Daily = 'daily',
-  Weekly = 'weekly',
-}

+ 0 - 5
packages/settings/src/Domain/GoogleDriveBackupFrequency/GoogleDriveBackupFrequency.ts

@@ -1,5 +0,0 @@
-export enum GoogleDriveBackupFrequency {
-  Disabled = 'disabled',
-  Daily = 'daily',
-  Weekly = 'weekly',
-}

+ 0 - 4
packages/settings/src/Domain/MuteFailedCloudBackupsEmails/MuteFailedCloudBackupsEmailsOption.ts

@@ -1,4 +0,0 @@
-export enum MuteFailedCloudBackupsEmailsOption {
-  Muted = 'muted',
-  NotMuted = 'not_muted',
-}

+ 0 - 5
packages/settings/src/Domain/OneDriveBackupFrequency/OneDriveBackupFrequency.ts

@@ -1,5 +0,0 @@
-export enum OneDriveBackupFrequency {
-  Disabled = 'disabled',
-  Daily = 'daily',
-  Weekly = 'weekly',
-}

+ 0 - 5
packages/settings/src/Domain/index.ts

@@ -1,13 +1,8 @@
-export * from './CloudProvider/CloudProvider'
-export * from './DropboxBackupFrequency/DropboxBackupFrequency'
 export * from './EmailBackupFrequency/EmailBackupFrequency'
-export * from './GoogleDriveBackupFrequency/GoogleDriveBackupFrequency'
 export * from './ListedAuthorSecretsData/ListedAuthorSecretsData'
 export * from './LogSessionUserAgent/LogSessionUserAgentOption'
 export * from './MuteFailedBackupsEmails/MuteFailedBackupsEmailsOption'
-export * from './MuteFailedCloudBackupsEmails/MuteFailedCloudBackupsEmailsOption'
 export * from './MuteMarketingEmails/MuteMarketingEmailsOption'
 export * from './MuteSignInEmails/MuteSignInEmailsOption'
-export * from './OneDriveBackupFrequency/OneDriveBackupFrequency'
 export * from './Setting/SettingName'
 export * from './Setting/SettingNameProps'

+ 0 - 1
packages/syncing-server/src/Bootstrap/Types.ts

@@ -42,7 +42,6 @@ const TYPES = {
   AccountDeletionRequestedEventHandler: Symbol.for('AccountDeletionRequestedEventHandler'),
   DuplicateItemSyncedEventHandler: Symbol.for('DuplicateItemSyncedEventHandler'),
   EmailBackupRequestedEventHandler: Symbol.for('EmailBackupRequestedEventHandler'),
-  CloudBackupRequestedEventHandler: Symbol.for('CloudBackupRequestedEventHandler'),
   ItemRevisionCreationRequestedEventHandler: Symbol.for('ItemRevisionCreationRequestedEventHandler'),
   // Services
   ContentDecoder: Symbol.for('ContentDecoder'),

+ 0 - 14
packages/syncing-server/src/Bootstrap/WorkerContainerConfigLoader.ts

@@ -27,7 +27,6 @@ import {
   SQSNewRelicEventMessageHandler,
 } from '@standardnotes/domain-events-infra'
 import { EmailBackupRequestedEventHandler } from '../Domain/Handler/EmailBackupRequestedEventHandler'
-import { CloudBackupRequestedEventHandler } from '../Domain/Handler/CloudBackupRequestedEventHandler'
 import { ItemRevisionCreationRequestedEventHandler } from '../Domain/Handler/ItemRevisionCreationRequestedEventHandler'
 import { FSItemBackupService } from '../Infra/FS/FSItemBackupService'
 import { CommonContainerConfigLoader } from './CommonContainerConfigLoader'
@@ -122,18 +121,6 @@ export class WorkerContainerConfigLoader extends CommonContainerConfigLoader {
           context.container.get(TYPES.Logger),
         )
       })
-    container
-      .bind<CloudBackupRequestedEventHandler>(TYPES.CloudBackupRequestedEventHandler)
-      .toDynamicValue((context: interfaces.Context) => {
-        return new CloudBackupRequestedEventHandler(
-          context.container.get(TYPES.ItemRepository),
-          context.container.get(TYPES.AuthHttpService),
-          context.container.get(TYPES.ExtensionsHttpService),
-          context.container.get(TYPES.ItemBackupService),
-          context.container.get(TYPES.EXTENSIONS_SERVER_URL),
-          context.container.get(TYPES.Logger),
-        )
-      })
     container
       .bind<ItemRevisionCreationRequestedEventHandler>(TYPES.ItemRevisionCreationRequestedEventHandler)
       .toDynamicValue((context: interfaces.Context) => {
@@ -194,7 +181,6 @@ export class WorkerContainerConfigLoader extends CommonContainerConfigLoader {
           ['DUPLICATE_ITEM_SYNCED', context.container.get(TYPES.DuplicateItemSyncedEventHandler)],
           ['ACCOUNT_DELETION_REQUESTED', context.container.get(TYPES.AccountDeletionRequestedEventHandler)],
           ['EMAIL_BACKUP_REQUESTED', context.container.get(TYPES.EmailBackupRequestedEventHandler)],
-          ['CLOUD_BACKUP_REQUESTED', context.container.get(TYPES.CloudBackupRequestedEventHandler)],
           ['ITEM_REVISION_CREATION_REQUESTED', context.container.get(TYPES.ItemRevisionCreationRequestedEventHandler)],
         ])
 

+ 0 - 177
packages/syncing-server/src/Domain/Handler/CloudBackupRequestedEventHandler.spec.ts

@@ -1,177 +0,0 @@
-import 'reflect-metadata'
-
-import { CloudBackupRequestedEvent } from '@standardnotes/domain-events'
-import { AuthHttpServiceInterface } from '../Auth/AuthHttpServiceInterface'
-import { Item } from '../Item/Item'
-import { ItemRepositoryInterface } from '../Item/ItemRepositoryInterface'
-import { CloudBackupRequestedEventHandler } from './CloudBackupRequestedEventHandler'
-import { ItemBackupServiceInterface } from '../Item/ItemBackupServiceInterface'
-import { ExtensionsHttpServiceInterface } from '../Extension/ExtensionsHttpServiceInterface'
-import { Logger } from 'winston'
-
-describe('CloudBackupRequestedEventHandler', () => {
-  let itemRepository: ItemRepositoryInterface
-  let authHttpService: AuthHttpServiceInterface
-  let extensionsHttpService: ExtensionsHttpServiceInterface
-  let itemBackupService: ItemBackupServiceInterface
-  const extensionsServerUrl = 'https://extensions-server'
-  let event: CloudBackupRequestedEvent
-  let item: Item
-  let logger: Logger
-
-  const createHandler = () =>
-    new CloudBackupRequestedEventHandler(
-      itemRepository,
-      authHttpService,
-      extensionsHttpService,
-      itemBackupService,
-      extensionsServerUrl,
-      logger,
-    )
-
-  beforeEach(() => {
-    item = {} as jest.Mocked<Item>
-
-    itemRepository = {} as jest.Mocked<ItemRepositoryInterface>
-    itemRepository.findAll = jest.fn().mockReturnValue([item])
-
-    authHttpService = {} as jest.Mocked<AuthHttpServiceInterface>
-    authHttpService.getUserKeyParams = jest.fn().mockReturnValue({ foo: 'bar' })
-
-    extensionsHttpService = {} as jest.Mocked<ExtensionsHttpServiceInterface>
-    extensionsHttpService.triggerCloudBackupOnExtensionsServer = jest.fn()
-
-    event = {} as jest.Mocked<CloudBackupRequestedEvent>
-    event.createdAt = new Date(1)
-    event.payload = {
-      cloudProvider: 'DROPBOX',
-      cloudProviderToken: 'test-token',
-      userUuid: '1-2-3',
-      muteEmailsSettingUuid: '2-3-4',
-      userHasEmailsMuted: false,
-    }
-
-    itemBackupService = {} as jest.Mocked<ItemBackupServiceInterface>
-    itemBackupService.backup = jest.fn().mockReturnValue(['backup-file-name'])
-
-    logger = {} as jest.Mocked<Logger>
-    logger.debug = jest.fn()
-    logger.warn = jest.fn()
-  })
-
-  it('should trigger cloud backup on extensions server - dropbox', async () => {
-    await createHandler().handle(event)
-
-    expect(itemRepository.findAll).toHaveBeenCalledWith({
-      sortBy: 'updated_at_timestamp',
-      sortOrder: 'ASC',
-      userUuid: '1-2-3',
-      deleted: false,
-    })
-
-    expect(extensionsHttpService.triggerCloudBackupOnExtensionsServer).toHaveBeenCalledWith({
-      authParams: {
-        foo: 'bar',
-      },
-      backupFilename: 'backup-file-name',
-      cloudProvider: 'DROPBOX',
-      extensionsServerUrl: 'https://extensions-server/dropbox/items/sync?type=sf&dbt=test-token',
-      muteEmailsSettingUuid: '2-3-4',
-      forceMute: false,
-      userUuid: '1-2-3',
-    })
-  })
-
-  it('should trigger cloud backup on extensions server - google drive', async () => {
-    event.payload.cloudProvider = 'GOOGLE_DRIVE'
-
-    await createHandler().handle(event)
-
-    expect(extensionsHttpService.triggerCloudBackupOnExtensionsServer).toHaveBeenCalledWith({
-      authParams: {
-        foo: 'bar',
-      },
-      backupFilename: 'backup-file-name',
-      cloudProvider: 'GOOGLE_DRIVE',
-      extensionsServerUrl: 'https://extensions-server/gdrive/sync?key=test-token',
-      muteEmailsSettingUuid: '2-3-4',
-      forceMute: false,
-      userUuid: '1-2-3',
-    })
-  })
-
-  it('should trigger cloud backup on extensions server - one drive', async () => {
-    event.payload.cloudProvider = 'ONE_DRIVE'
-
-    await createHandler().handle(event)
-
-    expect(extensionsHttpService.triggerCloudBackupOnExtensionsServer).toHaveBeenCalledWith({
-      authParams: {
-        foo: 'bar',
-      },
-      backupFilename: 'backup-file-name',
-      cloudProvider: 'ONE_DRIVE',
-      extensionsServerUrl: 'https://extensions-server/onedrive/sync?type=sf&key=test-token',
-      muteEmailsSettingUuid: '2-3-4',
-      forceMute: false,
-      userUuid: '1-2-3',
-    })
-  })
-
-  it('should not trigger cloud backup on extensions server - unknown', async () => {
-    event.payload.cloudProvider = 'test' as 'DROPBOX' | 'GOOGLE_DRIVE' | 'ONE_DRIVE'
-
-    let expectedError = null
-    try {
-      await createHandler().handle(event)
-    } catch (error) {
-      expectedError = error
-    }
-
-    expect(extensionsHttpService.triggerCloudBackupOnExtensionsServer).not.toHaveBeenCalled()
-    expect(expectedError).not.toBeNull()
-  })
-
-  it('should not trigger cloud backup if backup filename is not returned', async () => {
-    itemBackupService.backup = jest.fn().mockReturnValue([])
-
-    await createHandler().handle(event)
-
-    expect(extensionsHttpService.triggerCloudBackupOnExtensionsServer).not.toHaveBeenCalled()
-  })
-
-  it('should trigger cloud backup on extensions server with muted emails', async () => {
-    event.payload.userHasEmailsMuted = true
-
-    await createHandler().handle(event)
-
-    expect(itemRepository.findAll).toHaveBeenCalledWith({
-      sortBy: 'updated_at_timestamp',
-      sortOrder: 'ASC',
-      userUuid: '1-2-3',
-      deleted: false,
-    })
-
-    expect(extensionsHttpService.triggerCloudBackupOnExtensionsServer).toHaveBeenCalledWith({
-      authParams: {
-        foo: 'bar',
-      },
-      backupFilename: 'backup-file-name',
-      cloudProvider: 'DROPBOX',
-      extensionsServerUrl: 'https://extensions-server/dropbox/items/sync?type=sf&dbt=test-token',
-      muteEmailsSettingUuid: '2-3-4',
-      forceMute: true,
-      userUuid: '1-2-3',
-    })
-  })
-
-  it('should skip triggering cloud backups on extensions server if user key params cannot be obtained', async () => {
-    authHttpService.getUserKeyParams = jest.fn().mockImplementation(() => {
-      throw new Error('Oops!')
-    })
-
-    await createHandler().handle(event)
-
-    expect(extensionsHttpService.triggerCloudBackupOnExtensionsServer).not.toHaveBeenCalled()
-  })
-})

+ 0 - 80
packages/syncing-server/src/Domain/Handler/CloudBackupRequestedEventHandler.ts

@@ -1,80 +0,0 @@
-import { DomainEventHandlerInterface, CloudBackupRequestedEvent } from '@standardnotes/domain-events'
-
-import { ItemRepositoryInterface } from '../Item/ItemRepositoryInterface'
-import { ItemQuery } from '../Item/ItemQuery'
-import { AuthHttpServiceInterface } from '../Auth/AuthHttpServiceInterface'
-import { Item } from '../Item/Item'
-import { ExtensionsHttpServiceInterface } from '../Extension/ExtensionsHttpServiceInterface'
-import { ItemBackupServiceInterface } from '../Item/ItemBackupServiceInterface'
-import { Logger } from 'winston'
-import { KeyParamsData } from '@standardnotes/responses'
-
-export class CloudBackupRequestedEventHandler implements DomainEventHandlerInterface {
-  constructor(
-    private itemRepository: ItemRepositoryInterface,
-    private authHttpService: AuthHttpServiceInterface,
-    private extensionsHttpService: ExtensionsHttpServiceInterface,
-    private itemBackupService: ItemBackupServiceInterface,
-    private extensionsServerUrl: string,
-    private logger: Logger,
-  ) {}
-
-  async handle(event: CloudBackupRequestedEvent): Promise<void> {
-    const items = await this.getItemsForPostingToExtension(event)
-
-    let authParams: KeyParamsData
-    try {
-      authParams = await this.authHttpService.getUserKeyParams({
-        uuid: event.payload.userUuid,
-        authenticated: false,
-      })
-    } catch (error) {
-      this.logger.warn(`Could not get user key params from auth service: ${(error as Error).message}`)
-
-      return
-    }
-
-    const backupFilenames = await this.itemBackupService.backup(items, authParams)
-    if (backupFilenames.length === 0) {
-      this.logger.warn(`No backup files created for user ${event.payload.userUuid}`)
-
-      return
-    }
-
-    this.logger.debug(`Sending ${items.length} items to extensions server for user ${event.payload.userUuid}`)
-
-    await this.extensionsHttpService.triggerCloudBackupOnExtensionsServer({
-      cloudProvider: event.payload.cloudProvider,
-      authParams,
-      backupFilename: backupFilenames[0],
-      forceMute: event.payload.userHasEmailsMuted,
-      muteEmailsSettingUuid: event.payload.muteEmailsSettingUuid,
-      extensionsServerUrl: this.getExtensionsServerUrl(event),
-      userUuid: event.payload.userUuid,
-    })
-  }
-
-  private getExtensionsServerUrl(event: CloudBackupRequestedEvent): string {
-    switch (event.payload.cloudProvider) {
-      case 'ONE_DRIVE':
-        return `${this.extensionsServerUrl}/onedrive/sync?type=sf&key=${event.payload.cloudProviderToken}`
-      case 'GOOGLE_DRIVE':
-        return `${this.extensionsServerUrl}/gdrive/sync?key=${event.payload.cloudProviderToken}`
-      case 'DROPBOX':
-        return `${this.extensionsServerUrl}/dropbox/items/sync?type=sf&dbt=${event.payload.cloudProviderToken}`
-      default:
-        throw new Error(`Unsupported cloud provider ${event.payload.cloudProvider}`)
-    }
-  }
-
-  private async getItemsForPostingToExtension(event: CloudBackupRequestedEvent): Promise<Item[]> {
-    const itemQuery: ItemQuery = {
-      userUuid: event.payload.userUuid,
-      sortBy: 'updated_at_timestamp',
-      sortOrder: 'ASC',
-      deleted: false,
-    }
-
-    return this.itemRepository.findAll(itemQuery)
-  }
-}