2022-02-26 18:16:28 +01:00
|
|
|
import { Injectable, Logger } from '@nestjs/common';
|
2022-02-21 14:53:21 +01:00
|
|
|
import { JwtService } from '@nestjs/jwt';
|
|
|
|
|
import * as bcrypt from 'bcrypt';
|
2022-02-28 10:29:40 +01:00
|
|
|
import { instanceToPlain, plainToClass } from 'class-transformer';
|
2022-02-26 18:16:28 +01:00
|
|
|
import { validate } from 'class-validator';
|
2022-02-27 20:27:22 +01:00
|
|
|
import { JwtDataDto } from 'picsur-shared/dist/dto/auth.dto';
|
2022-03-06 12:34:33 +01:00
|
|
|
import { AsyncFailable, Fail, HasFailed } from 'picsur-shared/dist/types';
|
2022-03-07 20:19:58 +01:00
|
|
|
import { UsersService } from '../../collections/userdb/userdb.service';
|
|
|
|
|
import { EUserBackend } from '../../models/entities/user.entity';
|
2022-02-21 14:53:21 +01:00
|
|
|
|
|
|
|
|
@Injectable()
|
2022-03-07 20:19:58 +01:00
|
|
|
export class AuthManagerService {
|
2022-02-26 18:16:28 +01:00
|
|
|
private readonly logger = new Logger('AuthService');
|
|
|
|
|
|
2022-02-21 14:53:21 +01:00
|
|
|
constructor(
|
|
|
|
|
private usersService: UsersService,
|
|
|
|
|
private jwtService: JwtService,
|
|
|
|
|
) {}
|
|
|
|
|
|
2022-03-01 22:05:59 +01:00
|
|
|
async createUser(username: string, password: string): AsyncFailable<EUserBackend> {
|
2022-02-21 14:53:21 +01:00
|
|
|
const hashedPassword = await bcrypt.hash(password, 12);
|
2022-02-23 11:10:25 +01:00
|
|
|
return this.usersService.create(username, hashedPassword);
|
2022-02-21 14:53:21 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-01 22:05:59 +01:00
|
|
|
async deleteUser(user: string | EUserBackend): AsyncFailable<EUserBackend> {
|
2022-02-23 11:10:25 +01:00
|
|
|
return this.usersService.delete(user);
|
2022-02-21 14:53:21 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-01 22:05:59 +01:00
|
|
|
async listUsers(): AsyncFailable<EUserBackend[]> {
|
2022-02-26 16:06:32 +01:00
|
|
|
return this.usersService.findAll();
|
2022-02-21 14:53:21 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-10 23:02:27 +01:00
|
|
|
async userExists(username: string): Promise<boolean> {
|
|
|
|
|
return this.usersService.exists(username);
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-01 22:05:59 +01:00
|
|
|
async authenticate(username: string, password: string): AsyncFailable<EUserBackend> {
|
2022-02-26 16:06:32 +01:00
|
|
|
const user = await this.usersService.findOne(username, true);
|
2022-02-21 22:17:44 +01:00
|
|
|
if (HasFailed(user)) return user;
|
2022-02-21 14:53:21 +01:00
|
|
|
|
2022-02-21 22:17:44 +01:00
|
|
|
if (!(await bcrypt.compare(password, user.password)))
|
|
|
|
|
return Fail('Wrong password');
|
2022-02-21 14:53:21 +01:00
|
|
|
|
2022-02-26 16:06:32 +01:00
|
|
|
return await this.usersService.findOne(username);
|
2022-02-21 14:53:21 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-01 22:05:59 +01:00
|
|
|
async createToken(user: EUserBackend): Promise<string> {
|
2022-02-26 18:16:28 +01:00
|
|
|
const jwtData: JwtDataDto = plainToClass(JwtDataDto, {
|
2022-02-26 16:06:32 +01:00
|
|
|
user,
|
2022-02-26 18:16:28 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const errors = await validate(jwtData, { forbidUnknownValues: true });
|
|
|
|
|
if (errors.length > 0) {
|
|
|
|
|
this.logger.warn(errors);
|
|
|
|
|
throw new Error('Invalid jwt token generated');
|
|
|
|
|
}
|
2022-02-21 14:53:21 +01:00
|
|
|
|
2022-02-28 10:29:40 +01:00
|
|
|
return this.jwtService.signAsync(instanceToPlain(jwtData));
|
2022-02-21 14:53:21 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-01 22:05:59 +01:00
|
|
|
async makeAdmin(user: string | EUserBackend): AsyncFailable<true> {
|
2022-03-10 23:02:27 +01:00
|
|
|
return this.usersService.addRoles(user, ['admin']);
|
2022-02-21 14:53:21 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-01 22:05:59 +01:00
|
|
|
async revokeAdmin(user: string | EUserBackend): AsyncFailable<true> {
|
2022-03-10 23:02:27 +01:00
|
|
|
return this.usersService.removeRoles(user, ['admin']);
|
2022-02-21 14:53:21 +01:00
|
|
|
}
|
|
|
|
|
}
|