Skip to content

Commit d228a86

Browse files
authored
feat(auth): add triggering post setting update actions (#905)
* feat(auth): add triggering post setting update actions * feat(auth): refactor email backups * fix: add extra logs for backups * fix: specs
1 parent 0cb234a commit d228a86

21 files changed

+550
-415
lines changed

packages/auth/bin/backup.ts

Lines changed: 11 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,19 @@
11
import 'reflect-metadata'
22

3-
import { SettingName } from '@standardnotes/domain-core'
4-
5-
import { Stream } from 'stream'
6-
73
import { Logger } from 'winston'
84
import * as dayjs from 'dayjs'
95
import * as utc from 'dayjs/plugin/utc'
106

117
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
128
import TYPES from '../src/Bootstrap/Types'
139
import { Env } from '../src/Bootstrap/Env'
14-
import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
15-
import { DomainEventFactoryInterface } from '../src/Domain/Event/DomainEventFactoryInterface'
16-
import { SettingRepositoryInterface } from '../src/Domain/Setting/SettingRepositoryInterface'
17-
import { MuteFailedBackupsEmailsOption } from '@standardnotes/settings'
18-
import { RoleServiceInterface } from '../src/Domain/Role/RoleServiceInterface'
19-
import { PermissionName } from '@standardnotes/features'
20-
import { GetUserKeyParams } from '../src/Domain/UseCase/GetUserKeyParams/GetUserKeyParams'
10+
import { TriggerEmailBackupForAllUsers } from '../src/Domain/UseCase/TriggerEmailBackupForAllUsers/TriggerEmailBackupForAllUsers'
2111

2212
const inputArgs = process.argv.slice(2)
23-
const backupProvider = inputArgs[0]
24-
const backupFrequency = inputArgs[1]
25-
26-
const requestBackups = async (
27-
settingRepository: SettingRepositoryInterface,
28-
roleService: RoleServiceInterface,
29-
domainEventFactory: DomainEventFactoryInterface,
30-
domainEventPublisher: DomainEventPublisherInterface,
31-
getUserKeyParamsUseCase: GetUserKeyParams,
32-
): Promise<void> => {
33-
const settingName = SettingName.create(SettingName.NAMES.EmailBackupFrequency).getValue()
34-
const permissionName = PermissionName.DailyEmailBackup
35-
const muteEmailsSettingName = SettingName.NAMES.MuteFailedBackupsEmails
36-
const muteEmailsSettingValue = MuteFailedBackupsEmailsOption.Muted
37-
38-
const stream = await settingRepository.streamAllByNameAndValue(settingName, backupFrequency)
39-
40-
return new Promise((resolve, reject) => {
41-
stream
42-
.pipe(
43-
new Stream.Transform({
44-
objectMode: true,
45-
transform: async (setting, _encoding, callback) => {
46-
const userIsPermittedForEmailBackups = await roleService.userHasPermission(
47-
setting.setting_user_uuid,
48-
permissionName,
49-
)
50-
if (!userIsPermittedForEmailBackups) {
51-
callback()
52-
53-
return
54-
}
13+
const backupFrequency = inputArgs[0]
5514

56-
let userHasEmailsMuted = false
57-
const emailsMutedSetting = await settingRepository.findOneByNameAndUserUuid(
58-
muteEmailsSettingName,
59-
setting.setting_user_uuid,
60-
)
61-
if (emailsMutedSetting !== null && emailsMutedSetting.props.value !== null) {
62-
userHasEmailsMuted = emailsMutedSetting.props.value === muteEmailsSettingValue
63-
}
64-
65-
const keyParamsResponse = await getUserKeyParamsUseCase.execute({
66-
userUuid: setting.setting_user_uuid,
67-
authenticated: false,
68-
})
69-
70-
await domainEventPublisher.publish(
71-
domainEventFactory.createEmailBackupRequestedEvent(
72-
setting.setting_user_uuid,
73-
emailsMutedSetting?.id.toString() as string,
74-
userHasEmailsMuted,
75-
keyParamsResponse.keyParams,
76-
),
77-
)
78-
79-
callback()
80-
},
81-
}),
82-
)
83-
.on('finish', resolve)
84-
.on('error', reject)
85-
})
15+
const requestBackups = async (triggerEmailBackupForAllUsers: TriggerEmailBackupForAllUsers): Promise<void> => {
16+
await triggerEmailBackupForAllUsers.execute({ backupFrequency })
8617
}
8718

8819
const container = new ContainerConfigLoader('worker')
@@ -94,24 +25,20 @@ void container.load().then((container) => {
9425

9526
const logger: Logger = container.get(TYPES.Auth_Logger)
9627

97-
logger.info(`Starting ${backupFrequency} ${backupProvider} backup requesting...`)
28+
logger.info(`Starting ${backupFrequency} email backup requesting...`)
9829

99-
const settingRepository: SettingRepositoryInterface = container.get(TYPES.Auth_SettingRepository)
100-
const roleService: RoleServiceInterface = container.get(TYPES.Auth_RoleService)
101-
const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.Auth_DomainEventFactory)
102-
const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.Auth_DomainEventPublisher)
103-
const getUserKeyParamsUseCase: GetUserKeyParams = container.get(TYPES.Auth_GetUserKeyParams)
104-
105-
Promise.resolve(
106-
requestBackups(settingRepository, roleService, domainEventFactory, domainEventPublisher, getUserKeyParamsUseCase),
30+
const triggerEmailBackupForAllUsers: TriggerEmailBackupForAllUsers = container.get(
31+
TYPES.Auth_TriggerEmailBackupForAllUsers,
10732
)
33+
34+
Promise.resolve(requestBackups(triggerEmailBackupForAllUsers))
10835
.then(() => {
109-
logger.info(`${backupFrequency} ${backupProvider} backup requesting complete`)
36+
logger.info(`${backupFrequency} email backup requesting complete`)
11037

11138
process.exit(0)
11239
})
11340
.catch((error) => {
114-
logger.error(`Could not finish ${backupFrequency} ${backupProvider} backup requesting: ${error.message}`)
41+
logger.error(`Could not finish ${backupFrequency} email backup requesting: ${error.message}`)
11542

11643
process.exit(1)
11744
})

packages/auth/docker/entrypoint.sh

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ case "$COMMAND" in
2626

2727
'email-daily-backup' )
2828
echo "[Docker] Starting Email Daily Backup..."
29-
node docker/entrypoint-backup.js email daily
29+
node docker/entrypoint-backup.js daily
3030
;;
3131

3232
'email-weekly-backup' )
3333
echo "[Docker] Starting Email Weekly Backup..."
34-
node docker/entrypoint-backup.js email weekly
34+
node docker/entrypoint-backup.js weekly
3535
;;
3636

3737
'email-backup' )
@@ -40,21 +40,6 @@ case "$COMMAND" in
4040
node docker/entrypoint-user-email-backup.js $EMAIL
4141
;;
4242

43-
'dropbox-daily-backup' )
44-
echo "[Docker] Starting Dropbox Daily Backup..."
45-
node docker/entrypoint-backup.js dropbox daily
46-
;;
47-
48-
'google-drive-daily-backup' )
49-
echo "[Docker] Starting Google Drive Daily Backup..."
50-
node docker/entrypoint-backup.js google_drive daily
51-
;;
52-
53-
'one-drive-daily-backup' )
54-
echo "[Docker] Starting One Drive Daily Backup..."
55-
node docker/entrypoint-backup.js one_drive daily
56-
;;
57-
5843
* )
5944
echo "[Docker] Unknown command"
6045
;;

packages/auth/package.json

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,9 @@
2424
"worker": "yarn node dist/bin/worker.js",
2525
"cleanup": "yarn node dist/bin/cleanup.js",
2626
"stats": "yarn node dist/bin/stats.js",
27-
"daily-backup:email": "yarn node dist/bin/backup.js email daily",
27+
"daily-backup:email": "yarn node dist/bin/backup.js daily",
2828
"user-email-backup": "yarn node dist/bin/user_email_backup.js",
29-
"daily-backup:dropbox": "yarn node dist/bin/backup.js dropbox daily",
30-
"daily-backup:google_drive": "yarn node dist/bin/backup.js google_drive daily",
31-
"daily-backup:one_drive": "yarn node dist/bin/backup.js one_drive daily",
32-
"weekly-backup:email": "yarn node dist/bin/backup.js email weekly",
29+
"weekly-backup:email": "yarn node dist/bin/backup.js weekly",
3330
"content-recalculation": "yarn node dist/bin/content.js",
3431
"typeorm": "typeorm-ts-node-commonjs",
3532
"migrate": "yarn build && yarn typeorm migration:run -d dist/src/Bootstrap/DataSource.js"

packages/auth/src/Bootstrap/Container.ts

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,6 @@ import { ListedAccountCreatedEventHandler } from '../Domain/Handler/ListedAccoun
130130
import { ListedAccountDeletedEventHandler } from '../Domain/Handler/ListedAccountDeletedEventHandler'
131131
import { FileRemovedEventHandler } from '../Domain/Handler/FileRemovedEventHandler'
132132
import { UserDisabledSessionUserAgentLoggingEventHandler } from '../Domain/Handler/UserDisabledSessionUserAgentLoggingEventHandler'
133-
import { SettingInterpreterInterface } from '../Domain/Setting/SettingInterpreterInterface'
134-
import { SettingInterpreter } from '../Domain/Setting/SettingInterpreter'
135133
import { SettingCrypterInterface } from '../Domain/Setting/SettingCrypterInterface'
136134
import { SettingCrypter } from '../Domain/Setting/SettingCrypter'
137135
import { SharedSubscriptionInvitationRepositoryInterface } from '../Domain/SharedSubscription/SharedSubscriptionInvitationRepositoryInterface'
@@ -275,6 +273,9 @@ import { SubscriptionSettingPersistenceMapper } from '../Mapping/Persistence/Sub
275273
import { ApplyDefaultSettings } from '../Domain/UseCase/ApplyDefaultSettings/ApplyDefaultSettings'
276274
import { AuthResponseFactoryResolverInterface } from '../Domain/Auth/AuthResponseFactoryResolverInterface'
277275
import { UserInvitedToSharedVaultEventHandler } from '../Domain/Handler/UserInvitedToSharedVaultEventHandler'
276+
import { TriggerPostSettingUpdateActions } from '../Domain/UseCase/TriggerPostSettingUpdateActions/TriggerPostSettingUpdateActions'
277+
import { TriggerEmailBackupForUser } from '../Domain/UseCase/TriggerEmailBackupForUser/TriggerEmailBackupForUser'
278+
import { TriggerEmailBackupForAllUsers } from '../Domain/UseCase/TriggerEmailBackupForAllUsers/TriggerEmailBackupForAllUsers'
278279

279280
export class ContainerConfigLoader {
280281
constructor(private mode: 'server' | 'worker' = 'server') {}
@@ -772,16 +773,6 @@ export class ContainerConfigLoader {
772773
container.get<winston.Logger>(TYPES.Auth_Logger),
773774
),
774775
)
775-
container
776-
.bind<SettingInterpreterInterface>(TYPES.Auth_SettingInterpreter)
777-
.toConstantValue(
778-
new SettingInterpreter(
779-
container.get<DomainEventPublisherInterface>(TYPES.Auth_DomainEventPublisher),
780-
container.get<DomainEventFactoryInterface>(TYPES.Auth_DomainEventFactory),
781-
container.get<SettingRepositoryInterface>(TYPES.Auth_SettingRepository),
782-
container.get<GetUserKeyParams>(TYPES.Auth_GetUserKeyParams),
783-
),
784-
)
785776

786777
container.bind<OfflineSettingServiceInterface>(TYPES.Auth_OfflineSettingService).to(OfflineSettingService)
787778
container.bind<ContentDecoderInterface>(TYPES.Auth_ContenDecoder).toConstantValue(new ContentDecoder())
@@ -1231,6 +1222,35 @@ export class ContainerConfigLoader {
12311222
container.get<GetSharedOrRegularSubscriptionForUser>(TYPES.Auth_GetSharedOrRegularSubscriptionForUser),
12321223
),
12331224
)
1225+
container
1226+
.bind<TriggerEmailBackupForUser>(TYPES.Auth_TriggerEmailBackupForUser)
1227+
.toConstantValue(
1228+
new TriggerEmailBackupForUser(
1229+
container.get<RoleServiceInterface>(TYPES.Auth_RoleService),
1230+
container.get<GetSetting>(TYPES.Auth_GetSetting),
1231+
container.get<GetUserKeyParams>(TYPES.Auth_GetUserKeyParams),
1232+
container.get<DomainEventPublisherInterface>(TYPES.Auth_DomainEventPublisher),
1233+
container.get<DomainEventFactoryInterface>(TYPES.Auth_DomainEventFactory),
1234+
),
1235+
)
1236+
container
1237+
.bind<TriggerEmailBackupForAllUsers>(TYPES.Auth_TriggerEmailBackupForAllUsers)
1238+
.toConstantValue(
1239+
new TriggerEmailBackupForAllUsers(
1240+
container.get<SettingRepositoryInterface>(TYPES.Auth_SettingRepository),
1241+
container.get<TriggerEmailBackupForUser>(TYPES.Auth_TriggerEmailBackupForUser),
1242+
container.get<winston.Logger>(TYPES.Auth_Logger),
1243+
),
1244+
)
1245+
container
1246+
.bind<TriggerPostSettingUpdateActions>(TYPES.Auth_TriggerPostSettingUpdateActions)
1247+
.toConstantValue(
1248+
new TriggerPostSettingUpdateActions(
1249+
container.get<DomainEventPublisherInterface>(TYPES.Auth_DomainEventPublisher),
1250+
container.get<DomainEventFactoryInterface>(TYPES.Auth_DomainEventFactory),
1251+
container.get<TriggerEmailBackupForUser>(TYPES.Auth_TriggerEmailBackupForUser),
1252+
),
1253+
)
12341254

12351255
// Controller
12361256
container
@@ -1655,11 +1675,13 @@ export class ContainerConfigLoader {
16551675
container.get<GetAllSettingsForUser>(TYPES.Auth_GetAllSettingsForUser),
16561676
container.get<GetSetting>(TYPES.Auth_GetSetting),
16571677
container.get<SetSettingValue>(TYPES.Auth_SetSettingValue),
1678+
container.get<TriggerPostSettingUpdateActions>(TYPES.Auth_TriggerPostSettingUpdateActions),
16581679
container.get<DeleteSetting>(TYPES.Auth_DeleteSetting),
16591680
container.get<MapperInterface<Setting, SettingHttpRepresentation>>(TYPES.Auth_SettingHttpMapper),
16601681
container.get<MapperInterface<SubscriptionSetting, SubscriptionSettingHttpRepresentation>>(
16611682
TYPES.Auth_SubscriptionSettingHttpMapper,
16621683
),
1684+
container.get<winston.Logger>(TYPES.Auth_Logger),
16631685
container.get<ControllerContainerInterface>(TYPES.Auth_ControllerContainer),
16641686
),
16651687
)

packages/auth/src/Bootstrap/Types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,9 @@ const TYPES = {
164164
Auth_DesignateSurvivor: Symbol.for('Auth_DesignateSurvivor'),
165165
Auth_GetSharedOrRegularSubscriptionForUser: Symbol.for('Auth_GetSharedOrRegularSubscriptionForUser'),
166166
Auth_DisableEmailSettingBasedOnEmailSubscription: Symbol.for('Auth_DisableEmailSettingBasedOnEmailSubscription'),
167+
Auth_TriggerPostSettingUpdateActions: Symbol.for('Auth_TriggerPostSettingUpdateActions'),
168+
Auth_TriggerEmailBackupForUser: Symbol.for('Auth_TriggerEmailBackupForUser'),
169+
Auth_TriggerEmailBackupForAllUsers: Symbol.for('Auth_TriggerEmailBackupForAllUsers'),
167170
// Handlers
168171
Auth_AccountDeletionRequestedEventHandler: Symbol.for('Auth_AccountDeletionRequestedEventHandler'),
169172
Auth_SubscriptionPurchasedEventHandler: Symbol.for('Auth_SubscriptionPurchasedEventHandler'),
@@ -230,7 +233,6 @@ const TYPES = {
230233
Auth_SubscriptionSettingsAssociationService: Symbol.for('Auth_SubscriptionSettingsAssociationService'),
231234
Auth_FeatureService: Symbol.for('Auth_FeatureService'),
232235
Auth_SettingCrypter: Symbol.for('Auth_SettingCrypter'),
233-
Auth_SettingInterpreter: Symbol.for('Auth_SettingInterpreter'),
234236
Auth_ProtocolVersionSelector: Symbol.for('Auth_ProtocolVersionSelector'),
235237
Auth_BooleanSelector: Symbol.for('Auth_BooleanSelector'),
236238
Auth_BaseAuthController: Symbol.for('Auth_BaseAuthController'),

0 commit comments

Comments
 (0)