import { verify } from '@node-rs/argon2'; import { IsEmail, IsNotEmpty, IsOptional, IsString } from 'class-validator'; import { getConnectionManager } from 'typeorm'; import { InvalidCredentialsError, PasswordNeededError, UserDisabledError, UserNotFoundError } from '../../../errors/AuthError'; import { UsernameOrEmailNeededError } from '../../../errors/UserErrors'; import { JwtCreator } from '../../../jwtcreator'; import { User } from '../../entities/User'; import { ResponseAuth } from '../../responses/ResponseAuth'; /** * This class is used to create auth credentials based on user credentials provided in a json body (post request). * To be a little bit more exact: Is takes in a username/email + password and creates a new access and refresh token for the user. * It of course checks for user existance, password validity and so on. */ export class CreateAuth { /** * The username of the user that want's to login. * Either username or email have to be provided. */ @IsOptional() @IsString() username?: string; /** * The email address of the user that want's to login. * Either username or email have to be provided. */ @IsOptional() @IsEmail() @IsString() email?: string; /** * The user's password. * Will be checked against an argon2 hash. */ @IsNotEmpty() @IsString() password: string; /** * Creates a new auth object based on this. */ public async toAuth(): Promise { let newAuth: ResponseAuth = new ResponseAuth(); if (this.email === undefined && this.username === undefined) { throw new UsernameOrEmailNeededError(); } if (!this.password) { throw new PasswordNeededError(); } const found_user = await getConnectionManager().get().getRepository(User).findOne({ relations: ['groups', 'permissions', 'groups.permissions'], where: [{ username: this.username }, { email: this.email }] }); if (!found_user) { throw new UserNotFoundError(); } if (found_user.enabled == false) { throw new UserDisabledError(); } if (!(await verify(found_user.password, this.password + found_user.uuid))) { throw new InvalidCredentialsError(); } //Create the access token const timestamp_accesstoken_expiry = Math.floor(Date.now() / 1000) + 24 * 60 * 60 newAuth.access_token = JwtCreator.createAccess(found_user, timestamp_accesstoken_expiry); newAuth.access_token_expires_at = timestamp_accesstoken_expiry //Create the refresh token const timestamp_refresh_expiry = Math.floor(Date.now() / 1000) + 7 * 24 * 60 * 60 newAuth.refresh_token = JwtCreator.createRefresh(found_user, timestamp_refresh_expiry); newAuth.refresh_token_expires_at = timestamp_refresh_expiry return newAuth; } }