import { env } from "cloudflare:workers";
import { deleteCookie, getCookie, setCookie } from "@tanstack/react-start/server";
import { first } from "./db";
import { randomToken, sha256Hex } from "./crypto";
import type { UserRow, Viewer } from "~/lib/types";
const SESSION_COOKIE_BASE = "gitfor_session";
const LOOPBACK_HOSTS = new Set(["localhost", "127.0.0.1", "[::1]"]);
/** `__Host-` (Secure, Path=/, no Domain) everywhere browsers accept Secure cookies; a plain-http dev host gets neither. */
export function cookieSecure(): boolean {
const url = new URL(env.PUBLIC_URL);
return url.protocol === "https:" || LOOPBACK_HOSTS.has(url.hostname);
}
export function cookieName(base: string): string {
return cookieSecure() ? `__Host-${base}` : base;
}
/** Attributes for hand-built Set-Cookie headers. */
export function cookieAttributes(maxAge: number): string {
return `Path=/; HttpOnly;${cookieSecure() ? " Secure;" : ""} SameSite=Lax; Max-Age=${maxAge}`;
}
const SESSION_TTL_SECONDS = 60 * 60 * 24 * 30;
export const PAT_PREFIX = "gitfor_pat";
type SessionRecord = { userId: string; createdAt: number };
function sessionKey(tokenHash: string): string {
return `session:${tokenHash}`;
}
export function toViewer(user: UserRow): Viewer {
return {
id: user.id,
name: user.name,
displayName: user.display_name,
email: user.email,
isAdmin: user.is_admin === 1,
};