fix: auth pages errors handler

This commit is contained in:
Ahmed Bouhuolia
2025-10-30 19:27:29 +02:00
parent 4a0091d3f8
commit 0588a30c88
14 changed files with 111 additions and 75 deletions

View File

@@ -24,7 +24,7 @@ export class AuthSendResetPasswordService {
@Inject(SystemUser.name)
private readonly systemUserModel: typeof SystemUser,
) {}
) { }
/**
* Sends the given email reset password email.
@@ -33,8 +33,9 @@ export class AuthSendResetPasswordService {
async sendResetPassword(email: string): Promise<void> {
const user = await this.systemUserModel
.query()
.findOne({ email })
.throwIfNotFound();
.findOne({ email });
if (!user) return;
const token: string = uniqid();
@@ -48,10 +49,8 @@ export class AuthSendResetPasswordService {
this.deletePasswordResetToken(email);
// Creates a new password reset row with unique token.
const passwordReset = await this.resetPasswordModel.query().insert({
email,
token,
});
await this.resetPasswordModel.query().insert({ email, token });
// Triggers sent reset password event.
await this.eventPublisher.emitAsync(events.auth.sendResetPassword, {
user,

View File

@@ -1,9 +1,11 @@
import { ClsService } from 'nestjs-cls';
import { Inject, Injectable, UnauthorizedException } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { SystemUser } from '@/modules/System/models/SystemUser';
import { ModelObject } from 'objection';
import { JwtPayload } from '../Auth.interfaces';
import { InvalidEmailPasswordException } from '../exceptions/InvalidEmailPassword.exception';
import { UserNotFoundException } from '../exceptions/UserNotFound.exception';
@Injectable()
export class AuthSigninService {
@@ -12,7 +14,7 @@ export class AuthSigninService {
private readonly systemUserModel: typeof SystemUser,
private readonly jwtService: JwtService,
private readonly clsService: ClsService,
) {}
) { }
/**
* Validates the given email and password.
@@ -32,14 +34,10 @@ export class AuthSigninService {
.findOne({ email })
.throwIfNotFound();
} catch (err) {
throw new UnauthorizedException(
`There isn't any user with email: ${email}`,
);
throw new InvalidEmailPasswordException(email);
}
if (!(await user.checkPassword(password))) {
throw new UnauthorizedException(
`Wrong password for user with email: ${email}`,
);
throw new InvalidEmailPasswordException(email);
}
return user;
}
@@ -61,9 +59,7 @@ export class AuthSigninService {
this.clsService.set('tenantId', user.tenantId);
this.clsService.set('userId', user.id);
} catch (error) {
throw new UnauthorizedException(
`There isn't any user with email: ${payload.sub}`,
);
throw new UserNotFoundException(String(payload.sub));
}
return payload;
}

View File

@@ -32,7 +32,7 @@ export class AuthSignupService {
@Inject(SystemUser.name)
private readonly systemUserModel: typeof SystemUser,
) {}
) { }
/**
* Registers a new tenant with user from user input.
@@ -121,7 +121,6 @@ export class AuthSignupService {
const isAllowedDomain = signupRestrictions.allowedDomains.some(
(domain) => emailDomain === domain,
);
if (!isAllowedEmail && !isAllowedDomain) {
throw new ServiceError(
ERRORS.SIGNUP_RESTRICTED_NOT_ALLOWED,

View File

@@ -0,0 +1,15 @@
import { UnauthorizedException } from '@nestjs/common';
import { ERRORS } from '../Auth.constants';
export class InvalidEmailPasswordException extends UnauthorizedException {
constructor(email: string) {
super({
statusCode: 401,
error: 'Unauthorized',
message: `Invalid email or password for ${email}`,
code: ERRORS.INVALID_DETAILS,
});
}
}

View File

@@ -0,0 +1,13 @@
import { UnauthorizedException } from '@nestjs/common';
import { ERRORS } from '../Auth.constants';
export class UserNotFoundException extends UnauthorizedException {
constructor(identifier: string) {
super({
statusCode: 401,
error: 'Unauthorized',
message: `User not found: ${identifier}`,
code: ERRORS.USER_NOT_FOUND,
});
}
}

View File

@@ -17,12 +17,11 @@ import { TenantUser } from '../Tenancy/TenancyModels/models/TenantUser.model';
@Injectable()
export class AuthorizationGuard implements CanActivate {
constructor(
private reflector: Reflector,
private readonly clsService: ClsService,
@Inject(TenantUser.name)
private readonly tenantUserModel: TenantModelProxy<typeof TenantUser>,
) {}
) { }
/**
* Checks if the user has the required abilities to access the route
@@ -31,7 +30,7 @@ export class AuthorizationGuard implements CanActivate {
*/
async canActivate(context: ExecutionContext): Promise<boolean> {
const request = context.switchToHttp().getRequest<Request>();
const { tenantId, user } = request as any;
const { user } = request as any;
if (ABILITIES_CACHE.has(user.id)) {
(request as any).ability = ABILITIES_CACHE.get(user.id);
@@ -40,7 +39,6 @@ export class AuthorizationGuard implements CanActivate {
(request as any).ability = ability;
ABILITIES_CACHE.set(user.id, ability);
}
return true;
}