backup.ts 3.9 KB

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