fix(auth): use custom UnauthorizedException for structured 401 error responses
LocalStrategy and auth controllers were importing UnauthorizedException from @nestjs/common instead of @modules/shared. While both return 401, only the custom DomainException-based version produces the structured error format (errorCode, correlationId, timestamp) expected by the GlobalExceptionFilter's primary code path. Also adds handleRequest() override to LocalAuthGuard to ensure custom exceptions from the strategy propagate directly without Passport transforming them. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import { Inject, Injectable, UnauthorizedException } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { PassportStrategy } from '@nestjs/passport';
|
import { PassportStrategy } from '@nestjs/passport';
|
||||||
import { Strategy } from 'passport-local';
|
import { Strategy } from 'passport-local';
|
||||||
import { normalizeVietnamPhone } from '@modules/shared';
|
import { normalizeVietnamPhone, UnauthorizedException } from '@modules/shared';
|
||||||
import { USER_REPOSITORY, type IUserRepository } from '../../domain/repositories/user.repository';
|
import { USER_REPOSITORY, type IUserRepository } from '../../domain/repositories/user.repository';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ import {
|
|||||||
Post,
|
Post,
|
||||||
Req,
|
Req,
|
||||||
Res,
|
Res,
|
||||||
UnauthorizedException,
|
|
||||||
UseGuards,
|
UseGuards,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { type CommandBus, type QueryBus } from '@nestjs/cqrs';
|
import { type CommandBus, type QueryBus } from '@nestjs/cqrs';
|
||||||
import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth, ApiBody } from '@nestjs/swagger';
|
import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth, ApiBody } from '@nestjs/swagger';
|
||||||
import { Throttle } from '@nestjs/throttler';
|
import { Throttle } from '@nestjs/throttler';
|
||||||
import type { Request, Response } from 'express';
|
import type { Request, Response } from 'express';
|
||||||
|
import { UnauthorizedException } from '@modules/shared';
|
||||||
import { LoginUserCommand } from '../../application/commands/login-user/login-user.command';
|
import { LoginUserCommand } from '../../application/commands/login-user/login-user.command';
|
||||||
import { RefreshTokenCommand } from '../../application/commands/refresh-token/refresh-token.command';
|
import { RefreshTokenCommand } from '../../application/commands/refresh-token/refresh-token.command';
|
||||||
import { RegisterUserCommand } from '../../application/commands/register-user/register-user.command';
|
import { RegisterUserCommand } from '../../application/commands/register-user/register-user.command';
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ import {
|
|||||||
Query,
|
Query,
|
||||||
Req,
|
Req,
|
||||||
Res,
|
Res,
|
||||||
UnauthorizedException,
|
|
||||||
UseGuards,
|
UseGuards,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
|
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
|
||||||
import { Throttle } from '@nestjs/throttler';
|
import { Throttle } from '@nestjs/throttler';
|
||||||
import type { Request, Response } from 'express';
|
import type { Request, Response } from 'express';
|
||||||
|
import { UnauthorizedException } from '@modules/shared';
|
||||||
import { type TokenPair } from '../../infrastructure/services/token.service';
|
import { type TokenPair } from '../../infrastructure/services/token.service';
|
||||||
import { type ZaloOAuthStrategy } from '../../infrastructure/strategies/zalo-oauth.strategy';
|
import { type ZaloOAuthStrategy } from '../../infrastructure/strategies/zalo-oauth.strategy';
|
||||||
import { GoogleOAuthGuard } from '../guards/google-oauth.guard';
|
import { GoogleOAuthGuard } from '../guards/google-oauth.guard';
|
||||||
|
|||||||
@@ -1,5 +1,18 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { type ExecutionContext, Injectable } from '@nestjs/common';
|
||||||
import { AuthGuard } from '@nestjs/passport';
|
import { AuthGuard } from '@nestjs/passport';
|
||||||
|
import { UnauthorizedException } from '@modules/shared';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class LocalAuthGuard extends AuthGuard('local') {}
|
export class LocalAuthGuard extends AuthGuard('local') {
|
||||||
|
override handleRequest<T>(err: Error | null, user: T, _info: unknown, _context: ExecutionContext): T {
|
||||||
|
// If the strategy threw a DomainException (e.g. our custom UnauthorizedException),
|
||||||
|
// re-throw it directly so GlobalExceptionFilter produces the structured error format.
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
if (!user) {
|
||||||
|
throw new UnauthorizedException('Số điện thoại hoặc mật khẩu không đúng');
|
||||||
|
}
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user