From febe51db9c3c7ac014390a9170c3821651200cad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=97=D0=B0=D0=B8=D0=B4=20=D0=9E=D0=BC=D0=B0=D1=80=20?= =?UTF-8?q?=D0=9C=D0=B5=D0=B4=D1=85=D0=B0=D1=82=20=7C=20Zaid=20Omar=20Medh?= =?UTF-8?q?at?= Date: Tue, 27 Jan 2026 14:52:00 +0500 Subject: [PATCH] fix service --- src/auth/auth.service.ts | 101 +++++++++++++++++++++++++-------------- 1 file changed, 64 insertions(+), 37 deletions(-) diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts index 7daed63..1429e39 100644 --- a/src/auth/auth.service.ts +++ b/src/auth/auth.service.ts @@ -1,9 +1,13 @@ -import { Injectable, UnauthorizedException, BadRequestException } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; -import { JwtService } from '@nestjs/jwt'; -import { UsersService } from '../users/users.service'; -import { LoginDto, ChangePasswordDto, SetupPasswordDto } from './dto'; -import { TokenPair } from './interfaces'; +import { + Injectable, + UnauthorizedException, + BadRequestException, +} from "@nestjs/common"; +import { ConfigService } from "@nestjs/config"; +import { JwtService } from "@nestjs/jwt"; +import { UsersService } from "../users/users.service"; +import { LoginDto, ChangePasswordDto, SetupPasswordDto } from "./dto"; +import { TokenPair } from "./interfaces"; @Injectable() export class AuthService { @@ -13,44 +17,55 @@ export class AuthService { private usersService: UsersService, ) {} - async validateUser(loginDto: LoginDto): Promise<{ id: string; username: string }> { + async validateUser( + loginDto: LoginDto, + ): Promise<{ id: string; username: string }> { const { username, password } = loginDto; const user = await this.usersService.findByUsername(username); if (!user) { - throw new UnauthorizedException('Invalid credentials'); + throw new UnauthorizedException("Invalid credentials"); } if (!user.isPasswordSet) { - throw new BadRequestException('Password not set. Please use /auth/setup endpoint first.'); + throw new BadRequestException( + "Password not set. Please use /auth/setup endpoint first.", + ); } - const isPasswordValid = await this.usersService.validatePassword(user, password); + const isPasswordValid = await this.usersService.validatePassword( + user, + password, + ); if (!isPasswordValid) { - throw new UnauthorizedException('Invalid credentials'); + throw new UnauthorizedException("Invalid credentials"); } if (!user.isAdmin) { - throw new UnauthorizedException('Access denied'); + throw new UnauthorizedException("Access denied"); } return { id: user.id, username: user.username }; } - async setupPassword(setupPasswordDto: SetupPasswordDto): Promise<{ id: string; username: string }> { + async setupPassword( + setupPasswordDto: SetupPasswordDto, + ): Promise<{ id: string; username: string }> { const { username, password } = setupPasswordDto; const user = await this.usersService.findByUsername(username); if (!user) { - throw new UnauthorizedException('User not found'); + throw new UnauthorizedException("User not found"); } if (!user.isAdmin) { - throw new UnauthorizedException('Access denied'); + throw new UnauthorizedException("Access denied"); } if (user.isPasswordSet) { - throw new BadRequestException('Password already set. Use /auth/change-password to change it.'); + throw new BadRequestException( + "Password already set. Use /auth/change-password to change it.", + ); } await this.usersService.setupPassword(username, password); @@ -65,26 +80,29 @@ export class AuthService { const accessPayload = { sub: userId, username, - type: 'access', + type: "access", }; const refreshPayload = { sub: userId, username, - type: 'refresh', + type: "refresh", }; - const accessSecret = this.configService.get('JWT_ACCESS_SECRET') || 'default-secret'; - const refreshSecret = this.configService.get('JWT_REFRESH_SECRET') || 'default-refresh-secret'; + const accessSecret = + this.configService.get("JWT_ACCESS_SECRET") || "default-secret"; + const refreshSecret = + this.configService.get("JWT_REFRESH_SECRET") || + "default-refresh-secret"; const [accessToken, refreshToken] = await Promise.all([ this.jwtService.signAsync(accessPayload, { secret: accessSecret, - expiresIn: '15m', + expiresIn: "15m", }), this.jwtService.signAsync(refreshPayload, { secret: refreshSecret, - expiresIn: '7d', + expiresIn: "7d", }), ]); @@ -92,51 +110,60 @@ export class AuthService { } async refreshTokens(userId: string, username: string): Promise { - // Verify user still exists and is admin const user = await this.usersService.findById(userId); if (!user || !user.isAdmin) { - throw new UnauthorizedException('User not found or no longer authorized'); + throw new UnauthorizedException("User not found or no longer authorized"); } return this.generateTokens(userId, username); } getCookieOptions(isRefreshToken = false) { - const isProduction = this.configService.get('NODE_ENV') === 'production'; - const cookieSecure = this.configService.get('COOKIE_SECURE') === 'true'; + const isProduction = + this.configService.get("NODE_ENV") === "production"; + const cookieSecure = + this.configService.get("COOKIE_SECURE") === "true"; + const domain = this.configService.get("COOKIE_DOMAIN"); return { httpOnly: true, secure: isProduction || cookieSecure, - sameSite: 'lax' as const, - path: isRefreshToken ? '/auth/refresh' : '/', - maxAge: isRefreshToken - ? 7 * 24 * 60 * 60 * 1000 // 7 days for refresh token - : 15 * 60 * 1000, // 15 minutes for access token + sameSite: "none" as const, + path: isRefreshToken ? "/auth/refresh" : "/", + domain: domain, + maxAge: isRefreshToken ? 7 * 24 * 60 * 60 * 1000 : 15 * 60 * 1000, }; } getClearCookieOptions(isRefreshToken = false) { return { httpOnly: true, - path: isRefreshToken ? '/auth/refresh' : '/', + path: isRefreshToken ? "/auth/refresh" : "/", }; } - async changePassword(userId: string, changePasswordDto: ChangePasswordDto): Promise { + async changePassword( + userId: string, + changePasswordDto: ChangePasswordDto, + ): Promise { const { currentPassword, newPassword } = changePasswordDto; const user = await this.usersService.findById(userId); if (!user) { - throw new UnauthorizedException('User not found'); + throw new UnauthorizedException("User not found"); } - const isCurrentPasswordValid = await this.usersService.validatePassword(user, currentPassword); + const isCurrentPasswordValid = await this.usersService.validatePassword( + user, + currentPassword, + ); if (!isCurrentPasswordValid) { - throw new BadRequestException('Current password is incorrect'); + throw new BadRequestException("Current password is incorrect"); } if (currentPassword === newPassword) { - throw new BadRequestException('New password must be different from current password'); + throw new BadRequestException( + "New password must be different from current password", + ); } await this.usersService.updatePassword(userId, newPassword);