fix: derive internal dynamic rectification token
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
import { createHash } from "node:crypto";
|
||||
|
||||
export function resolveDynamicRectificationToken(
|
||||
configuredToken: string | undefined,
|
||||
serviceRoleKey: string | undefined,
|
||||
): string | null {
|
||||
const configured = configuredToken?.trim();
|
||||
if (configured) return configured;
|
||||
const serviceRole = serviceRoleKey?.trim();
|
||||
if (!serviceRole) return null;
|
||||
return createHash("sha256")
|
||||
.update(`jyotisha-dynamic-rectification-v1:${serviceRole}`)
|
||||
.digest("hex");
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
createJourneyEngineWire,
|
||||
} from "./birth-time-journey-engine-model.ts";
|
||||
import type { BirthTimeJourneyEngine } from "./birth-time-journey-service.ts";
|
||||
import { resolveDynamicRectificationToken } from "./birth-time-dynamic-token.ts";
|
||||
|
||||
export {
|
||||
BirthTimeJourneyEngineConfigurationError,
|
||||
@@ -16,7 +17,10 @@ export function createJyotishBirthTimeJourneyEngine(
|
||||
): BirthTimeJourneyEngine {
|
||||
return createJourneyEngineMethods(createJourneyEngineWire({
|
||||
apiBase,
|
||||
dynamicToken: process.env.JYOTISH_DYNAMIC_RECTIFICATION_TOKEN ?? null,
|
||||
dynamicToken: resolveDynamicRectificationToken(
|
||||
process.env.JYOTISH_DYNAMIC_RECTIFICATION_TOKEN,
|
||||
process.env.SUPABASE_SERVICE_ROLE_KEY,
|
||||
),
|
||||
fetchImpl: fetch,
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
eventScorePayload,
|
||||
} from "../src/lib/birth-time-journey-engine-model.ts";
|
||||
import type { JourneyEngineFetch } from "../src/lib/birth-time-journey-engine-model.ts";
|
||||
import { resolveDynamicRectificationToken } from "../src/lib/birth-time-dynamic-token.ts";
|
||||
|
||||
test("journey engine serializes only stored event-scoring inputs", () => {
|
||||
const payload = eventScorePayload({
|
||||
@@ -191,6 +192,12 @@ test("missing dynamic token fails both endpoints before fetch", async () => {
|
||||
assert.equal(harness.calls.length, 0);
|
||||
});
|
||||
|
||||
test("dynamic token derives only from a server-side service role fallback", () => {
|
||||
assert.equal(resolveDynamicRectificationToken("configured-token", "service-role"), "configured-token");
|
||||
assert.match(resolveDynamicRectificationToken(undefined, "service-role") ?? "", /^[a-f0-9]{64}$/);
|
||||
assert.equal(resolveDynamicRectificationToken(undefined, undefined), null);
|
||||
});
|
||||
|
||||
test("legacy wire calls never receive dynamic authorization", async () => {
|
||||
const calls: { readonly path: string; readonly init: RequestInit }[] = [];
|
||||
const engine = createJourneyEngineMethods(createJourneyEngineWire({
|
||||
|
||||
@@ -1510,6 +1510,12 @@ class JyotishAPIHandler(BaseHTTPRequestHandler):
|
||||
|
||||
def _require_dynamic_rectification_token(self):
|
||||
configured = os.environ.get('JYOTISH_DYNAMIC_RECTIFICATION_TOKEN', '').strip()
|
||||
if not configured:
|
||||
service_role = os.environ.get('SUPABASE_SERVICE_ROLE_KEY', '').strip()
|
||||
if service_role:
|
||||
configured = hashlib.sha256(
|
||||
f'jyotisha-dynamic-rectification-v1:{service_role}'.encode('utf-8')
|
||||
).hexdigest()
|
||||
supplied = self._job_access_token()
|
||||
matches = secrets.compare_digest(supplied, configured)
|
||||
if not configured or not matches:
|
||||
|
||||
Reference in New Issue
Block a user