import { compareSync, hashSync } from 'bcryptjs' import { HttpException, HttpStatus } from '@nestjs/common' import { Patient } from '../../../models/patient.model' export const AUTH_TOKEN_LENGTH = 5 export type AuthToken = { code: string encryptedCode: string } export const USER_HAS_NOT_TOKEN = 'User has not token' export const USERS_TOKEN_EXPIRED = "User's token expired" export const INVALID_TOKEN = 'Invalid token' export class AuthTokenHelper { static authTokenIsValid(patient: Patient, token: string): boolean { if (!patient.hasAuthToken()) { throw new HttpException({ message: USER_HAS_NOT_TOKEN }, HttpStatus.NOT_FOUND) } if (patient.hasExpiredAuthToken()) { throw new HttpException({ message: USERS_TOKEN_EXPIRED }, HttpStatus.UNAUTHORIZED) } if (!this.tokenMatch(token, patient.auth_token)) { throw new HttpException({ message: INVALID_TOKEN }, HttpStatus.UNAUTHORIZED) } return true } static buildAuthToken(givenCode?: string): AuthToken { const code = givenCode || this.generate(AUTH_TOKEN_LENGTH) return { code, encryptedCode: this.encrypt(code), } } private static generate(chars: number): string { let token = '' for (let index = 0; index < chars; index++) { token += Math.floor(Math.random() * 9).toString() } return token } private static encrypt(decrypted: any, salt = 10): string { return hashSync(decrypted, salt) } private static tokenMatch(decrypted: any, encrypted: string): boolean { return compareSync(decrypted, encrypted) } }