diff --git a/apps/api/package.json b/apps/api/package.json index 0d8df50..c5fc66c 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -57,6 +57,7 @@ "@nestjs/cli": "^11.0.0", "@nestjs/schematics": "^11.0.0", "@nestjs/testing": "^11.0.1", + "@types/bcrypt": "^5.0.2", "@types/bip32": "^2.0.4", "@types/cron": "^2.4.3", "@types/express": "^5.0.0", diff --git a/apps/api/src/auth/auth.service.ts b/apps/api/src/auth/auth.service.ts index afdc429..a74a860 100644 --- a/apps/api/src/auth/auth.service.ts +++ b/apps/api/src/auth/auth.service.ts @@ -1,9 +1,9 @@ import { Injectable, BadRequestException, UnauthorizedException } from '@nestjs/common'; -import * as bcrypt from 'bcrypt'; import { JwtService } from '@nestjs/jwt'; import { PrismaService } from '../prisma/prisma.service'; import { RegisterMerchantDto } from './dto/register-merchant.dto'; import { LoginMerchantDto } from './dto/login-merchant.dto'; +import { comparePassword, hashPassword } from './password.util'; @Injectable() export class AuthService { @@ -26,7 +26,7 @@ export class AuthService { const existing = await this.prisma.merchant.findUnique({ where: { email: dto.email } }); if (existing) throw new BadRequestException('Email already in use'); - const hash = await bcrypt.hash(dto.password, 12); + const hash = await hashPassword(dto.password); const merchant = await this.prisma.merchant.create({ data: { email: dto.email, passwordHash: hash }, @@ -39,7 +39,7 @@ export class AuthService { const merchant = await this.prisma.merchant.findUnique({ where: { email: dto.email } }); if (!merchant) throw new UnauthorizedException('Invalid credentials'); - const ok = await bcrypt.compare(dto.password, merchant.passwordHash); + const ok = await comparePassword(dto.password, merchant.passwordHash); if (!ok) throw new UnauthorizedException('Invalid credentials'); const payload = { merchant_id: merchant.id }; diff --git a/apps/api/src/auth/password.util.ts b/apps/api/src/auth/password.util.ts new file mode 100644 index 0000000..8dbfacb --- /dev/null +++ b/apps/api/src/auth/password.util.ts @@ -0,0 +1,11 @@ +import * as bcrypt from 'bcrypt'; + +const SALT_ROUNDS = 12; + +export function hashPassword(password: string): Promise { + return bcrypt.hash(password, SALT_ROUNDS); +} + +export function comparePassword(password: string, hash: string): Promise { + return bcrypt.compare(password, hash); +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 87d6cf4..9d4ba2f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -183,6 +183,9 @@ importers: '@nestjs/testing': specifier: ^11.0.1 version: 11.1.27(@nestjs/common@11.1.27(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.27)(@nestjs/platform-express@11.1.27) + '@types/bcrypt': + specifier: ^5.0.2 + version: 5.0.2 '@types/bip32': specifier: ^2.0.4 version: 2.0.4 @@ -5009,6 +5012,12 @@ packages: } deprecated: This is a stub types definition. bip32 provides its own type definitions, so you do not need this installed. + '@types/bcrypt@5.0.2': + resolution: + { + integrity: sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ==, + } + '@types/body-parser@1.19.6': resolution: { @@ -16372,6 +16381,10 @@ snapshots: dependencies: bip32: 4.0.0 + '@types/bcrypt@5.0.2': + dependencies: + '@types/node': 22.20.0 + '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38