Files
schedule-parser-next/src/auth/auth.service.ts
n08i40k 2efceeaec4 1.3.1
Уведомления об обновлении приложения.
2024-10-06 02:43:13 +04:00

175 lines
4.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import {
ConflictException,
Injectable,
NotAcceptableException,
NotFoundException,
UnauthorizedException,
} from "@nestjs/common";
import { JwtService } from "@nestjs/jwt";
import {
SignInReqDto,
SignInResDto,
SignUpReqDto,
SignUpResDto,
ChangePasswordReqDto,
UpdateTokenReqDto,
UpdateTokenResDto,
} from "../dto/auth.dto";
import { UsersService } from "../users/users.service";
import { genSalt, hash } from "bcrypt";
import { Prisma, UserRole } from "@prisma/client";
import { Types } from "mongoose";
import { UserDto, UserRoleDto } from "../dto/user.dto";
@Injectable()
export class AuthService {
constructor(
private readonly usersService: UsersService,
private readonly jwtService: JwtService,
) {}
async decodeUserToken(token: string): Promise<UserDto> {
const jwtUser: { id: string } | null =
await this.jwtService.verifyAsync(token);
if (jwtUser === null) {
throw new UnauthorizedException(
"Некорректный или недействительный токен",
);
}
const user = await this.usersService
.findUnique({ id: jwtUser.id })
.then((user) => user as UserDto | null);
if (!user)
throw new UnauthorizedException("Не удалось найти пользователя!");
if (user.accessToken !== token) {
throw new UnauthorizedException(
"Некорректный или недействительный токен",
);
}
return user as UserDto;
}
async signUp(signUpDto: SignUpReqDto): Promise<SignUpResDto> {
const group = signUpDto.group.replaceAll(" ", "");
const username = signUpDto.username.replaceAll(" ", "");
if (
![UserRoleDto.STUDENT, UserRoleDto.TEACHER].includes(signUpDto.role)
) {
throw new NotAcceptableException("Передана неизвестная роль");
}
if (await this.usersService.contains({ username: username })) {
throw new ConflictException(
"Пользователь с таким именем уже существует!",
);
}
const salt = await genSalt(8);
const id = new Types.ObjectId().toString("hex");
const input: Prisma.UserCreateInput = {
id: id,
username: username,
salt: salt,
password: await hash(signUpDto.password, salt),
accessToken: await this.jwtService.signAsync({
id: id,
}),
role: signUpDto.role as UserRole,
group: group,
version: signUpDto.version ?? "1.0.0",
};
return this.usersService.create(input).then((user) => {
return {
id: user.id,
accessToken: user.accessToken,
};
});
}
async signIn(signInDto: SignInReqDto): Promise<SignInResDto> {
const user = await this.usersService.findUnique({
username: signInDto.username.replaceAll(" ", ""),
});
if (
!user ||
user.password !== (await hash(signInDto.password, user.salt))
) {
throw new UnauthorizedException(
"Некорректное имя пользователя или пароль!",
);
}
const accessToken = await this.jwtService.signAsync({ id: user.id });
await this.usersService.update({
where: { id: user.id },
data: { accessToken: accessToken },
});
return { id: user.id, accessToken: accessToken };
}
async updateToken(
updateTokenDto: UpdateTokenReqDto,
): Promise<UpdateTokenResDto> {
if (
!(await this.jwtService.verifyAsync(updateTokenDto.accessToken, {
ignoreExpiration: true,
}))
) {
throw new NotFoundException(
"Некорректный или недействительный токен!",
);
}
const jwtUser: { id: string } = await this.jwtService.decode(
updateTokenDto.accessToken,
);
const user = await this.usersService.findUnique({ id: jwtUser.id });
if (!user || user.accessToken !== updateTokenDto.accessToken) {
throw new NotFoundException(
"Некорректный или недействительный токен!",
);
}
const accessToken = await this.jwtService.signAsync({ id: user.id });
await this.usersService.update({
where: { id: user.id },
data: { accessToken: accessToken },
});
return { accessToken: accessToken };
}
async changePassword(
user: UserDto,
changePasswordReqDto: ChangePasswordReqDto,
): Promise<void> {
const { oldPassword, newPassword } = changePasswordReqDto;
if (oldPassword == newPassword)
throw new ConflictException("Пароли идентичны");
if (user.password !== (await hash(oldPassword, user.salt)))
throw new UnauthorizedException("Передан неверный исходный пароль");
await this.usersService.update({
where: { id: user.id },
data: {
password: await hash(newPassword, user.salt),
},
});
}
}