diff --git a/template/nest-next/src/auth/auth.module.ts b/template/nest-next/src/auth/auth.module.ts index 9324a182..8e01ea53 100644 --- a/template/nest-next/src/auth/auth.module.ts +++ b/template/nest-next/src/auth/auth.module.ts @@ -5,6 +5,7 @@ import { RedisSessionRepository } from './repository/redis-session.repository'; import { IssueApiTokenService, IssueTokenSerivce, + RevokeAllUserSessionService, RevokeApiTokenService, RevokeTokenService, } from './commands'; @@ -20,6 +21,7 @@ import { GetTokenService } from './queries/get-token'; import { TokenRepository } from './repository/token.repository'; import { ApiTokenService } from './api-token.service'; import { RefreshTokenService } from './commands/refresh-token.command'; +import { KickoutUserEventHandler } from './event-handler'; @Module({ imports: [MikroOrmModule.forFeature([User])], @@ -39,7 +41,9 @@ import { RefreshTokenService } from './commands/refresh-token.command'; GetTokenService, RevokeTokenService, GetApiTokenService, + RevokeAllUserSessionService, RefreshTokenService, + KickoutUserEventHandler, ], exports: [AuthService, ApiTokenService], }) diff --git a/template/nest-next/src/auth/commands/index.ts b/template/nest-next/src/auth/commands/index.ts index 3adc6e42..dcbb628b 100644 --- a/template/nest-next/src/auth/commands/index.ts +++ b/template/nest-next/src/auth/commands/index.ts @@ -2,3 +2,4 @@ export * from './issue-api-token.command'; export * from './issue-token.command'; export * from './revoke-api-token.command'; export * from './revoke-token.command'; +export * from './revoke-all-user-session.command'; diff --git a/template/nest-next/src/auth/commands/revoke-all-user-session.command.ts b/template/nest-next/src/auth/commands/revoke-all-user-session.command.ts new file mode 100644 index 00000000..aed69b32 --- /dev/null +++ b/template/nest-next/src/auth/commands/revoke-all-user-session.command.ts @@ -0,0 +1,17 @@ +import { Command, ICommandHandler } from '@nestjs/cqrs'; +import { UserId } from '../../user'; +import { RedisSessionRepository } from '../repository/redis-session.repository'; + +export class RevokeAllUserSession extends Command { + constructor(public readonly uid: UserId) { + super(); + } +} + +export class RevokeAllUserSessionService implements ICommandHandler { + constructor(private readonly sessionRepository: RedisSessionRepository) {} + + async execute(command: RevokeAllUserSession) { + await this.sessionRepository.revokeAllSession(command.uid); + } +} diff --git a/template/nest-next/src/auth/event-handler/index.ts b/template/nest-next/src/auth/event-handler/index.ts new file mode 100644 index 00000000..a40b532e --- /dev/null +++ b/template/nest-next/src/auth/event-handler/index.ts @@ -0,0 +1 @@ +export { KickoutUserEventHandler } from './kick-out-user'; diff --git a/template/nest-next/src/auth/event-handler/kick-out-user.ts b/template/nest-next/src/auth/event-handler/kick-out-user.ts new file mode 100644 index 00000000..02af35e5 --- /dev/null +++ b/template/nest-next/src/auth/event-handler/kick-out-user.ts @@ -0,0 +1,11 @@ +import { CommandBus, EventsHandler, IEventHandler } from '@nestjs/cqrs'; +import { UserPasswordChangedEvent, UserRemovedEvent } from '../../user'; +import { RevokeAllUserSession } from '../commands'; + +@EventsHandler(UserRemovedEvent, UserPasswordChangedEvent) +export class KickoutUserEventHandler implements IEventHandler { + constructor(private readonly cb: CommandBus) {} + async handle(event: UserRemovedEvent) { + await this.cb.execute(new RevokeAllUserSession(event.userId)); + } +} diff --git a/template/nest-next/src/user/index.ts b/template/nest-next/src/user/index.ts index f9f9eb2f..8302a68d 100644 --- a/template/nest-next/src/user/index.ts +++ b/template/nest-next/src/user/index.ts @@ -1,3 +1,4 @@ export { User, UserRole } from './user.entity'; export type { UserId } from './user.entity'; export * from './error'; +export * from './events';