auth in progress

This commit is contained in:
andres
2023-06-13 14:31:05 +02:00
parent 779b235363
commit 6f2fab076d
13 changed files with 181 additions and 29 deletions

View File

@@ -1,32 +1,104 @@
import { Injectable } from '@nestjs/common'
import { isAfter } from 'date-fns'
import { Injectable, UnauthorizedException } from '@nestjs/common'
import { addDays, isAfter } from 'date-fns'
import * as jwt from 'jsonwebtoken'
import * as bcrypt from 'bcrypt'
import { UsersRepository } from '../users/infrastructure/users.repository'
import * as process from 'process'
import { PrismaService } from '../../prisma.service'
@Injectable()
export class AuthService {
constructor(private usersRepository: UsersRepository) {}
constructor(private usersRepository: UsersRepository, private prisma: PrismaService) {}
createJwtTokensPair(userId: string, email: string | null) {
async revokeToken(token: string, userId: string): Promise<void> {
await this.prisma.revokedToken.create({
data: {
userId,
token,
},
})
}
async isTokenRevoked(token: string): Promise<boolean> {
const revokedToken = await this.prisma.revokedToken.findUnique({
where: { token },
})
return !!revokedToken
}
// Periodically remove old revoked tokens
async removeExpiredTokens(): Promise<void> {
const hourAgo = new Date()
hourAgo.setHours(hourAgo.getHours() - 1)
await this.prisma.revokedToken.deleteMany({
where: { revokedAt: { lt: hourAgo } },
})
}
async createJwtTokensPair(userId: string) {
const accessSecretKey = process.env.ACCESS_JWT_SECRET_KEY
const refreshSecretKey = process.env.REFRESH_JWT_SECRET_KEY
const payload: { userId: string; date: Date; email: string | null } = {
const payload: { userId: string; date: Date } = {
userId,
date: new Date(),
email,
}
const accessToken = jwt.sign(payload, accessSecretKey, { expiresIn: '1d' })
const accessToken = jwt.sign(payload, accessSecretKey, { expiresIn: '10m' })
const refreshToken = jwt.sign(payload, refreshSecretKey, {
expiresIn: '30d',
})
console.log(refreshToken.length)
// Save refresh token in the database
await this.prisma.refreshToken.create({
data: {
userId: userId,
token: refreshToken,
expiresAt: addDays(new Date(), 30),
isRevoked: false,
},
})
return {
accessToken,
refreshToken,
}
}
async checkToken(accessToken: string, refreshToken: string) {
try {
await jwt.verify(accessToken, process.env.ACCESS_JWT_SECRET_KEY)
return true
} catch (err) {
if (err instanceof jwt.TokenExpiredError) {
const dbRefreshToken = await this.prisma.refreshToken.findUnique({
where: { token: refreshToken },
})
const isTokenRevoked = await this.isTokenRevoked(accessToken)
if (isTokenRevoked) {
throw new UnauthorizedException()
}
if (dbRefreshToken && !dbRefreshToken.isRevoked && dbRefreshToken.expiresAt > new Date()) {
const newTokens = await this.createJwtTokensPair(dbRefreshToken.userId)
await this.prisma.refreshToken.update({
where: { id: dbRefreshToken.id },
data: { isRevoked: true },
})
return newTokens
}
}
throw err
}
}
async logout(accessToken: string, refreshToken: string) {
// Revoke the access token
const decoded = jwt.verify(accessToken, process.env.ACCESS_JWT_SECRET_KEY)
await this.revokeToken(accessToken, decoded.userId)
await this.prisma.refreshToken.update({
where: { token: refreshToken },
data: { isRevoked: true },
})
}
async checkCredentials(email: string, password: string) {
const user = await this.usersRepository.findUserByEmail(email)
if (!user /*|| !user.emailConfirmation.isConfirmed*/)
@@ -49,7 +121,7 @@ export class AuthService {
},
}
}
const tokensPair = this.createJwtTokensPair(user.id, user.email)
const tokensPair = await this.createJwtTokensPair(user.id)
return {
resultCode: 0,
data: tokensPair,