user_email_backup.ts 4.5 KB

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