diff --git a/.pnp.cjs b/.pnp.cjs index aab8a11c3..6f393d669 100755 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -2499,6 +2499,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["jsonwebtoken", "npm:8.5.1"]\ ],\ "linkType": "HARD"\ + }],\ + ["npm:3.19.4", {\ + "packageLocation": "./.yarn/cache/@standardnotes-auth-npm-3.19.4-29b35c1352-84ac9e669e.zip/node_modules/@standardnotes/auth/",\ + "packageDependencies": [\ + ["@standardnotes/auth", "npm:3.19.4"],\ + ["@standardnotes/common", "npm:1.23.1"],\ + ["jsonwebtoken", "npm:8.5.1"]\ + ],\ + "linkType": "HARD"\ }]\ ]],\ ["@standardnotes/auth-server", [\ @@ -2511,13 +2520,13 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@standardnotes/analytics", "npm:1.6.0"],\ ["@standardnotes/api", "npm:1.1.13"],\ ["@standardnotes/auth", "npm:3.19.3"],\ - ["@standardnotes/common", "npm:1.23.0"],\ - ["@standardnotes/domain-events", "npm:2.32.2"],\ + ["@standardnotes/common", "npm:1.23.1"],\ + ["@standardnotes/domain-events", "npm:2.32.4"],\ ["@standardnotes/domain-events-infra", "npm:1.5.2"],\ ["@standardnotes/features", "npm:1.45.5"],\ ["@standardnotes/responses", "npm:1.6.36"],\ ["@standardnotes/scheduler", "npm:1.1.1"],\ - ["@standardnotes/settings", "npm:1.14.3"],\ + ["@standardnotes/settings", "npm:1.15.0"],\ ["@standardnotes/sncrypto-common", "npm:1.9.0"],\ ["@standardnotes/sncrypto-node", "npm:1.8.3"],\ ["@standardnotes/time", "npm:1.7.0"],\ @@ -2568,6 +2577,13 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@standardnotes/common", "npm:1.23.0"]\ ],\ "linkType": "HARD"\ + }],\ + ["npm:1.23.1", {\ + "packageLocation": "./.yarn/cache/@standardnotes-common-npm-1.23.1-ed73dbb679-f498f4c469.zip/node_modules/@standardnotes/common/",\ + "packageDependencies": [\ + ["@standardnotes/common", "npm:1.23.1"]\ + ],\ + "linkType": "HARD"\ }]\ ]],\ ["@standardnotes/config", [\ @@ -2610,6 +2626,16 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@standardnotes/scheduler", "npm:1.1.1"]\ ],\ "linkType": "HARD"\ + }],\ + ["npm:2.32.4", {\ + "packageLocation": "./.yarn/cache/@standardnotes-domain-events-npm-2.32.4-0b0cc85196-9f8a1637aa.zip/node_modules/@standardnotes/domain-events/",\ + "packageDependencies": [\ + ["@standardnotes/domain-events", "npm:2.32.4"],\ + ["@standardnotes/auth", "npm:3.19.4"],\ + ["@standardnotes/features", "npm:1.45.6"],\ + ["@standardnotes/scheduler", "npm:1.1.2"]\ + ],\ + "linkType": "HARD"\ }]\ ]],\ ["@standardnotes/domain-events-infra", [\ @@ -2663,6 +2689,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@standardnotes/common", "npm:1.23.0"]\ ],\ "linkType": "HARD"\ + }],\ + ["npm:1.45.6", {\ + "packageLocation": "./.yarn/cache/@standardnotes-features-npm-1.45.6-6f88b4fd2a-572780d6e2.zip/node_modules/@standardnotes/features/",\ + "packageDependencies": [\ + ["@standardnotes/features", "npm:1.45.6"],\ + ["@standardnotes/auth", "npm:3.19.4"],\ + ["@standardnotes/common", "npm:1.23.1"]\ + ],\ + "linkType": "HARD"\ }]\ ]],\ ["@standardnotes/files-server", [\ @@ -2760,6 +2795,14 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@standardnotes/common", "npm:1.23.0"]\ ],\ "linkType": "HARD"\ + }],\ + ["npm:1.1.2", {\ + "packageLocation": "./.yarn/cache/@standardnotes-scheduler-npm-1.1.2-78f89314fb-68642a0874.zip/node_modules/@standardnotes/scheduler/",\ + "packageDependencies": [\ + ["@standardnotes/scheduler", "npm:1.1.2"],\ + ["@standardnotes/common", "npm:1.23.1"]\ + ],\ + "linkType": "HARD"\ }]\ ]],\ ["@standardnotes/scheduler-server", [\ @@ -2842,6 +2885,13 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@standardnotes/settings", "npm:1.14.3"]\ ],\ "linkType": "HARD"\ + }],\ + ["npm:1.15.0", {\ + "packageLocation": "./.yarn/cache/@standardnotes-settings-npm-1.15.0-bfec86ee49-4397d453a1.zip/node_modules/@standardnotes/settings/",\ + "packageDependencies": [\ + ["@standardnotes/settings", "npm:1.15.0"]\ + ],\ + "linkType": "HARD"\ }]\ ]],\ ["@standardnotes/sncrypto-common", [\ diff --git a/.yarn/cache/@standardnotes-auth-npm-3.19.4-29b35c1352-84ac9e669e.zip b/.yarn/cache/@standardnotes-auth-npm-3.19.4-29b35c1352-84ac9e669e.zip new file mode 100644 index 000000000..e3cc077ea Binary files /dev/null and b/.yarn/cache/@standardnotes-auth-npm-3.19.4-29b35c1352-84ac9e669e.zip differ diff --git a/.yarn/cache/@standardnotes-common-npm-1.23.1-ed73dbb679-f498f4c469.zip b/.yarn/cache/@standardnotes-common-npm-1.23.1-ed73dbb679-f498f4c469.zip new file mode 100644 index 000000000..507ef2442 Binary files /dev/null and b/.yarn/cache/@standardnotes-common-npm-1.23.1-ed73dbb679-f498f4c469.zip differ diff --git a/.yarn/cache/@standardnotes-domain-events-npm-2.32.4-0b0cc85196-9f8a1637aa.zip b/.yarn/cache/@standardnotes-domain-events-npm-2.32.4-0b0cc85196-9f8a1637aa.zip new file mode 100644 index 000000000..e3a55f59e Binary files /dev/null and b/.yarn/cache/@standardnotes-domain-events-npm-2.32.4-0b0cc85196-9f8a1637aa.zip differ diff --git a/.yarn/cache/@standardnotes-features-npm-1.45.6-6f88b4fd2a-572780d6e2.zip b/.yarn/cache/@standardnotes-features-npm-1.45.6-6f88b4fd2a-572780d6e2.zip new file mode 100644 index 000000000..0d73d49c5 Binary files /dev/null and b/.yarn/cache/@standardnotes-features-npm-1.45.6-6f88b4fd2a-572780d6e2.zip differ diff --git a/.yarn/cache/@standardnotes-scheduler-npm-1.1.2-78f89314fb-68642a0874.zip b/.yarn/cache/@standardnotes-scheduler-npm-1.1.2-78f89314fb-68642a0874.zip new file mode 100644 index 000000000..e06738dc8 Binary files /dev/null and b/.yarn/cache/@standardnotes-scheduler-npm-1.1.2-78f89314fb-68642a0874.zip differ diff --git a/.yarn/cache/@standardnotes-settings-npm-1.15.0-bfec86ee49-4397d453a1.zip b/.yarn/cache/@standardnotes-settings-npm-1.15.0-bfec86ee49-4397d453a1.zip new file mode 100644 index 000000000..c5ee2aa65 Binary files /dev/null and b/.yarn/cache/@standardnotes-settings-npm-1.15.0-bfec86ee49-4397d453a1.zip differ diff --git a/packages/auth/bin/email.ts b/packages/auth/bin/email.ts new file mode 100644 index 000000000..a76cb5dba --- /dev/null +++ b/packages/auth/bin/email.ts @@ -0,0 +1,139 @@ +import 'reflect-metadata' + +import 'newrelic' + +import { Stream } from 'stream' + +import { Logger } from 'winston' +import * as dayjs from 'dayjs' +import * as utc from 'dayjs/plugin/utc' + +import { UserRepositoryInterface } from '../src/Domain/User/UserRepositoryInterface' +import { ContainerConfigLoader } from '../src/Bootstrap/Container' +import TYPES from '../src/Bootstrap/Types' +import { Env } from '../src/Bootstrap/Env' +import { SettingServiceInterface } from '../src/Domain/Setting/SettingServiceInterface' +import { DomainEventFactoryInterface } from '../src/Domain/Event/DomainEventFactoryInterface' +import { UserSubscriptionRepositoryInterface } from '../src/Domain/Subscription/UserSubscriptionRepositoryInterface' +import { DomainEventPublisherInterface } from '@standardnotes/domain-events' +import { MuteMarketingEmailsOption, SettingName } from '@standardnotes/settings' +import { EmailMessageIdentifier } from '@standardnotes/common' +import { User } from '../src/Domain/User/User' +import { EncryptionVersion } from '../src/Domain/Encryption/EncryptionVersion' +import { TimerInterface } from '@standardnotes/time' + +const inputArgs = process.argv.slice(2) +const emailMessageIdentifier = inputArgs[0] + +const sendEmailCampaign = async ( + userRepository: UserRepositoryInterface, + settingService: SettingServiceInterface, + userSubscriptionRepository: UserSubscriptionRepositoryInterface, + timer: TimerInterface, + domainEventFactory: DomainEventFactoryInterface, + domainEventPublisher: DomainEventPublisherInterface, +): Promise => { + const stream = await userRepository.streamAll() + + return new Promise((resolve, reject) => { + stream + .pipe( + new Stream.Transform({ + objectMode: true, + transform: async (rawUserData, _encoding, callback) => { + const emailsMutedSetting = await settingService.findSettingWithDecryptedValue({ + userUuid: rawUserData.user_uuid, + settingName: SettingName.MuteMarketingEmails, + }) + + if (emailsMutedSetting === null) { + const user = (await userRepository.findOneByUuid(rawUserData.user_uuid)) as User + + await settingService.createOrReplace({ + user, + props: { + name: SettingName.MuteMarketingEmails, + unencryptedValue: MuteMarketingEmailsOption.NotMuted, + serverEncryptionVersion: EncryptionVersion.Default, + sensitive: false, + }, + }) + } + + if (emailsMutedSetting?.value === MuteMarketingEmailsOption.Muted) { + callback() + + return + } + + let activeSubscription = false + let subscriptionPlanName = null + + const userSubscription = await userSubscriptionRepository.findOneByUserUuid(rawUserData.user_uuid) + if (userSubscription !== null) { + activeSubscription = + !userSubscription.cancelled && userSubscription.endsAt > timer.getTimestampInMicroseconds() + subscriptionPlanName = userSubscription.planName + } + + await domainEventPublisher.publish( + domainEventFactory.createEmailMessageRequestedEvent({ + userEmail: rawUserData.user_email, + messageIdentifier: emailMessageIdentifier as EmailMessageIdentifier, + context: { + activeSubscription, + subscriptionPlanName, + }, + }), + ) + + callback() + }, + }), + ) + .on('finish', resolve) + .on('error', reject) + }) +} + +const container = new ContainerConfigLoader() +void container.load().then((container) => { + dayjs.extend(utc) + + const env: Env = new Env() + env.load() + + const logger: Logger = container.get(TYPES.Logger) + + logger.info(`Starting email campaign for email ${emailMessageIdentifier} ...`) + + const userRepository: UserRepositoryInterface = container.get(TYPES.UserRepository) + const settingService: SettingServiceInterface = container.get(TYPES.SettingService) + const userSubscriptionRepository: UserSubscriptionRepositoryInterface = container.get( + TYPES.UserSubscriptionRepository, + ) + const timer: TimerInterface = container.get(TYPES.Timer) + const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.DomainEventFactory) + const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.DomainEventPublisher) + + Promise.resolve( + sendEmailCampaign( + userRepository, + settingService, + userSubscriptionRepository, + timer, + domainEventFactory, + domainEventPublisher, + ), + ) + .then(() => { + logger.info(`${emailMessageIdentifier} email campaign complete.`) + + process.exit(0) + }) + .catch((error) => { + logger.error(`Could not finish ${emailMessageIdentifier} email campaign: ${error.message}`) + + process.exit(1) + }) +}) diff --git a/packages/auth/package.json b/packages/auth/package.json index 440a96f43..35d21f74a 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -33,13 +33,13 @@ "@standardnotes/analytics": "^1.6.0", "@standardnotes/api": "^1.1.13", "@standardnotes/auth": "^3.19.2", - "@standardnotes/common": "^1.23.0", - "@standardnotes/domain-events": "^2.31.1", + "@standardnotes/common": "^1.23.1", + "@standardnotes/domain-events": "^2.32.4", "@standardnotes/domain-events-infra": "^1.4.135", "@standardnotes/features": "^1.45.2", "@standardnotes/responses": "^1.6.15", "@standardnotes/scheduler": "^1.1.1", - "@standardnotes/settings": "^1.14.2", + "@standardnotes/settings": "^1.15.0", "@standardnotes/sncrypto-common": "^1.8.1", "@standardnotes/sncrypto-node": "^1.8.1", "@standardnotes/time": "^1.6.8", diff --git a/packages/auth/src/Domain/Event/DomainEventFactory.spec.ts b/packages/auth/src/Domain/Event/DomainEventFactory.spec.ts index e43ccb000..8b1facdd5 100644 --- a/packages/auth/src/Domain/Event/DomainEventFactory.spec.ts +++ b/packages/auth/src/Domain/Event/DomainEventFactory.spec.ts @@ -1,6 +1,6 @@ import 'reflect-metadata' -import { RoleName } from '@standardnotes/common' +import { EmailMessageIdentifier, RoleName } from '@standardnotes/common' import { PredicateName, PredicateAuthority, PredicateVerificationResult } from '@standardnotes/scheduler' import { TimerInterface } from '@standardnotes/time' @@ -18,6 +18,35 @@ describe('DomainEventFactory', () => { timer.getUTCDate = jest.fn().mockReturnValue(new Date(1)) }) + it('should create a EMAIL_MESSAGE_REQUESTED event', () => { + expect( + createFactory().createEmailMessageRequestedEvent({ + userEmail: 'test@test.te', + messageIdentifier: EmailMessageIdentifier.ENCOURAGE_EMAIL_BACKUPS, + context: { + foo: 'bar', + }, + }), + ).toEqual({ + createdAt: expect.any(Date), + meta: { + correlation: { + userIdentifier: 'test@test.te', + userIdentifierType: 'email', + }, + origin: 'auth', + }, + payload: { + messageIdentifier: 'ENCOURAGE_EMAIL_BACKUPS', + userEmail: 'test@test.te', + context: { + foo: 'bar', + }, + }, + type: 'EMAIL_MESSAGE_REQUESTED', + }) + }) + it('should create a PREDICATE_VERIFIED event', () => { expect( createFactory().createPredicateVerifiedEvent({ diff --git a/packages/auth/src/Domain/Event/DomainEventFactory.ts b/packages/auth/src/Domain/Event/DomainEventFactory.ts index 71e50a438..183e7ddf1 100644 --- a/packages/auth/src/Domain/Event/DomainEventFactory.ts +++ b/packages/auth/src/Domain/Event/DomainEventFactory.ts @@ -1,4 +1,4 @@ -import { RoleName, Uuid } from '@standardnotes/common' +import { EmailMessageIdentifier, RoleName, Uuid } from '@standardnotes/common' import { AccountDeletionRequestedEvent, UserEmailChangedEvent, @@ -14,6 +14,7 @@ import { SharedSubscriptionInvitationCanceledEvent, PredicateVerifiedEvent, DomainEventService, + EmailMessageRequestedEvent, } from '@standardnotes/domain-events' import { Predicate, PredicateVerificationResult } from '@standardnotes/scheduler' import { TimerInterface } from '@standardnotes/time' @@ -26,6 +27,25 @@ import { DomainEventFactoryInterface } from './DomainEventFactoryInterface' export class DomainEventFactory implements DomainEventFactoryInterface { constructor(@inject(TYPES.Timer) private timer: TimerInterface) {} + createEmailMessageRequestedEvent(dto: { + userEmail: string + messageIdentifier: EmailMessageIdentifier + context: Record + }): EmailMessageRequestedEvent { + return { + type: 'EMAIL_MESSAGE_REQUESTED', + createdAt: this.timer.getUTCDate(), + meta: { + correlation: { + userIdentifier: dto.userEmail, + userIdentifierType: 'email', + }, + origin: DomainEventService.Auth, + }, + payload: dto, + } + } + createPredicateVerifiedEvent(dto: { userUuid: Uuid predicate: Predicate diff --git a/packages/auth/src/Domain/Event/DomainEventFactoryInterface.ts b/packages/auth/src/Domain/Event/DomainEventFactoryInterface.ts index 7d6618567..b9f14da7c 100644 --- a/packages/auth/src/Domain/Event/DomainEventFactoryInterface.ts +++ b/packages/auth/src/Domain/Event/DomainEventFactoryInterface.ts @@ -1,4 +1,4 @@ -import { Uuid, RoleName } from '@standardnotes/common' +import { Uuid, RoleName, EmailMessageIdentifier } from '@standardnotes/common' import { Predicate, PredicateVerificationResult } from '@standardnotes/scheduler' import { AccountDeletionRequestedEvent, @@ -14,10 +14,16 @@ import { SharedSubscriptionInvitationCreatedEvent, SharedSubscriptionInvitationCanceledEvent, PredicateVerifiedEvent, + EmailMessageRequestedEvent, } from '@standardnotes/domain-events' import { InviteeIdentifierType } from '../SharedSubscription/InviteeIdentifierType' export interface DomainEventFactoryInterface { + createEmailMessageRequestedEvent(dto: { + userEmail: string + messageIdentifier: EmailMessageIdentifier + context: Record + }): EmailMessageRequestedEvent createUserSignedInEvent(dto: { userUuid: string userEmail: string diff --git a/packages/auth/src/Domain/Setting/SettingsAssociationService.spec.ts b/packages/auth/src/Domain/Setting/SettingsAssociationService.spec.ts index 2a09f4425..2748072a7 100644 --- a/packages/auth/src/Domain/Setting/SettingsAssociationService.spec.ts +++ b/packages/auth/src/Domain/Setting/SettingsAssociationService.spec.ts @@ -39,13 +39,13 @@ describe('SettingsAssociationService', () => { it('should return the default set of settings for a newly registered user', () => { const settings = createService().getDefaultSettingsAndValuesForNewUser() const flatSettings = [...(settings as Map).keys()] - expect(flatSettings).toEqual(['MUTE_SIGN_IN_EMAILS', 'LOG_SESSION_USER_AGENT']) + expect(flatSettings).toEqual(['MUTE_SIGN_IN_EMAILS', 'MUTE_MARKETING_EMAILS', 'LOG_SESSION_USER_AGENT']) }) it('should return the default set of settings for a newly registered vault account', () => { const settings = createService().getDefaultSettingsAndValuesForNewVaultAccount() const flatSettings = [...(settings as Map).keys()] - expect(flatSettings).toEqual(['MUTE_SIGN_IN_EMAILS', 'LOG_SESSION_USER_AGENT']) + expect(flatSettings).toEqual(['MUTE_SIGN_IN_EMAILS', 'MUTE_MARKETING_EMAILS', 'LOG_SESSION_USER_AGENT']) expect(settings.get(SettingName.LogSessionUserAgent)?.value).toEqual('disabled') }) diff --git a/packages/auth/src/Domain/Setting/SettingsAssociationService.ts b/packages/auth/src/Domain/Setting/SettingsAssociationService.ts index 61c8dddc9..079e3323a 100644 --- a/packages/auth/src/Domain/Setting/SettingsAssociationService.ts +++ b/packages/auth/src/Domain/Setting/SettingsAssociationService.ts @@ -1,5 +1,10 @@ import { PermissionName } from '@standardnotes/features' -import { LogSessionUserAgentOption, MuteSignInEmailsOption, SettingName } from '@standardnotes/settings' +import { + LogSessionUserAgentOption, + MuteMarketingEmailsOption, + MuteSignInEmailsOption, + SettingName, +} from '@standardnotes/settings' import { injectable } from 'inversify' import { EncryptionVersion } from '../Encryption/EncryptionVersion' @@ -14,6 +19,7 @@ export class SettingsAssociationService implements SettingsAssociationServiceInt SettingName.MuteFailedBackupsEmails, SettingName.MuteFailedCloudBackupsEmails, SettingName.MuteSignInEmails, + SettingName.MuteMarketingEmails, SettingName.DropboxBackupFrequency, SettingName.GoogleDriveBackupFrequency, SettingName.OneDriveBackupFrequency, @@ -28,6 +34,7 @@ export class SettingsAssociationService implements SettingsAssociationServiceInt SettingName.MuteFailedBackupsEmails, SettingName.MuteFailedCloudBackupsEmails, SettingName.MuteSignInEmails, + SettingName.MuteMarketingEmails, SettingName.ListedAuthorSecrets, SettingName.LogSessionUserAgent, ] @@ -47,6 +54,14 @@ export class SettingsAssociationService implements SettingsAssociationServiceInt value: MuteSignInEmailsOption.NotMuted, }, ], + [ + SettingName.MuteMarketingEmails, + { + sensitive: false, + serverEncryptionVersion: EncryptionVersion.Unencrypted, + value: MuteMarketingEmailsOption.NotMuted, + }, + ], [ SettingName.LogSessionUserAgent, { diff --git a/yarn.lock b/yarn.lock index 715851460..cf0aa609f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1820,13 +1820,13 @@ __metadata: "@standardnotes/analytics": ^1.6.0 "@standardnotes/api": ^1.1.13 "@standardnotes/auth": ^3.19.2 - "@standardnotes/common": ^1.23.0 - "@standardnotes/domain-events": ^2.31.1 + "@standardnotes/common": ^1.23.1 + "@standardnotes/domain-events": ^2.32.4 "@standardnotes/domain-events-infra": ^1.4.135 "@standardnotes/features": ^1.45.2 "@standardnotes/responses": ^1.6.15 "@standardnotes/scheduler": ^1.1.1 - "@standardnotes/settings": ^1.14.2 + "@standardnotes/settings": ^1.15.0 "@standardnotes/sncrypto-common": ^1.8.1 "@standardnotes/sncrypto-node": ^1.8.1 "@standardnotes/time": ^1.6.8 @@ -1889,6 +1889,16 @@ __metadata: languageName: node linkType: hard +"@standardnotes/auth@npm:^3.19.4": + version: 3.19.4 + resolution: "@standardnotes/auth@npm:3.19.4" + dependencies: + "@standardnotes/common": ^1.23.1 + jsonwebtoken: ^8.5.1 + checksum: 84ac9e669ee393a8ac04c49729cd732280ab7ad9c6ad780e1f8cc7e02bdd1d15b8446d84134e775d805e6fa04e9500d9e62d7f857e6b1f5bb36f10a0c31640ff + languageName: node + linkType: hard + "@standardnotes/common@npm:^1.19.1, @standardnotes/common@npm:^1.19.4, @standardnotes/common@npm:^1.22.0, @standardnotes/common@npm:^1.23.0": version: 1.23.0 resolution: "@standardnotes/common@npm:1.23.0" @@ -1896,6 +1906,13 @@ __metadata: languageName: node linkType: hard +"@standardnotes/common@npm:^1.23.1": + version: 1.23.1 + resolution: "@standardnotes/common@npm:1.23.1" + checksum: f498f4c469f7b9cdfc08b7648077832a2a214d844f012d02d73c2c418fab221af3302570cc6b1957b5ed481b55237f95bc24fc5c231162bfcdf8730333d38405 + languageName: node + linkType: hard + "@standardnotes/config@npm:2.0.1": version: 2.0.1 resolution: "@standardnotes/config@npm:2.0.1" @@ -1946,7 +1963,7 @@ __metadata: languageName: node linkType: hard -"@standardnotes/domain-events@npm:^2.27.6, @standardnotes/domain-events@npm:^2.29.0, @standardnotes/domain-events@npm:^2.31.1, @standardnotes/domain-events@npm:^2.32.2": +"@standardnotes/domain-events@npm:^2.27.6, @standardnotes/domain-events@npm:^2.29.0, @standardnotes/domain-events@npm:^2.32.2": version: 2.32.2 resolution: "@standardnotes/domain-events@npm:2.32.2" dependencies: @@ -1968,6 +1985,17 @@ __metadata: languageName: node linkType: hard +"@standardnotes/domain-events@npm:^2.32.4": + version: 2.32.4 + resolution: "@standardnotes/domain-events@npm:2.32.4" + dependencies: + "@standardnotes/auth": ^3.19.4 + "@standardnotes/features": ^1.45.6 + "@standardnotes/scheduler": ^1.1.2 + checksum: 9f8a1637aa63d04f2c60e1a4c75e5fc5f4013f4a5e39b9cd55d56a894220cee47390e8b37422b4c128db05d231ab371e8a1caa4e1af3395bf04319697dae7303 + languageName: node + linkType: hard + "@standardnotes/encryption@npm:^1.8.19": version: 1.8.19 resolution: "@standardnotes/encryption@npm:1.8.19" @@ -1989,6 +2017,16 @@ __metadata: languageName: node linkType: hard +"@standardnotes/features@npm:^1.45.6": + version: 1.45.6 + resolution: "@standardnotes/features@npm:1.45.6" + dependencies: + "@standardnotes/auth": ^3.19.4 + "@standardnotes/common": ^1.23.1 + checksum: 572780d6e24efa664f316f6cf56c01907e00263db6204fee17f7ce9e43fa376411f373863dda59f8fb039250a224b7f8637fbd0bcbd7241112e061accbc05360 + languageName: node + linkType: hard + "@standardnotes/files-server@workspace:packages/files": version: 0.0.0-use.local resolution: "@standardnotes/files-server@workspace:packages/files" @@ -2112,6 +2150,15 @@ __metadata: languageName: node linkType: hard +"@standardnotes/scheduler@npm:^1.1.2": + version: 1.1.2 + resolution: "@standardnotes/scheduler@npm:1.1.2" + dependencies: + "@standardnotes/common": ^1.23.1 + checksum: 68642a08741aeb4936e4a69e43e2b85e5cbfa3ce60006d292cee517d33093edaf35a6a7af61343d85ab3474d6e980a073a2779f6e0b1f11805ab06a407b15ce7 + languageName: node + linkType: hard + "@standardnotes/server-monorepo@workspace:.": version: 0.0.0-use.local resolution: "@standardnotes/server-monorepo@workspace:." @@ -2148,13 +2195,20 @@ __metadata: languageName: node linkType: hard -"@standardnotes/settings@npm:1.14.3, @standardnotes/settings@npm:^1.14.2": +"@standardnotes/settings@npm:1.14.3": version: 1.14.3 resolution: "@standardnotes/settings@npm:1.14.3" checksum: 60fbb2ca856083b1afdf3a93cfb2729151c8a4a34f02564a8a814a7caad9982285303ad79ffb1da7643046061a6efe39410e57e8e4703a8963be8dc0ffabeaa6 languageName: node linkType: hard +"@standardnotes/settings@npm:^1.15.0": + version: 1.15.0 + resolution: "@standardnotes/settings@npm:1.15.0" + checksum: 4397d453a1a0cd5554012a5bf5ee2025c102ffc6d742841eecd2ab9cd46b0fbfe78da61b401451646274887d92801cafcef4c283bbfc6074b4d152103e15f861 + languageName: node + linkType: hard + "@standardnotes/sncrypto-common@npm:^1.3.0, @standardnotes/sncrypto-common@npm:^1.8.1, @standardnotes/sncrypto-common@npm:^1.9.0": version: 1.9.0 resolution: "@standardnotes/sncrypto-common@npm:1.9.0"