← back to Grant
lib/sister-auth.ts
50 lines
import { NextResponse } from 'next/server';
/**
* lib/sister-auth.ts — outbound credentials for cross-service calls into
* sibling DW services (Patty, PoppyPetitions, Freddy, etc.).
*
* 2026-05-05 (tick 30 + architect-reviewer reverse port): copied from
* Patty's lib/sister-auth.ts. Grant doesn't currently make sister-service
* calls, but the moment it does (e.g. → Patty for "find petitions matching
* this grant's cause", → Freddy for "lookup foundations in the marketplace
* catalog"), this is the canonical helper to use.
*
* Falls back to AUTH_PASSWORD which Grant's own login already requires.
* If neither password env is set, SISTER_AUTH is '' and SISTER_OK is false;
* route handlers MUST gate on SISTER_OK and return sisterUnconfigured()
* instead of fetching with empty creds (which would silently 401 and look
* like a bug).
*
* NOTE on `?? 'admin'`: the username default is intentional and SAFE —
* 'admin' is not a secret, just the conventional username across all DW
* Express services. The anti-pattern rule (no literal fallbacks) targets
* PASSWORDS and SECRETS specifically. Using `??` (not `||`) so an explicit
* empty-string SISTER_AUTH_USERNAME is preserved (treated as "unset" only
* when actually undefined/null).
*/
const SISTER_PASS = process.env.SISTER_AUTH_PASSWORD ?? process.env.AUTH_PASSWORD ?? '';
const SISTER_USER = process.env.SISTER_AUTH_USERNAME ?? 'admin';
export const SISTER_AUTH: string = SISTER_PASS
? 'Basic ' + Buffer.from(`${SISTER_USER}:${SISTER_PASS}`).toString('base64')
: '';
export const SISTER_OK: boolean = SISTER_AUTH !== '';
export function sisterUnconfigured(): NextResponse {
return NextResponse.json(
{ error: 'sister auth not configured (SISTER_AUTH_PASSWORD or AUTH_PASSWORD env required)' },
{ status: 503 },
);
}
/**
* Raw credentials for sister services that use form/JSON login (e.g. cookie
* auth via /api/auth/login) rather than a Basic Authorization header.
*/
export function sisterCredentials(): { username: string; password: string } {
return { username: SISTER_USER, password: SISTER_PASS };
}