Wire new routes; identity, summarize-url, dashboard, admin

This commit is contained in:
Keysat
2026-06-13 13:36:30 -05:00
parent 04dcf86fa4
commit 318c6c4b81
20 changed files with 12407 additions and 499 deletions
+34 -8
View File
@@ -14,6 +14,8 @@
// entitlements: string[],
// reason: string | null }
import fs from "fs";
import path from "path";
import { getConfigSnapshot } from "./config.js";
const KEYSAT_CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour
@@ -23,6 +25,19 @@ const cache = new Map();
// Dynamically import the licensing client so it doesn't block boot
// if vendor/keysat-licensing-client is missing in dev environments.
// Construct the verifier on first use with the issuer public key
// embedded in the image at assets/issuer.pub — same PEM file Recap-app
// ships, so a license that validates in Recap also validates here.
//
// IMPORTANT: this used to call `mod.createVerifier()` (no args), which
// silently no-op'd because the licensing-client exports a `Verifier`
// CLASS, not a `createVerifier` factory. The result was that the
// verifier instance was always null → offline verification was skipped
// → entitlements always came back empty → tierFromEntitlements()
// always returned "core" regardless of what the license actually
// contained. Symptom: a real Pro license activated cleanly in Recap
// (showing the PRO badge) still saw Core credits on the relay. Fixed
// by using the documented Verifier + PublicKey.fromPem(pem) shape.
let verifierLoaded = false;
let verifier = null;
async function loadVerifier() {
@@ -30,17 +45,28 @@ async function loadVerifier() {
verifierLoaded = true;
try {
const mod = await import("@keysat/licensing-client");
// Same pattern Recap uses: build a verifier with the embedded
// public key. Recap's license.js shows the exact call; copy it
// here. For v0.1 we only need offline verification — if the
// vendor module signature differs across Recap versions we can
// tweak this.
if (mod?.createVerifier) {
verifier = mod.createVerifier();
if (!mod?.Verifier || !mod?.PublicKey) {
console.warn(
"[keysat] @keysat/licensing-client missing Verifier/PublicKey exports — leaving verifier null (all licenses will resolve to Core)"
);
return null;
}
// Locate the embedded issuer PEM. The Docker image copies
// assets/ to /app/assets/, so when this module runs from
// /app/server/keysat-client.js, the PEM is at ../assets/issuer.pub.
// Allow KEYSAT_ISSUER_PEM_PATH env override for local dev / tests.
const __dirname = path.dirname(new URL(import.meta.url).pathname);
const pemPath =
process.env.KEYSAT_ISSUER_PEM_PATH ||
path.join(__dirname, "..", "assets", "issuer.pub");
const pem = fs.readFileSync(pemPath, "utf8");
verifier = new mod.Verifier(mod.PublicKey.fromPem(pem));
console.log(
`[keysat] verifier ready (issuer PEM loaded from ${pemPath})`
);
} catch (err) {
console.warn(
`[keysat] failed to load @keysat/licensing-client (${err.message}) — will treat all licenses as anonymous`
`[keysat] failed to initialize verifier (${err.message}) — all licenses will resolve to Core until this is fixed`
);
}
return verifier;