53 lines
1.3 KiB
TypeScript
53 lines
1.3 KiB
TypeScript
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
|
import { UserService } from '../user/user.service';
|
|
import { JwtService } from '@nestjs/jwt';
|
|
import * as bcrypt from 'bcrypt';
|
|
import { User } from '../entity/user';
|
|
import { LoginRequest, LoginResponse } from '../types';
|
|
|
|
@Injectable()
|
|
export class AuthService {
|
|
constructor(
|
|
private userService: UserService,
|
|
private jwtService: JwtService,
|
|
) {}
|
|
|
|
async validateUser(username: string, pass: string): Promise<User | null> {
|
|
const user = await this.userService.findByUsername(username, {
|
|
groups: {
|
|
roles: true,
|
|
},
|
|
});
|
|
if (user && (await bcrypt.compare(pass, user.password))) {
|
|
return user;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
async login(loginData: LoginRequest): Promise<LoginResponse> {
|
|
const user: User | null = await this.validateUser(
|
|
loginData.username,
|
|
loginData.password,
|
|
);
|
|
|
|
if (!user) {
|
|
throw new UnauthorizedException();
|
|
}
|
|
|
|
const roles: Set<string> = new Set<string>();
|
|
for (const group of user.groups ?? []) {
|
|
for (const role of group.roles ?? []) {
|
|
roles.add(role.name);
|
|
}
|
|
}
|
|
const payload = {
|
|
username: user.username,
|
|
sub: user.id,
|
|
roles: Array.from(roles),
|
|
};
|
|
return {
|
|
access_token: this.jwtService.sign(payload),
|
|
};
|
|
}
|
|
}
|