Wire new routes; identity, summarize-url, dashboard, admin
This commit is contained in:
+34
-8
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user