AkurAI Build
Menu

Public repository / dc540296357442733693769e22cd6944f7c2a721

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" });
}