diff --git a/src/auth/auth.controller.ts b/src/auth/auth.controller.ts index f778780..d9a174e 100644 --- a/src/auth/auth.controller.ts +++ b/src/auth/auth.controller.ts @@ -43,8 +43,8 @@ export class AuthController { @HttpCode(HttpStatus.OK) refreshTokens( @GetCurrentUserId() userId: number, - @GetCurrentUser('refreshToken') refreshToken: string, + @GetCurrentUser('email') email: string, ): Promise { - return this.authService.refreshTokens(userId, refreshToken); + return this.authService.refreshTokens(userId, email); } } diff --git a/src/auth/auth.module.ts b/src/auth/auth.module.ts index 5ea6142..54812eb 100644 --- a/src/auth/auth.module.ts +++ b/src/auth/auth.module.ts @@ -4,9 +4,10 @@ import { JwtModule } from '@nestjs/jwt'; import { AuthController } from './auth.controller'; import { AuthService } from './auth.service'; import { AtStrategy, RtStrategy } from './strategies'; +import { PrismaModule } from '../prisma/prisma.module'; @Module({ - imports: [JwtModule.register({})], + imports: [JwtModule.register({}), PrismaModule], controllers: [AuthController], providers: [AuthService, AtStrategy, RtStrategy], }) diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts index ca0d04d..279c5e6 100644 --- a/src/auth/auth.service.ts +++ b/src/auth/auth.service.ts @@ -3,8 +3,8 @@ import { ConfigService } from '@nestjs/config'; import { JwtService } from '@nestjs/jwt'; import { PrismaClientKnownRequestError } from '@prisma/client/runtime'; import * as argon from 'argon2'; -import { PrismaService } from '../prisma/prisma.service'; +import { PrismaService } from '../prisma/prisma.service'; import { AuthDto } from './dto'; import { JwtPayload, Tokens } from './types'; @@ -74,19 +74,9 @@ export class AuthService { return true; } - async refreshTokens(userId: number, rt: string): Promise { - const user = await this.prisma.user.findUnique({ - where: { - id: userId, - }, - }); - if (!user || !user.hashedRt) throw new ForbiddenException('Access Denied'); - - const rtMatches = await argon.verify(user.hashedRt, rt); - if (!rtMatches) throw new ForbiddenException('Access Denied'); - - const tokens = await this.getTokens(user.id, user.email); - await this.updateRtHash(user.id, tokens.refresh_token); + async refreshTokens(userId: number, email:string): Promise { + const tokens = await this.getTokens(userId, email); + await this.updateRtHash(userId, tokens.refresh_token); return tokens; } diff --git a/src/auth/strategies/at.strategy.ts b/src/auth/strategies/at.strategy.ts index ede4b7c..c0532c8 100644 --- a/src/auth/strategies/at.strategy.ts +++ b/src/auth/strategies/at.strategy.ts @@ -1,19 +1,27 @@ -import { Injectable } from '@nestjs/common'; +import { ForbiddenException, Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { PassportStrategy } from '@nestjs/passport'; import { ExtractJwt, Strategy } from 'passport-jwt'; +import { PrismaService } from '../../prisma/prisma.service'; import { JwtPayload } from '../types'; @Injectable() export class AtStrategy extends PassportStrategy(Strategy, 'jwt') { - constructor(config: ConfigService) { + constructor(config: ConfigService, private prisma: PrismaService) { super({ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), secretOrKey: config.get('AT_SECRET'), }); } - validate(payload: JwtPayload) { + async validate(payload: JwtPayload) { + const user = await this.prisma.user.findUnique({ + where: { + id: payload.sub, + }, + }); + if (!user || !user.hashedRt) throw new ForbiddenException('Access Denied'); + return payload; } } diff --git a/src/auth/strategies/rt.strategy.ts b/src/auth/strategies/rt.strategy.ts index f5d4311..ded1348 100644 --- a/src/auth/strategies/rt.strategy.ts +++ b/src/auth/strategies/rt.strategy.ts @@ -1,13 +1,15 @@ import { PassportStrategy } from '@nestjs/passport'; import { ExtractJwt, Strategy } from 'passport-jwt'; import { Request } from 'express'; +import * as argon from 'argon2'; import { ForbiddenException, Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { JwtPayload, JwtPayloadWithRt } from '../types'; +import { PrismaService } from 'src/prisma/prisma.service'; @Injectable() export class RtStrategy extends PassportStrategy(Strategy, 'jwt-refresh') { - constructor(config: ConfigService) { + constructor(config: ConfigService, private prisma: PrismaService) { super({ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), secretOrKey: config.get('RT_SECRET'), @@ -15,7 +17,7 @@ export class RtStrategy extends PassportStrategy(Strategy, 'jwt-refresh') { }); } - validate(req: Request, payload: JwtPayload): JwtPayloadWithRt { + async validate(req: Request, payload: JwtPayload): Promise { const refreshToken = req ?.get('authorization') ?.replace('Bearer', '') @@ -23,6 +25,16 @@ export class RtStrategy extends PassportStrategy(Strategy, 'jwt-refresh') { if (!refreshToken) throw new ForbiddenException('Refresh token malformed'); + const user = await this.prisma.user.findUnique({ + where: { + id: payload.sub, + }, + }); + if (!user || !user.hashedRt) throw new ForbiddenException('Access Denied'); + + const rtMatches = await argon.verify(user.hashedRt, refreshToken); + if (!rtMatches) throw new ForbiddenException('Access Denied'); + return { ...payload, refreshToken,