verae-access-authz/src/client.js

38 lines
1.5 KiB
JavaScript

/** Call verae.access.authz.check then the internal subject. Fail closed. */
import { SUBJECTS } from './subjects.js';
export async function authorizeThenRequest(nc, sc, { plane, subject, principal, payload, timeout = 2000 }) {
const kind = payload?.kind;
const checkMsg = await nc.request(
SUBJECTS.AUTHZ_CHECK,
sc.encode(JSON.stringify({ plane, subject, principal, kind, payload })),
{ timeout },
);
const decision = JSON.parse(sc.decode(checkMsg.data) || '{}');
if (!decision.allow) {
const err = new Error(decision.reason || 'denied');
err.decision = decision;
throw err;
}
const internal = decision.subject;
const body = { ...payload, plane, principal, traceId: payload?.traceId };
const m = await nc.request(internal, sc.encode(JSON.stringify(body)), { timeout });
return { decision, body: JSON.parse(sc.decode(m.data) || '{}') };
}
export async function authorizeThenPublish(nc, sc, { plane, subject, principal, payload, timeout = 2000 }) {
const kind = payload?.kind;
const checkMsg = await nc.request(
SUBJECTS.AUTHZ_CHECK,
sc.encode(JSON.stringify({ plane, subject, principal, kind, payload })),
{ timeout },
);
const decision = JSON.parse(sc.decode(checkMsg.data) || '{}');
if (!decision.allow) {
const err = new Error(decision.reason || 'denied');
err.decision = decision;
throw err;
}
nc.publish(decision.subject, sc.encode(JSON.stringify({ ...payload, plane, principal })));
return { decision };
}