import { BcryptCrypto, Crypto } from "./crypto.ts"; import { Database } from "./database.ts"; import { Err, Ok, Result } from "./utils.ts"; export type LoginReq = { username: string; password: string; }; export type LoginRes = { sessionId: number; }; export type LoginError = | "internal" | "wrong username/password" | "account banned"; export class Sessions { public constructor( private db: Database, private crypto: Crypto = new BcryptCrypto(), ) {} public async login(req: LoginReq): Promise> { const findUserResult = await this.db.userWithUsername(req.username); if (!findUserResult.ok) { return Err("internal"); } if (!findUserResult.value.some) { return Err("wrong username/password"); } const user = findUserResult.value.value; if (!await this.crypto.compare(req.password, user.passwordHash)) { return Err("wrong username/password"); } const session = await this.db.createSession({ userId: user.id, }); if (!session.ok) { return Err("internal"); } return Ok({ sessionId: session.value.id, }); } }