mirror of
https://github.com/ershisan99/flashcards-api.git
synced 2025-12-17 12:33:22 +00:00
auth in progress
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user