90 lines
2.2 KiB
TypeScript
90 lines
2.2 KiB
TypeScript
|
import {
|
||
|
Injectable,
|
||
|
NotFoundException,
|
||
|
BadRequestException,
|
||
|
} from '@nestjs/common'
|
||
|
import { PrismaService } from 'nestjs-prisma'
|
||
|
import { Prisma } from '@prisma/client'
|
||
|
import { PasswordService } from './password.service'
|
||
|
import { Token, UserToken } from './models/token.model'
|
||
|
import { JwtService } from '@nestjs/jwt'
|
||
|
import { ConfigService } from '@nestjs/config'
|
||
|
|
||
|
@Injectable()
|
||
|
export class AuthService {
|
||
|
constructor(
|
||
|
private prisma: PrismaService,
|
||
|
private passwordService: PasswordService,
|
||
|
private jwtService: JwtService,
|
||
|
private configService: ConfigService,
|
||
|
) {}
|
||
|
|
||
|
async createUser(payload: Prisma.UserCreateInput): Promise<UserToken> {
|
||
|
const hashedPassword = await this.passwordService.hashPassword(
|
||
|
payload.password,
|
||
|
)
|
||
|
const user = await this.prisma.user.create({
|
||
|
data: {
|
||
|
...payload,
|
||
|
password: hashedPassword,
|
||
|
},
|
||
|
})
|
||
|
|
||
|
return {
|
||
|
...this.generateTokens({ userId: user.id }),
|
||
|
...this.exclude(user, ['password']),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
async login(email: string, password: string): Promise<UserToken> {
|
||
|
const user = await this.prisma.user.findUnique({ where: { email } })
|
||
|
|
||
|
if (!user) {
|
||
|
throw new NotFoundException(`No user found for email: ${email}`)
|
||
|
}
|
||
|
|
||
|
const passwordValid = await this.passwordService.validatePassword(
|
||
|
password,
|
||
|
user.password,
|
||
|
)
|
||
|
|
||
|
if (!passwordValid) {
|
||
|
throw new BadRequestException('Invalid password')
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
...this.generateTokens({ userId: user.id }),
|
||
|
...this.exclude(user, ['password']),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private exclude<User, Key extends keyof User>(
|
||
|
user: User,
|
||
|
keys: Key[],
|
||
|
): Omit<User, Key> {
|
||
|
for (const key of keys) {
|
||
|
delete user[key]
|
||
|
}
|
||
|
return user
|
||
|
}
|
||
|
|
||
|
private generateTokens(payload: { userId: string }): Token {
|
||
|
const accessToken = this.jwtService.sign(payload, {
|
||
|
secret: this.configService.get<string>(
|
||
|
'JWT_ACCESS_SECRET',
|
||
|
'JWT_ACCESS_SECRET',
|
||
|
),
|
||
|
expiresIn: '30min',
|
||
|
})
|
||
|
const refreshToken = this.jwtService.sign(payload, {
|
||
|
secret: this.configService.get<string>(
|
||
|
'JWT_REFRESH_SECRET',
|
||
|
'JWT_REFRESH_SECRET',
|
||
|
),
|
||
|
expiresIn: '7d',
|
||
|
})
|
||
|
|
||
|
return { accessToken, refreshToken }
|
||
|
}
|
||
|
}
|