浏览代码

feat: transition users after sign out

Karol Sójko 1 年之前
父节点
当前提交
398338c8f8

+ 6 - 0
packages/auth/src/Controller/AuthController.ts

@@ -226,6 +226,12 @@ export class AuthController implements UserServerInterface {
     let headers = undefined
     if (userUuid !== null) {
       headers = new Map([['x-invalidate-cache', userUuid]])
+
+      await this.domainEventPublisher.publish(
+        this.domainEventFactory.createTransitionRequestedEvent({
+          userUuid,
+        }),
+      )
     }
 
     return {

+ 16 - 0
packages/auth/src/Domain/Event/DomainEventFactory.ts

@@ -20,6 +20,7 @@ import {
   StatisticPersistenceRequestedEvent,
   SessionCreatedEvent,
   SessionRefreshedEvent,
+  TransitionRequestedEvent,
 } from '@standardnotes/domain-events'
 import { Predicate, PredicateVerificationResult } from '@standardnotes/predicates'
 import { TimerInterface } from '@standardnotes/time'
@@ -32,6 +33,21 @@ import { DomainEventFactoryInterface } from './DomainEventFactoryInterface'
 export class DomainEventFactory implements DomainEventFactoryInterface {
   constructor(@inject(TYPES.Auth_Timer) private timer: TimerInterface) {}
 
+  createTransitionRequestedEvent(dto: { userUuid: string }): TransitionRequestedEvent {
+    return {
+      type: 'TRANSITION_REQUESTED',
+      createdAt: this.timer.getUTCDate(),
+      meta: {
+        correlation: {
+          userIdentifier: dto.userUuid,
+          userIdentifierType: 'uuid',
+        },
+        origin: DomainEventService.Auth,
+      },
+      payload: dto,
+    }
+  }
+
   createSessionCreatedEvent(dto: { userUuid: string }): SessionCreatedEvent {
     return {
       type: 'SESSION_CREATED',

+ 2 - 0
packages/auth/src/Domain/Event/DomainEventFactoryInterface.ts

@@ -18,6 +18,7 @@ import {
   StatisticPersistenceRequestedEvent,
   SessionCreatedEvent,
   SessionRefreshedEvent,
+  TransitionRequestedEvent,
 } from '@standardnotes/domain-events'
 import { InviteeIdentifierType } from '../SharedSubscription/InviteeIdentifierType'
 
@@ -89,4 +90,5 @@ export interface DomainEventFactoryInterface {
   }): StatisticPersistenceRequestedEvent
   createSessionCreatedEvent(dto: { userUuid: string }): SessionCreatedEvent
   createSessionRefreshedEvent(dto: { userUuid: string }): SessionRefreshedEvent
+  createTransitionRequestedEvent(dto: { userUuid: string }): TransitionRequestedEvent
 }

+ 8 - 0
packages/domain-events/src/Domain/Event/TransitionRequestedEvent.ts

@@ -0,0 +1,8 @@
+import { DomainEventInterface } from './DomainEventInterface'
+
+import { TransitionRequestedEventPayload } from './TransitionRequestedEventPayload'
+
+export interface TransitionRequestedEvent extends DomainEventInterface {
+  type: 'TRANSITION_REQUESTED'
+  payload: TransitionRequestedEventPayload
+}

+ 3 - 0
packages/domain-events/src/Domain/Event/TransitionRequestedEventPayload.ts

@@ -0,0 +1,3 @@
+export interface TransitionRequestedEventPayload {
+  userUuid: string
+}

+ 2 - 0
packages/domain-events/src/Domain/index.ts

@@ -96,6 +96,8 @@ export * from './Event/SubscriptionRevertRequestedEvent'
 export * from './Event/SubscriptionRevertRequestedEventPayload'
 export * from './Event/SubscriptionSyncRequestedEvent'
 export * from './Event/SubscriptionSyncRequestedEventPayload'
+export * from './Event/TransitionRequestedEvent'
+export * from './Event/TransitionRequestedEventPayload'
 export * from './Event/TransitionStatusUpdatedEvent'
 export * from './Event/TransitionStatusUpdatedEventPayload'
 export * from './Event/UserAddedToSharedVaultEvent'

+ 15 - 0
packages/syncing-server/src/Bootstrap/Container.ts

@@ -166,6 +166,7 @@ import { SQLItem } from '../Infra/TypeORM/SQLItem'
 import { SQLItemPersistenceMapper } from '../Mapping/Persistence/SQLItemPersistenceMapper'
 import { SQLItemRepository } from '../Infra/TypeORM/SQLItemRepository'
 import { SendEventToClient } from '../Domain/UseCase/Syncing/SendEventToClient/SendEventToClient'
+import { TransitionRequestedEventHandler } from '../Domain/Handler/TransitionRequestedEventHandler'
 
 export class ContainerConfigLoader {
   private readonly DEFAULT_CONTENT_SIZE_TRANSFER_LIMIT = 10_000_000
@@ -955,6 +956,16 @@ export class ContainerConfigLoader {
           container.get<Logger>(TYPES.Sync_Logger),
         ),
       )
+    container
+      .bind<TransitionRequestedEventHandler>(TYPES.Sync_TransitionRequestedEventHandler)
+      .toConstantValue(
+        new TransitionRequestedEventHandler(
+          container.get<TriggerTransitionFromPrimaryToSecondaryDatabaseForUser>(
+            TYPES.Sync_TriggerTransitionFromPrimaryToSecondaryDatabaseForUser,
+          ),
+          container.get<Logger>(TYPES.Sync_Logger),
+        ),
+      )
 
     // Services
     container.bind<ContentDecoder>(TYPES.Sync_ContentDecoder).toDynamicValue(() => new ContentDecoder())
@@ -993,6 +1004,10 @@ export class ContainerConfigLoader {
         'TRANSITION_STATUS_UPDATED',
         container.get<TransitionStatusUpdatedEventHandler>(TYPES.Sync_TransitionStatusUpdatedEventHandler),
       ],
+      [
+        'TRANSITION_REQUESTED',
+        container.get<TransitionRequestedEventHandler>(TYPES.Sync_TransitionRequestedEventHandler),
+      ],
     ])
     if (!isConfiguredForHomeServer) {
       container.bind(TYPES.Sync_AUTH_SERVER_URL).toConstantValue(env.get('AUTH_SERVER_URL'))

+ 1 - 0
packages/syncing-server/src/Bootstrap/Types.ts

@@ -97,6 +97,7 @@ const TYPES = {
   Sync_SharedVaultFileUploadedEventHandler: Symbol.for('Sync_SharedVaultFileUploadedEventHandler'),
   Sync_SharedVaultFileMovedEventHandler: Symbol.for('Sync_SharedVaultFileMovedEventHandler'),
   Sync_TransitionStatusUpdatedEventHandler: Symbol.for('Sync_TransitionStatusUpdatedEventHandler'),
+  Sync_TransitionRequestedEventHandler: Symbol.for('Sync_TransitionRequestedEventHandler'),
   // Services
   Sync_ContentDecoder: Symbol.for('Sync_ContentDecoder'),
   Sync_DomainEventPublisher: Symbol.for('Sync_DomainEventPublisher'),

+ 23 - 0
packages/syncing-server/src/Domain/Handler/TransitionRequestedEventHandler.ts

@@ -0,0 +1,23 @@
+import { DomainEventHandlerInterface, TransitionRequestedEvent } from '@standardnotes/domain-events'
+import { Logger } from 'winston'
+
+import { TriggerTransitionFromPrimaryToSecondaryDatabaseForUser } from '../UseCase/Transition/TriggerTransitionFromPrimaryToSecondaryDatabaseForUser/TriggerTransitionFromPrimaryToSecondaryDatabaseForUser'
+
+export class TransitionRequestedEventHandler implements DomainEventHandlerInterface {
+  constructor(
+    private triggerTransitionFromPrimaryToSecondaryDatabaseForUser: TriggerTransitionFromPrimaryToSecondaryDatabaseForUser,
+    private logger: Logger,
+  ) {}
+
+  async handle(event: TransitionRequestedEvent): Promise<void> {
+    this.logger.info(`Handling transition requested event for user ${event.payload.userUuid}`)
+
+    const result = await this.triggerTransitionFromPrimaryToSecondaryDatabaseForUser.execute({
+      userUuid: event.payload.userUuid,
+    })
+
+    if (result.isFailed()) {
+      this.logger.error(`Failed to trigger transition for user ${event.payload.userUuid}`)
+    }
+  }
+}