backup.ts 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import 'reflect-metadata'
  2. import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
  3. import { ServiceIdentifier } from '@standardnotes/domain-core'
  4. const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AuthScheduledTask })
  5. sdk.start()
  6. import { Stream } from 'stream'
  7. import { Logger } from 'winston'
  8. import * as dayjs from 'dayjs'
  9. import * as utc from 'dayjs/plugin/utc'
  10. import { ContainerConfigLoader } from '../src/Bootstrap/Container'
  11. import TYPES from '../src/Bootstrap/Types'
  12. import { Env } from '../src/Bootstrap/Env'
  13. import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
  14. import { DomainEventFactoryInterface } from '../src/Domain/Event/DomainEventFactoryInterface'
  15. import { SettingRepositoryInterface } from '../src/Domain/Setting/SettingRepositoryInterface'
  16. import { MuteFailedBackupsEmailsOption, SettingName } from '@standardnotes/settings'
  17. import { RoleServiceInterface } from '../src/Domain/Role/RoleServiceInterface'
  18. import { PermissionName } from '@standardnotes/features'
  19. import { GetUserKeyParams } from '../src/Domain/UseCase/GetUserKeyParams/GetUserKeyParams'
  20. const inputArgs = process.argv.slice(2)
  21. const backupProvider = inputArgs[0]
  22. const backupFrequency = inputArgs[1]
  23. const requestBackups = async (
  24. settingRepository: SettingRepositoryInterface,
  25. roleService: RoleServiceInterface,
  26. domainEventFactory: DomainEventFactoryInterface,
  27. domainEventPublisher: DomainEventPublisherInterface,
  28. getUserKeyParamsUseCase: GetUserKeyParams,
  29. ): Promise<void> => {
  30. const settingName = SettingName.create(SettingName.NAMES.EmailBackupFrequency).getValue()
  31. const permissionName = PermissionName.DailyEmailBackup
  32. const muteEmailsSettingName = SettingName.NAMES.MuteFailedBackupsEmails
  33. const muteEmailsSettingValue = MuteFailedBackupsEmailsOption.Muted
  34. const stream = await settingRepository.streamAllByNameAndValue(settingName, backupFrequency)
  35. return new Promise((resolve, reject) => {
  36. stream
  37. .pipe(
  38. new Stream.Transform({
  39. objectMode: true,
  40. transform: async (setting, _encoding, callback) => {
  41. const userIsPermittedForEmailBackups = await roleService.userHasPermission(
  42. setting.setting_user_uuid,
  43. permissionName,
  44. )
  45. if (!userIsPermittedForEmailBackups) {
  46. callback()
  47. return
  48. }
  49. let userHasEmailsMuted = false
  50. const emailsMutedSetting = await settingRepository.findOneByNameAndUserUuid(
  51. muteEmailsSettingName,
  52. setting.setting_user_uuid,
  53. )
  54. if (emailsMutedSetting !== null && emailsMutedSetting.value !== null) {
  55. userHasEmailsMuted = emailsMutedSetting.value === muteEmailsSettingValue
  56. }
  57. const keyParamsResponse = await getUserKeyParamsUseCase.execute({
  58. userUuid: setting.setting_user_uuid,
  59. authenticated: false,
  60. })
  61. await domainEventPublisher.publish(
  62. domainEventFactory.createEmailBackupRequestedEvent(
  63. setting.setting_user_uuid,
  64. emailsMutedSetting?.uuid as string,
  65. userHasEmailsMuted,
  66. keyParamsResponse.keyParams,
  67. ),
  68. )
  69. callback()
  70. },
  71. }),
  72. )
  73. .on('finish', resolve)
  74. .on('error', reject)
  75. })
  76. }
  77. const container = new ContainerConfigLoader('worker')
  78. void container.load().then((container) => {
  79. dayjs.extend(utc)
  80. const env: Env = new Env()
  81. env.load()
  82. const logger: Logger = container.get(TYPES.Auth_Logger)
  83. logger.info(`Starting ${backupFrequency} ${backupProvider} backup requesting...`)
  84. const settingRepository: SettingRepositoryInterface = container.get(TYPES.Auth_SettingRepository)
  85. const roleService: RoleServiceInterface = container.get(TYPES.Auth_RoleService)
  86. const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.Auth_DomainEventFactory)
  87. const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.Auth_DomainEventPublisher)
  88. const getUserKeyParamsUseCase: GetUserKeyParams = container.get(TYPES.Auth_GetUserKeyParams)
  89. const tracer = new OpenTelemetryTracer()
  90. tracer.startSpan(ServiceIdentifier.NAMES.AuthScheduledTask, 'backup')
  91. Promise.resolve(
  92. requestBackups(settingRepository, roleService, domainEventFactory, domainEventPublisher, getUserKeyParamsUseCase),
  93. )
  94. .then(() => {
  95. logger.info(`${backupFrequency} ${backupProvider} backup requesting complete`)
  96. tracer.stopSpan()
  97. process.exit(0)
  98. })
  99. .catch((error) => {
  100. logger.error(`Could not finish ${backupFrequency} ${backupProvider} backup requesting: ${error.message}`)
  101. tracer.stopSpanWithError(error)
  102. process.exit(1)
  103. })
  104. })