72 lines
2.2 KiB
TypeScript
72 lines
2.2 KiB
TypeScript
import { omit } from 'lodash';
|
|
import * as bcrypt from 'bcrypt';
|
|
import { Injectable } from '@nestjs/common';
|
|
import { PostgresErrorCode } from 'src/database/postgresErrorCodes.enum';
|
|
import { UsersService } from 'src/users/users.service';
|
|
import { RegisterDto } from './dto/register.dto';
|
|
import {
|
|
InternalErrorException,
|
|
UserEmailExistsException,
|
|
WrongCredentialsException,
|
|
} from 'src/utils/errors';
|
|
import { JwtService } from '@nestjs/jwt';
|
|
import { ConfigService } from '@nestjs/config';
|
|
import { TokenPayload } from './interfaces/token-payload.interface';
|
|
|
|
@Injectable()
|
|
export class AuthService {
|
|
constructor(
|
|
private readonly usersService: UsersService,
|
|
private readonly jwtService: JwtService,
|
|
private readonly configService: ConfigService,
|
|
) {}
|
|
|
|
public async register(registrationData: RegisterDto) {
|
|
const hashedPassword = await bcrypt.hash(registrationData.password, 10);
|
|
try {
|
|
const createdUser = await this.usersService.create({
|
|
...registrationData,
|
|
password: hashedPassword,
|
|
});
|
|
return omit(createdUser, 'password');
|
|
} catch (error) {
|
|
if (error?.code === PostgresErrorCode.UniqueViolation) {
|
|
throw new UserEmailExistsException();
|
|
}
|
|
throw new InternalErrorException();
|
|
}
|
|
}
|
|
|
|
public async getAuthenticatedUser(email: string, password: string) {
|
|
try {
|
|
const user = await this.usersService.getByEmail(email);
|
|
await this.verifyPassword(password, user.password);
|
|
return omit(user, 'password');
|
|
} catch (error) {
|
|
throw new WrongCredentialsException();
|
|
}
|
|
}
|
|
|
|
private async verifyPassword(plainPassword: string, hashedPassword: string) {
|
|
const isPasswordMatching = await bcrypt.compare(
|
|
plainPassword,
|
|
hashedPassword,
|
|
);
|
|
if (!isPasswordMatching) {
|
|
throw new WrongCredentialsException();
|
|
}
|
|
}
|
|
|
|
public async getCookieWithJwtToken(userId: number, username: string) {
|
|
const payload: TokenPayload = { id: userId, username };
|
|
const token = await this.jwtService.signAsync(payload);
|
|
return `Authentication=${token}; HttpOnly; Path=/; Max-Age=${this.configService.get(
|
|
'JWT_EXPIRATION_TIME',
|
|
)}`;
|
|
}
|
|
|
|
public getCookieForLogOut() {
|
|
return `Authentication=; HttpOnly; Path=/; Max-Age=0`;
|
|
}
|
|
}
|