Skip to content

Commit

Permalink
refactor and update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
duysolo committed Dec 14, 2024
1 parent 83e8594 commit ca5af30
Show file tree
Hide file tree
Showing 21 changed files with 74 additions and 69 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ import { Module } from '@nestjs/common'
},
jwt: {
secret: config.get('AUTH_JWT_SECRET'),
expiresIn: config.get('AUTH_JWT_EXPIRES') || '1d',
expiresIn: envRequired('AUTH_JWT_EXPIRES') || '1h',
refreshTokenExpiresIn: envRequired('AUTH_JWT_REFRESH_EXPIRES') || '7d',
},
transferTokenMethod: config.get<AuthTransferTokenMethod>(
'AUTH_TRANSFER_TOKEN_METHOD'
Expand Down
2 changes: 2 additions & 0 deletions src/application/actions/handlers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './login.command.handler'
export * from './user-logout.command.handler'
15 changes: 15 additions & 0 deletions src/application/actions/handlers/login.command.handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ICommandHandler, CommandHandler } from '@nestjs/cqrs'
import { lastValueFrom } from 'rxjs'
import { IAuthUserEntityForResponse, LocalLoginAction } from '../../../domain'
import { LoginCommand } from '../login.command'

@CommandHandler(LoginCommand)
export class LoginCommandHandler
implements ICommandHandler<LoginCommand, IAuthUserEntityForResponse>
{
public constructor(protected readonly action: LocalLoginAction) {}

public async execute(query: LoginCommand) {
return lastValueFrom(this.action.handle(query.input))
}
}
15 changes: 15 additions & 0 deletions src/application/actions/handlers/user-logout.command.handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { CommandHandler, ICommandHandler } from '@nestjs/cqrs'
import { lastValueFrom } from 'rxjs'
import { LogoutAction } from '../../../domain'
import { UserLogoutCommand } from '../user-logout.command'

@CommandHandler(UserLogoutCommand)
export class UserLogoutCommandHandler
implements ICommandHandler<UserLogoutCommand, void>
{
public constructor(protected readonly action: LogoutAction) {}

public async execute(query: UserLogoutCommand): Promise<void> {
return lastValueFrom(this.action.handle(query))
}
}
2 changes: 2 additions & 0 deletions src/application/actions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './login.command'
export * from './user-logout.command'
5 changes: 5 additions & 0 deletions src/application/actions/login.command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { AuthDto } from '../../domain'

export class LoginCommand {
public constructor(public readonly input: AuthDto) {}
}
5 changes: 5 additions & 0 deletions src/application/actions/user-logout.command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { ExecutionContext } from '@nestjs/common'

export class UserLogoutCommand {
public constructor(public readonly context: ExecutionContext) {}
}
2 changes: 0 additions & 2 deletions src/application/queries/handlers/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
export * from './get-current-user-by-access-token.query.handler'
export * from './get-current-user-by-refresh-token.query.handler'
export * from './login.query.handler'
export * from './user-logout.query.handler'
15 changes: 0 additions & 15 deletions src/application/queries/handlers/login.query.handler.ts

This file was deleted.

15 changes: 0 additions & 15 deletions src/application/queries/handlers/user-logout.query.handler.ts

This file was deleted.

2 changes: 0 additions & 2 deletions src/application/queries/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
export * from './get-current-user-by-access-token.query'
export * from './get-current-user-by-refresh-token.query'
export * from './login.query'
export * from './user-logout.query'
5 changes: 0 additions & 5 deletions src/application/queries/login.query.ts

This file was deleted.

7 changes: 0 additions & 7 deletions src/application/queries/user-logout.query.ts

This file was deleted.

15 changes: 9 additions & 6 deletions src/auth.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ import { JwtModule } from '@nestjs/jwt'
import {
GetCurrentUserByAccessTokenQueryHandler,
GetCurrentUserByRefreshTokenQueryHandler,
LoginQueryHandler,
UserLogoutQueryHandler,
} from './application/queries/handlers'
import {
AUTH_PASSWORD_HASHER,
Expand Down Expand Up @@ -55,6 +53,10 @@ import {
} from './presentation'
import { LogoutController } from './presentation/controllers/logout.controller'
import { HashingModule } from './hashing.module'
import {
LoginCommandHandler,
UserLogoutCommandHandler,
} from './application/actions/handlers'

export interface IAuthModuleOptions
extends Pick<ModuleMetadata, 'imports' | 'providers'> {
Expand Down Expand Up @@ -92,7 +94,7 @@ export class AuthModule implements NestModule {
useFactory: (definitions: IAuthDefinitions) => {
return {
secretKey: definitions.hashingSecretKey,
enabled: !!definitions.jwt && !!definitions.hashingSecretKey,
enabled: definitions.enableHashingToken,
}
},
inject: [AUTH_DEFINITIONS_MODULE_OPTIONS],
Expand Down Expand Up @@ -130,10 +132,10 @@ export class AuthModule implements NestModule {

TokenService,

LoginQueryHandler,
LoginCommandHandler,
GetCurrentUserByAccessTokenQueryHandler,
GetCurrentUserByRefreshTokenQueryHandler,
UserLogoutQueryHandler,
UserLogoutCommandHandler,

GetUserByJwtTokenAction,
GetUserByRefreshTokenAction,
Expand Down Expand Up @@ -217,7 +219,8 @@ export class AuthModule implements NestModule {
JwtStrategy,
RefreshTokenStrategy,

LoginQueryHandler,
LoginCommandHandler,
UserLogoutCommandHandler,
GetCurrentUserByAccessTokenQueryHandler,
GetCurrentUserByRefreshTokenQueryHandler,

Expand Down
4 changes: 2 additions & 2 deletions src/domain/actions/local-login.action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ export class LocalLoginAction {
public constructor(
@InjectAuthDefinitions()
protected readonly authDefinitions: IAuthDefinitions,
protected readonly authRepository: AuthRepository,
@InjectPasswordHasher()
protected readonly passwordHasherService: PasswordHasherService,
protected readonly authRepository: AuthRepository,
protected readonly tokenService: TokenService,
protected readonly eventBus: EventBus
) {}
Expand Down Expand Up @@ -108,7 +108,7 @@ export class LocalLoginAction {
new UserLoggedInEvent(user, impersonated, validatedDto, token)
)
),
map(({ user: userData, token }) => ({ userData, token } as T))
map(({ user: userData, token }) => ({ userData, token }) as T)
)
}

Expand Down
1 change: 1 addition & 0 deletions src/domain/definitions/auth-definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export interface IAuthDefinitions {
redactedFields?: string[]
ignoredRoutes?: string[]

enableHashingToken?: boolean
hashingSecretKey?: string

transferTokenMethod?: AuthTransferTokenMethod
Expand Down
1 change: 1 addition & 0 deletions src/domain/services/token.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export class TokenService {
userInfo[this.authDefinitions.usernameField || 'username']
),
sub: this.hashTextService.encode(userInfo.id),
iss: 'self-signed',
}).pipe(
map((payload) =>
this.jwtService.sign(payload, {
Expand Down
10 changes: 5 additions & 5 deletions src/domain/strategies/jwt.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { IAuthDefinitions } from '../index'

export const JWT_STRATEGY_NAME: string = 'jwt'

const cookieExtractor: (
export const cookieExtractor: (
transferTokenMethod: AuthTransferTokenMethod | undefined
) => JwtFromRequestFunction =
(transferTokenMethod) =>
Expand All @@ -33,7 +33,7 @@ const cookieExtractor: (
)
}

const accessTokenHeaderExtractor: (
export const accessTokenHeaderExtractor: (
transferTokenMethod: AuthTransferTokenMethod | undefined
) => JwtFromRequestFunction =
(transferTokenMethod) =>
Expand All @@ -53,7 +53,7 @@ const accessTokenHeaderExtractor: (

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy, JWT_STRATEGY_NAME) {
private readonly jwtFromRequest: JwtFromRequestFunction
private readonly _jwtFromRequest: JwtFromRequestFunction

public constructor(
@InjectAuthDefinitions()
Expand All @@ -72,7 +72,7 @@ export class JwtStrategy extends PassportStrategy(Strategy, JWT_STRATEGY_NAME) {
passReqToCallback: true,
})

this.jwtFromRequest = jwtFromRequest
this._jwtFromRequest = jwtFromRequest
}

public async validate(
Expand All @@ -81,7 +81,7 @@ export class JwtStrategy extends PassportStrategy(Strategy, JWT_STRATEGY_NAME) {
): Promise<IAuthResponse | undefined> {
return this.queryBus.execute(
new GetCurrentUserByAccessTokenQuery(
this.jwtFromRequest(request) || '',
this._jwtFromRequest(request) || '',
payload
)
)
Expand Down
10 changes: 5 additions & 5 deletions src/domain/strategies/local.strategy.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Injectable } from '@nestjs/common'
import { QueryBus } from '@nestjs/cqrs'
import { CommandBus } from '@nestjs/cqrs'
import { PassportStrategy } from '@nestjs/passport'
import { Strategy } from 'passport-local'
import { LoginQuery } from '../../application/queries'
import { InjectAuthDefinitions } from '../decorators'
import type { IAuthUserEntityForResponse } from '../definitions'
import { IAuthDefinitions } from '../index'
import { LoginCommand } from '../../application/actions'

export const LOCAL_STRATEGY_NAME: string = 'local'

Expand All @@ -14,7 +14,7 @@ export class LocalStrategy extends PassportStrategy(Strategy) {
public constructor(
@InjectAuthDefinitions()
protected readonly authDefinitions: IAuthDefinitions,
protected readonly queryBus: QueryBus
protected readonly bus: CommandBus
) {
super({
usernameField: authDefinitions.usernameField || 'username',
Expand All @@ -28,8 +28,8 @@ export class LocalStrategy extends PassportStrategy(Strategy) {
username: string,
password: string
): Promise<IAuthUserEntityForResponse> {
return this.queryBus.execute(
new LoginQuery({
return this.bus.execute(
new LoginCommand({
...request.body,
username,
password,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export const transferTokenFromResponseToCookie: (

const token: IJwtTokenResponse = authResponse.token

// eslint-disable-next-line guard-for-in
for (const responseKey in mapKeys) {
const currentToken = token[responseKey]
const currentKey = mapKeys[responseKey]
Expand Down
8 changes: 4 additions & 4 deletions src/presentation/interceptors/user-logout.interceptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import {
Injectable,
NestInterceptor,
} from '@nestjs/common'
import { QueryBus } from '@nestjs/cqrs'
import { CommandBus } from '@nestjs/cqrs'
import { asyncScheduler, map, mergeMap, Observable, scheduled } from 'rxjs'
import { UserLogoutQuery } from '../../application/queries'
import { UserLogoutCommand } from '../../application/actions'

@Injectable()
export class UserLogoutInterceptor implements NestInterceptor {
public constructor(protected readonly queryBus: QueryBus) {}
public constructor(protected readonly _bus: CommandBus) {}

public intercept(
context: ExecutionContext,
Expand All @@ -19,7 +19,7 @@ export class UserLogoutInterceptor implements NestInterceptor {
return next.handle().pipe(
mergeMap((res) => {
return scheduled(
this.queryBus.execute(new UserLogoutQuery(context)),
this._bus.execute(new UserLogoutCommand(context)),
asyncScheduler
).pipe(map(() => res))
})
Expand Down

0 comments on commit ca5af30

Please sign in to comment.