grill-blog/sessions.ts
2024-05-13 23:50:54 +02:00

48 lines
1.2 KiB
TypeScript

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<Result<LoginRes, LoginError>> {
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,
});
}
}