import * as bcrypt from 'bcrypt' import {Field, FieldType, Model} from '../../../orm' import {Authenticatable, AuthenticatableIdentifier} from '../../types' import {Injectable} from '../../../di' import {Awaitable, JSONState} from '../../../util' /** * A basic ORM-driven user class. */ @Injectable() export class ORMUser extends Model implements Authenticatable { protected static table = 'users' protected static key = 'user_id' /** The primary key of the user in the table. */ @Field(FieldType.serial, 'user_id') public userId!: number /** The unique string-identifier of the user. */ @Field(FieldType.varchar) public username!: string /** The user's first name. */ @Field(FieldType.varchar, 'first_name') public firstName?: string /** The user's last name. */ @Field(FieldType.varchar, 'last_name') public lastName?: string /** The hashed and salted password of the user. */ @Field(FieldType.varchar, 'password_hash') public passwordHash!: string /** Human-readable display name of the user. */ getDisplay(): string { if ( this.firstName || this.lastName ) { return `${this.firstName} ${this.lastName}` } return this.username } /** Globally-unique identifier of the user. */ getUniqueIdentifier(): AuthenticatableIdentifier { return `user-${this.userId}` } /** Unique identifier of the user. */ getIdentifier(): AuthenticatableIdentifier { return this.username } /** Check if the provided password is valid for the user. */ verifyPassword(password: string): Awaitable { return bcrypt.compare(password, this.passwordHash) } /** Change the user's password, hashing it. */ async setPassword(password: string): Promise { this.passwordHash = await bcrypt.hash(password, 10) } validateCredential(credential: string): Awaitable { return this.verifyPassword(credential) } async dehydrate(): Promise { return this.toQueryRow() } async rehydrate(state: JSONState): Promise { await this.assumeFromSource(state) } }