Menu
Public repository / 1b41bcdd9e7d715e0117aa1edf8d3712789587b6
AkurAI-Mail / src/lib/auth.ts
Latest change 66e3647948f2e277afdd6ecd16939de8b6ad525f - Initial commit: AkurAI Mail UI (SvelteKit+Bun) by Ólafur Búi Ólafsson
import { createHash, timingSafeEqual } from "node:crypto";
import type { Cookies } from "@sveltejs/kit";
export const sessionCookie = "akurai_session";
export const mailboxSessionCookie = "akurai_mailbox_session";
const adminUser = process.env.AKURAI_ADMIN_USER ?? "admin";
const adminPassword = process.env.AKURAI_ADMIN_PASSWORD ?? "";
function digest(value: string) {
return createHash("sha256").update(value).digest("hex");
}
function same(a: string, b: string) {
const left = Buffer.from(a);
const right = Buffer.from(b);
return left.length === right.length && timingSafeEqual(left, right);
}
export function configuredUser() {
return adminUser;
}
export function validateCredentials(email: string, password: string) {
if (!adminPassword) return false;
return same(digest(email), digest(adminUser)) && same(digest(password), digest(adminPassword));
}
export function sessionValue() {
return digest(`${adminUser}:${adminPassword}`);
}
export function mailboxSessionValue(email: string) {
return `${email}:${digest(`${email}:${adminPassword}:mailbox`)}`;
}
export function isAuthenticated(cookies: Cookies) {
const value = cookies.get(sessionCookie) ?? "";
return Boolean(adminPassword && value && same(value, sessionValue()));
}
export function mailboxFromSession(cookies: Cookies) {
const value = cookies.get(mailboxSessionCookie) ?? "";
const separator = value.lastIndexOf(":");
if (separator < 1 || !adminPassword) return "";
const email = value.slice(0, separator);
const token = value.slice(separator + 1);
return same(token, digest(`${email}:${adminPassword}:mailbox`)) ? email : "";
}
export function isMailboxAuthenticated(cookies: Cookies) {
return Boolean(mailboxFromSession(cookies));
}
export function setSession(cookies: Cookies) {
cookies.set(sessionCookie, sessionValue(), {
path: "/",
httpOnly: true,
sameSite: "strict",
secure: false,
maxAge: 60 * 60 * 10
});
}
export function setMailboxSession(cookies: Cookies, email: string) {
cookies.set(mailboxSessionCookie, mailboxSessionValue(email), {
path: "/webmail",
httpOnly: true,
sameSite: "strict",
secure: false,
maxAge: 60 * 60 * 10
});
}
export function clearSession(cookies: Cookies) {
cookies.delete(sessionCookie, { path: "/" });
cookies.delete(mailboxSessionCookie, { path: "/webmail" });
}