← Case study

POSTGRESQL REFERENCE · WORKING SOURCE

src/access.ts

This file ships in the runnable source archive. Synthetic fixtures and demonstration policies are identified in the README.

Download the complete project ↓
import { scryptSync, timingSafeEqual } from "node:crypto";
import type { Actor } from "./contracts.ts";
import { type DB, pool } from "./db.ts";
import { fail, hash } from "./errors.ts";
export const passwordHash = (password: string, salt: string = crypto.randomUUID()) =>
  `${salt}:${scryptSync(password, salt, 32).toString("hex")}`;
export function checkPassword(password: string, stored: string) {
  const [salt, expected] = stored.split(":");
  const actual = scryptSync(password, salt, 32);
  return expected.length === 64 &&
    timingSafeEqual(actual, Uint8Array.from(expected.match(/../g)!.map((x) => parseInt(x, 16))));
}
export function operator(actor: Actor) {
  if (actor.role !== "operator") fail(403, "FORBIDDEN", "This action requires a warehouse operator.");
}
export function customer(actor: Actor) {
  if (actor.role !== "customer") fail(403, "FORBIDDEN", "Sign in as a shipper to make a commercial booking.");
}
export async function authenticate(req: Request): Promise<Actor> {
  const token = (req.headers.get("cookie") ?? "").split(";").map((s) => s.trim()).find((s) =>
    s.startsWith("warehouse_session=")
  )?.split("=")[1];
  if (!token) fail(401, "UNAUTHENTICATED", "Sign in to continue.");
  const result = await pool.query(
    `SELECT u.id,u.email,u.name,m.org_id AS "orgId",m.role,o.name AS "orgName",s.csrf_token AS "csrfToken" FROM sessions s JOIN users u ON u.id=s.user_id JOIN memberships m ON m.user_id=u.id JOIN organizations o ON o.id=m.org_id WHERE s.token_hash=$1 AND s.expires_at>clock_timestamp()`,
    [await hash(token)],
  );
  if (!result.rowCount) fail(401, "UNAUTHENTICATED", "Your session has expired. Sign in again.");
  return result.rows[0];
}
export async function reservationAccess(db: DB, actor: Actor, id: string) {
  const r = (await db.query(
    `SELECT r.*,o.name AS customer_name,w.operator_org_id,w.timezone FROM reservations r JOIN organizations o ON o.id=r.customer_org_id JOIN warehouses w ON w.id=r.warehouse_id WHERE r.id=$1 AND (($2='customer' AND r.customer_org_id=$3) OR ($2='operator' AND w.operator_org_id=$3))`,
    [id, actor.role, actor.orgId],
  )).rows[0];
  if (!r) fail(404, "NOT_FOUND", "Reservation not found.");
  return r;
}
export async function quoteAccess(db: DB, actor: Actor, id: string) {
  const q = (await db.query(
    `SELECT q.*,w.operator_org_id,w.timezone FROM quotes q JOIN warehouses w ON w.id=q.warehouse_id WHERE q.id=$1 AND (($2='customer' AND q.customer_org_id=$3) OR ($2='operator' AND w.operator_org_id=$3))`,
    [id, actor.role, actor.orgId],
  )).rows[0];
  if (!q) fail(404, "NOT_FOUND", "Quote not found.");
  return q;
}
export async function palletAccess(db: DB, actor: Actor, id: string) {
  const p = (await db.query(
    `SELECT p.*,c.id AS custody_id,c.position_id,c.received_at,c.released_at,r.warehouse_id,r.end_at,w.timezone,w.operator_org_id FROM pallets p JOIN custodies c ON c.pallet_id=p.id JOIN reservations r ON r.id=p.reservation_id JOIN warehouses w ON w.id=r.warehouse_id WHERE p.id=$1 AND (($2='customer' AND p.owner_org_id=$3) OR ($2='operator' AND w.operator_org_id=$3))`,
    [id, actor.role, actor.orgId],
  )).rows[0];
  if (!p) fail(404, "NOT_FOUND", "Pallet not found.");
  return p;
}