import { Authenticatable, AuthenticatableIdentifier, AuthenticatableRepository, } from '../../types' import {Awaitable, Maybe, uuid4} from '../../../util' import {ORMUser} from './ORMUser' import {Container, Inject, Injectable} from '../../../di' import {AuthenticatableAlreadyExistsError} from '../../AuthenticatableAlreadyExistsError' /** * A user repository implementation that looks up users stored in the database. */ @Injectable() export class ORMUserRepository extends AuthenticatableRepository { @Inject('injector') protected readonly injector!: Container /** Look up the user by their username. */ getByIdentifier(id: AuthenticatableIdentifier): Awaitable> { return (this.injector.getStaticOverride(ORMUser) as typeof ORMUser).query() .where('username', '=', id) .first() } /** Returns true if this repository supports registering users. */ supportsRegistration(): boolean { return true } /** Create a user in this repository from basic credentials. */ async createFromCredentials(username: string, password: string): Promise { if ( await this.getByIdentifier(username) ) { throw new AuthenticatableAlreadyExistsError(`Authenticatable already exists with credentials.`, { username, }) } const user = this.injector.makeByStaticOverride(ORMUser) user.username = username await user.setPassword(password) await user.save() return user } /** Create a user in this repository from an external Authenticatable instance. */ async createFromExternal(user: Authenticatable): Promise { return this.createFromCredentials(String(user.getUniqueIdentifier()), uuid4()) } }