top-tran/backend/src/services/auth.service.ts
2026-04-27 20:33:09 -03:00

72 lines
No EOL
2.1 KiB
TypeScript

import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';
import crypto from 'node:crypto';
import { z } from 'zod';
import * as usersRepo from '../repositories/users.repository.js';
import * as tokensRepo from '../repositories/tokens.repository.js';
import { TokenType } from '../generated/prisma/enums.js';
const JWT_SECRET = process.env.JWT_SECRET ?? 'changeme';
const JWT_EXPIRES_IN = '15m';
const REFRESH_EXPIRES_DAYS = 7;
export const registerSchema = z.object({
name: z.string().check(z.minLength(2)),
email: z.email(),
password: z.string().check(z.minLength(6)),
});
export const loginSchema = z.object({
email: z.email(),
password: z.string().check(z.minLength(1)),
});
export async function register(input: z.infer<typeof registerSchema>) {
const existing = await usersRepo.findUserByEmail(input.email);
if (existing) throw new Error('Email already in use');
const hashed = await bcrypt.hash(input.password, 10);
const now = new Date();
const user = await usersRepo.createUser({
id: crypto.randomUUID(),
name: input.name,
email: input.email,
password: hashed,
updatedAt: now,
});
return { id: user.id, name: user.name, email: user.email };
}
export async function login(input: z.infer<typeof loginSchema>) {
const user = await usersRepo.findUserByEmail(input.email);
if (!user) throw new Error('Invalid credentials');
const valid = await bcrypt.compare(input.password, user.password);
if (!valid) throw new Error('Invalid credentials');
const accessToken = jwt.sign({ sub: user.id }, JWT_SECRET, { expiresIn: JWT_EXPIRES_IN });
const refreshToken = crypto.randomUUID();
const expiresAt = new Date();
expiresAt.setDate(expiresAt.getDate() + REFRESH_EXPIRES_DAYS);
await tokensRepo.createToken({
id: crypto.randomUUID(),
token: refreshToken,
type: TokenType.REFRESH,
userId: user.id,
expiresAt,
});
return { accessToken, refreshToken };
}
export async function logout(refreshToken: string) {
await tokensRepo.deleteToken(refreshToken);
}
export function verifyAccessToken(token: string): { sub: string } {
return jwt.verify(token, JWT_SECRET) as { sub: string };
}