@atlasauth/emulator-core 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adopt.d.ts +50 -0
- package/dist/adopt.js +57 -0
- package/dist/adopt.js.map +1 -0
- package/dist/coverage.d.ts +15 -0
- package/dist/coverage.js +31 -0
- package/dist/coverage.js.map +1 -0
- package/dist/crypto-util.d.ts +10 -0
- package/dist/crypto-util.js +76 -0
- package/dist/crypto-util.js.map +1 -0
- package/dist/custom-html.d.ts +57 -0
- package/dist/custom-html.js +491 -0
- package/dist/custom-html.js.map +1 -0
- package/dist/engine.d.ts +34 -3
- package/dist/engine.js +57 -8
- package/dist/engine.js.map +1 -1
- package/dist/error-catalog.js +16 -0
- package/dist/error-catalog.js.map +1 -1
- package/dist/event-gate.d.ts +3 -0
- package/dist/event-gate.js +430 -0
- package/dist/event-gate.js.map +1 -0
- package/dist/generic.js +14 -2
- package/dist/generic.js.map +1 -1
- package/dist/handlers/access-signals.d.ts +48 -0
- package/dist/handlers/access-signals.js +76 -0
- package/dist/handlers/access-signals.js.map +1 -0
- package/dist/handlers/approvals.d.ts +2 -0
- package/dist/handlers/approvals.js +418 -0
- package/dist/handlers/approvals.js.map +1 -0
- package/dist/handlers/authz-data.d.ts +2 -0
- package/dist/handlers/authz-data.js +627 -0
- package/dist/handlers/authz-data.js.map +1 -0
- package/dist/handlers/authz-layers.d.ts +229 -0
- package/dist/handlers/authz-layers.js +786 -0
- package/dist/handlers/authz-layers.js.map +1 -0
- package/dist/handlers/authz-state.d.ts +80 -0
- package/dist/handlers/authz-state.js +175 -0
- package/dist/handlers/authz-state.js.map +1 -0
- package/dist/handlers/authz.d.ts +2 -0
- package/dist/handlers/authz.js +410 -0
- package/dist/handlers/authz.js.map +1 -0
- package/dist/handlers/billing.d.ts +100 -0
- package/dist/handlers/billing.js +877 -0
- package/dist/handlers/billing.js.map +1 -0
- package/dist/handlers/cedar-ext.d.ts +35 -0
- package/dist/handlers/cedar-ext.js +174 -0
- package/dist/handlers/cedar-ext.js.map +1 -0
- package/dist/handlers/cedar.d.ts +146 -0
- package/dist/handlers/cedar.js +689 -0
- package/dist/handlers/cedar.js.map +1 -0
- package/dist/handlers/connections.d.ts +5 -0
- package/dist/handlers/connections.js +561 -0
- package/dist/handlers/connections.js.map +1 -0
- package/dist/handlers/control.js +6 -1
- package/dist/handlers/control.js.map +1 -1
- package/dist/handlers/device.d.ts +47 -0
- package/dist/handlers/device.js +665 -0
- package/dist/handlers/device.js.map +1 -0
- package/dist/handlers/emu3-misc.d.ts +38 -0
- package/dist/handlers/emu3-misc.js +1056 -0
- package/dist/handlers/emu3-misc.js.map +1 -0
- package/dist/handlers/emu4-actions-access.d.ts +46 -0
- package/dist/handlers/emu4-actions-access.js +107 -0
- package/dist/handlers/emu4-actions-access.js.map +1 -0
- package/dist/handlers/emu4-actions-catalog-extra.d.ts +3 -0
- package/dist/handlers/emu4-actions-catalog-extra.js +204 -0
- package/dist/handlers/emu4-actions-catalog-extra.js.map +1 -0
- package/dist/handlers/emu4-actions-catalog.d.ts +3 -0
- package/dist/handlers/emu4-actions-catalog.js +143 -0
- package/dist/handlers/emu4-actions-catalog.js.map +1 -0
- package/dist/handlers/emu4-actions-def.d.ts +50 -0
- package/dist/handlers/emu4-actions-def.js +250 -0
- package/dist/handlers/emu4-actions-def.js.map +1 -0
- package/dist/handlers/emu4-actions-sandbox.d.ts +36 -0
- package/dist/handlers/emu4-actions-sandbox.js +318 -0
- package/dist/handlers/emu4-actions-sandbox.js.map +1 -0
- package/dist/handlers/emu4-actions-typegen.d.ts +5 -0
- package/dist/handlers/emu4-actions-typegen.js +73 -0
- package/dist/handlers/emu4-actions-typegen.js.map +1 -0
- package/dist/handlers/emu4-actions.d.ts +2 -0
- package/dist/handlers/emu4-actions.js +506 -0
- package/dist/handlers/emu4-actions.js.map +1 -0
- package/dist/handlers/emu4-authz-trust.d.ts +40 -0
- package/dist/handlers/emu4-authz-trust.js +488 -0
- package/dist/handlers/emu4-authz-trust.js.map +1 -0
- package/dist/handlers/emu4-authz.d.ts +2 -0
- package/dist/handlers/emu4-authz.js +752 -0
- package/dist/handlers/emu4-authz.js.map +1 -0
- package/dist/handlers/emu4-billing-core.d.ts +23 -0
- package/dist/handlers/emu4-billing-core.js +22 -0
- package/dist/handlers/emu4-billing-core.js.map +1 -0
- package/dist/handlers/emu4-billing-x.d.ts +2 -0
- package/dist/handlers/emu4-billing-x.js +489 -0
- package/dist/handlers/emu4-billing-x.js.map +1 -0
- package/dist/handlers/emu4-billing.d.ts +14 -0
- package/dist/handlers/emu4-billing.js +846 -0
- package/dist/handlers/emu4-billing.js.map +1 -0
- package/dist/handlers/emu4-clones.d.ts +2 -0
- package/dist/handlers/emu4-clones.js +322 -0
- package/dist/handlers/emu4-clones.js.map +1 -0
- package/dist/handlers/emu4-compliance.d.ts +8 -0
- package/dist/handlers/emu4-compliance.js +39 -0
- package/dist/handlers/emu4-compliance.js.map +1 -0
- package/dist/handlers/emu4-config.d.ts +14 -0
- package/dist/handlers/emu4-config.js +148 -0
- package/dist/handlers/emu4-config.js.map +1 -0
- package/dist/handlers/emu4-cookies.d.ts +8 -0
- package/dist/handlers/emu4-cookies.js +248 -0
- package/dist/handlers/emu4-cookies.js.map +1 -0
- package/dist/handlers/emu4-erasure.d.ts +2 -0
- package/dist/handlers/emu4-erasure.js +587 -0
- package/dist/handlers/emu4-erasure.js.map +1 -0
- package/dist/handlers/emu4-federation.d.ts +8 -0
- package/dist/handlers/emu4-federation.js +18 -0
- package/dist/handlers/emu4-federation.js.map +1 -0
- package/dist/handlers/emu4-journey-math.d.ts +42 -0
- package/dist/handlers/emu4-journey-math.js +99 -0
- package/dist/handlers/emu4-journey-math.js.map +1 -0
- package/dist/handlers/emu4-messaging.d.ts +21 -0
- package/dist/handlers/emu4-messaging.js +595 -0
- package/dist/handlers/emu4-messaging.js.map +1 -0
- package/dist/handlers/emu4-minors.d.ts +7 -0
- package/dist/handlers/emu4-minors.js +408 -0
- package/dist/handlers/emu4-minors.js.map +1 -0
- package/dist/handlers/emu4-oauth-audit.d.ts +5 -0
- package/dist/handlers/emu4-oauth-audit.js +17 -0
- package/dist/handlers/emu4-oauth-audit.js.map +1 -0
- package/dist/handlers/emu4-oauth-auth.d.ts +83 -0
- package/dist/handlers/emu4-oauth-auth.js +363 -0
- package/dist/handlers/emu4-oauth-auth.js.map +1 -0
- package/dist/handlers/emu4-oauth-delivery.d.ts +68 -0
- package/dist/handlers/emu4-oauth-delivery.js +207 -0
- package/dist/handlers/emu4-oauth-delivery.js.map +1 -0
- package/dist/handlers/emu4-oauth-keys.d.ts +11 -0
- package/dist/handlers/emu4-oauth-keys.js +268 -0
- package/dist/handlers/emu4-oauth-keys.js.map +1 -0
- package/dist/handlers/emu4-oauth-pub.d.ts +36 -0
- package/dist/handlers/emu4-oauth-pub.js +420 -0
- package/dist/handlers/emu4-oauth-pub.js.map +1 -0
- package/dist/handlers/emu4-oauth.d.ts +10 -0
- package/dist/handlers/emu4-oauth.js +23 -0
- package/dist/handlers/emu4-oauth.js.map +1 -0
- package/dist/handlers/emu4-policies.d.ts +2 -0
- package/dist/handlers/emu4-policies.js +408 -0
- package/dist/handlers/emu4-policies.js.map +1 -0
- package/dist/handlers/emu4-region.d.ts +2 -0
- package/dist/handlers/emu4-region.js +189 -0
- package/dist/handlers/emu4-region.js.map +1 -0
- package/dist/handlers/emu4-saml.d.ts +12 -0
- package/dist/handlers/emu4-saml.js +532 -0
- package/dist/handlers/emu4-saml.js.map +1 -0
- package/dist/handlers/emu4-shared.d.ts +44 -0
- package/dist/handlers/emu4-shared.js +90 -0
- package/dist/handlers/emu4-shared.js.map +1 -0
- package/dist/handlers/emu4-snapshots.d.ts +38 -0
- package/dist/handlers/emu4-snapshots.js +231 -0
- package/dist/handlers/emu4-snapshots.js.map +1 -0
- package/dist/handlers/emu4-sns.d.ts +9 -0
- package/dist/handlers/emu4-sns.js +21 -0
- package/dist/handlers/emu4-sns.js.map +1 -0
- package/dist/handlers/emu4-trust-binding.d.ts +27 -0
- package/dist/handlers/emu4-trust-binding.js +344 -0
- package/dist/handlers/emu4-trust-binding.js.map +1 -0
- package/dist/handlers/emu4-trust.d.ts +35 -0
- package/dist/handlers/emu4-trust.js +543 -0
- package/dist/handlers/emu4-trust.js.map +1 -0
- package/dist/handlers/federation.d.ts +2 -0
- package/dist/handlers/federation.js +481 -0
- package/dist/handlers/federation.js.map +1 -0
- package/dist/handlers/fga-engine.d.ts +78 -0
- package/dist/handlers/fga-engine.js +663 -0
- package/dist/handlers/fga-engine.js.map +1 -0
- package/dist/handlers/governance.d.ts +2 -0
- package/dist/handlers/governance.js +460 -0
- package/dist/handlers/governance.js.map +1 -0
- package/dist/handlers/hooks.js +17 -1
- package/dist/handlers/hooks.js.map +1 -1
- package/dist/handlers/index.d.ts +5 -1
- package/dist/handlers/index.js +45 -3
- package/dist/handlers/index.js.map +1 -1
- package/dist/handlers/keys.js +6 -1
- package/dist/handlers/keys.js.map +1 -1
- package/dist/handlers/machines.js +61 -8
- package/dist/handlers/machines.js.map +1 -1
- package/dist/handlers/messaging.d.ts +6 -0
- package/dist/handlers/messaging.js +893 -0
- package/dist/handlers/messaging.js.map +1 -0
- package/dist/handlers/oauth-adv.d.ts +191 -0
- package/dist/handlers/oauth-adv.js +1305 -0
- package/dist/handlers/oauth-adv.js.map +1 -0
- package/dist/handlers/oauth-flows.d.ts +52 -0
- package/dist/handlers/oauth-flows.js +480 -0
- package/dist/handlers/oauth-flows.js.map +1 -0
- package/dist/handlers/oauth.d.ts +96 -0
- package/dist/handlers/oauth.js +793 -0
- package/dist/handlers/oauth.js.map +1 -0
- package/dist/handlers/orgs.js +6 -0
- package/dist/handlers/orgs.js.map +1 -1
- package/dist/handlers/passkeys.d.ts +3 -0
- package/dist/handlers/passkeys.js +293 -0
- package/dist/handlers/passkeys.js.map +1 -0
- package/dist/handlers/platform.d.ts +20 -0
- package/dist/handlers/platform.js +472 -0
- package/dist/handlers/platform.js.map +1 -0
- package/dist/handlers/round2.d.ts +8 -0
- package/dist/handlers/round2.js +372 -0
- package/dist/handlers/round2.js.map +1 -0
- package/dist/handlers/scim.d.ts +4 -0
- package/dist/handlers/scim.js +595 -0
- package/dist/handlers/scim.js.map +1 -0
- package/dist/handlers/sessions.d.ts +9 -3
- package/dist/handlers/sessions.js +76 -38
- package/dist/handlers/sessions.js.map +1 -1
- package/dist/handlers/support.d.ts +20 -0
- package/dist/handlers/support.js +62 -0
- package/dist/handlers/support.js.map +1 -0
- package/dist/handlers/users.js +7 -0
- package/dist/handlers/users.js.map +1 -1
- package/dist/handlers/workflows.d.ts +2 -0
- package/dist/handlers/workflows.js +428 -0
- package/dist/handlers/workflows.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +23 -1
- package/dist/index.js.map +1 -1
- package/dist/jwe.d.ts +18 -0
- package/dist/jwe.js +101 -0
- package/dist/jwe.js.map +1 -0
- package/dist/jws.d.ts +41 -0
- package/dist/jws.js +135 -0
- package/dist/jws.js.map +1 -0
- package/dist/messages.d.ts +7 -0
- package/dist/messages.js +8 -4
- package/dist/messages.js.map +1 -1
- package/dist/messaging-callbacks.d.ts +100 -0
- package/dist/messaging-callbacks.js +767 -0
- package/dist/messaging-callbacks.js.map +1 -0
- package/dist/openapi.js +41 -1
- package/dist/openapi.js.map +1 -1
- package/dist/parity-bin.js +3 -1
- package/dist/parity-bin.js.map +1 -1
- package/dist/parity-emu3-authz.d.ts +3 -0
- package/dist/parity-emu3-authz.js +61 -0
- package/dist/parity-emu3-authz.js.map +1 -0
- package/dist/parity-emu3-billing.d.ts +3 -0
- package/dist/parity-emu3-billing.js +25 -0
- package/dist/parity-emu3-billing.js.map +1 -0
- package/dist/parity-emu3-messaging.d.ts +3 -0
- package/dist/parity-emu3-messaging.js +27 -0
- package/dist/parity-emu3-messaging.js.map +1 -0
- package/dist/parity-emu3-misc.d.ts +2 -0
- package/dist/parity-emu3-misc.js +63 -0
- package/dist/parity-emu3-misc.js.map +1 -0
- package/dist/parity-emu3-oauth.d.ts +2 -0
- package/dist/parity-emu3-oauth.js +39 -0
- package/dist/parity-emu3-oauth.js.map +1 -0
- package/dist/parity-emu4-actions.d.ts +2 -0
- package/dist/parity-emu4-actions.js +38 -0
- package/dist/parity-emu4-actions.js.map +1 -0
- package/dist/parity-emu4-authz.d.ts +3 -0
- package/dist/parity-emu4-authz.js +68 -0
- package/dist/parity-emu4-authz.js.map +1 -0
- package/dist/parity-emu4-billing.d.ts +6 -0
- package/dist/parity-emu4-billing.js +44 -0
- package/dist/parity-emu4-billing.js.map +1 -0
- package/dist/parity-emu4-compliance.d.ts +2 -0
- package/dist/parity-emu4-compliance.js +92 -0
- package/dist/parity-emu4-compliance.js.map +1 -0
- package/dist/parity-emu4-federation.d.ts +2 -0
- package/dist/parity-emu4-federation.js +33 -0
- package/dist/parity-emu4-federation.js.map +1 -0
- package/dist/parity-emu4-messaging.d.ts +3 -0
- package/dist/parity-emu4-messaging.js +42 -0
- package/dist/parity-emu4-messaging.js.map +1 -0
- package/dist/parity-emu4-oauth.d.ts +2 -0
- package/dist/parity-emu4-oauth.js +55 -0
- package/dist/parity-emu4-oauth.js.map +1 -0
- package/dist/parity-emu4-trust.d.ts +2 -0
- package/dist/parity-emu4-trust.js +41 -0
- package/dist/parity-emu4-trust.js.map +1 -0
- package/dist/parity-routes.d.ts +14 -0
- package/dist/parity-routes.js +439 -0
- package/dist/parity-routes.js.map +1 -0
- package/dist/parity.d.ts +10 -3
- package/dist/parity.js +14 -5
- package/dist/parity.js.map +1 -1
- package/dist/sns-cert.d.ts +9 -0
- package/dist/sns-cert.js +101 -0
- package/dist/sns-cert.js.map +1 -0
- package/dist/tokens.d.ts +85 -3
- package/dist/tokens.js +196 -24
- package/dist/tokens.js.map +1 -1
- package/dist/webauthn-virtual.d.ts +70 -0
- package/dist/webauthn-virtual.js +186 -0
- package/dist/webauthn-virtual.js.map +1 -0
- package/dist/webhook-ext.d.ts +16 -0
- package/dist/webhook-ext.js +218 -0
- package/dist/webhook-ext.js.map +1 -0
- package/dist/webhooks.d.ts +3 -0
- package/dist/webhooks.js +37 -3
- package/dist/webhooks.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sessionBindingClaims = exports.trustConfig = void 0;
|
|
4
|
+
exports.enforceSessionBinding = enforceSessionBinding;
|
|
5
|
+
exports.dbscRegistrationHeaders = dbscRegistrationHeaders;
|
|
6
|
+
exports.emu4TrustBindingHandlers = emu4TrustBindingHandlers;
|
|
7
|
+
const crypto_util_1 = require("../crypto-util");
|
|
8
|
+
const errors_1 = require("../errors");
|
|
9
|
+
const jws_1 = require("../jws");
|
|
10
|
+
const store_1 = require("../store");
|
|
11
|
+
const oauth_flows_1 = require("./oauth-flows");
|
|
12
|
+
const sessions_1 = require("./sessions");
|
|
13
|
+
const support_1 = require("./support");
|
|
14
|
+
const emu4_trust_1 = require("./emu4-trust");
|
|
15
|
+
const state = (0, support_1.engineState)((_e) => ({
|
|
16
|
+
config: { session_binding: { mode: 'off', require_attestation: false }, device_bound_sessions: false, app_attestation: false },
|
|
17
|
+
bindings: new Map(),
|
|
18
|
+
devices: new Map(),
|
|
19
|
+
/** Random per engine, so a bound cookie from another engine never verifies. */
|
|
20
|
+
hmac: crypto.subtle.importKey('raw', crypto.getRandomValues(new Uint8Array(32)), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']),
|
|
21
|
+
}));
|
|
22
|
+
const trustConfig = (e) => state(e).config;
|
|
23
|
+
exports.trustConfig = trustConfig;
|
|
24
|
+
const bindingMode = (e) => state(e).config.session_binding.mode;
|
|
25
|
+
const refused = (message, reason) => new errors_1.EmulatorError('UNAUTHENTICATED', message, undefined, { meta: { reason } });
|
|
26
|
+
const readCookie = (c, name) => {
|
|
27
|
+
for (const part of (c.request.headers.get('cookie') ?? '').split(';')) {
|
|
28
|
+
const [k, ...rest] = part.trim().split('=');
|
|
29
|
+
if (k === name)
|
|
30
|
+
return rest.join('=');
|
|
31
|
+
}
|
|
32
|
+
return undefined;
|
|
33
|
+
};
|
|
34
|
+
const refreshOf = (c) => {
|
|
35
|
+
const cookie = readCookie(c, '__atlas_rt');
|
|
36
|
+
return cookie ? decodeURIComponent(cookie) : (c.request.headers.get('x-refresh-token') ?? undefined);
|
|
37
|
+
};
|
|
38
|
+
/** `cnf.jkt` for the session JWT of a bound session; nothing for an unbound one. */
|
|
39
|
+
const sessionBindingClaims = (e, sessionId) => {
|
|
40
|
+
const b = state(e).bindings.get(sessionId);
|
|
41
|
+
return b ? { cnf: { jkt: b.jkt } } : {};
|
|
42
|
+
};
|
|
43
|
+
exports.sessionBindingClaims = sessionBindingClaims;
|
|
44
|
+
/** A proof from the request: `null` when there is no DPoP header, a refusal (401 `dpop_proof_invalid`) when it does not verify or was used before. */
|
|
45
|
+
async function proofOf(c) {
|
|
46
|
+
const raw = c.request.headers.get('dpop');
|
|
47
|
+
if (raw === null)
|
|
48
|
+
return null;
|
|
49
|
+
try {
|
|
50
|
+
const r = await (0, jws_1.verifyDpopProof)({ proof: raw, htm: c.request.method, htu: c.request.url, nowMs: c.engine.clock.now() });
|
|
51
|
+
if (!(0, oauth_flows_1.claimDpopJti)(c.engine, r.jkt, r.jti, (jws_1.DPOP_IAT_WINDOW_S + 5) * 1000))
|
|
52
|
+
throw new Error('That DPoP proof was already used.');
|
|
53
|
+
return { jkt: r.jkt, alg: String((0, jws_1.decodeJwt)(raw)?.header.alg ?? '') };
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
throw refused(err instanceof Error && err.message === 'That DPoP proof was already used.' ? err.message : 'The DPoP proof is not valid.', 'dpop_proof_invalid');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const hmac = async (e, msg) => (0, crypto_util_1.bytesToB64url)(new Uint8Array(await crypto.subtle.sign('HMAC', await state(e).hmac, new TextEncoder().encode(msg))));
|
|
60
|
+
/** `<session id>.<exp seconds>.<mac>`: stateless, bound to the session, the kind and the expiry. */
|
|
61
|
+
const signBound = async (e, kind, sid, exp) => `${sid}.${exp}.${await hmac(e, `${kind}.${sid}.${exp}`)}`;
|
|
62
|
+
async function verifyBound(e, kind, token) {
|
|
63
|
+
const parts = (token ?? '').split('.');
|
|
64
|
+
if (parts.length < 3)
|
|
65
|
+
return null;
|
|
66
|
+
const sig = parts.pop();
|
|
67
|
+
const exp = Number(parts.pop());
|
|
68
|
+
const sid = parts.join('.');
|
|
69
|
+
if (!sid || !Number.isFinite(exp) || exp * 1000 <= e.clock.now())
|
|
70
|
+
return null;
|
|
71
|
+
// shortcut: plain string comparison, not constant time (an in-process test double has no timing channel to protect).
|
|
72
|
+
return (await hmac(e, `${kind}.${sid}.${exp}`)) === sig ? sid : null;
|
|
73
|
+
}
|
|
74
|
+
const BOUND_COOKIE = '__atlas_dbsc';
|
|
75
|
+
const BOUND_TTL_S = 600;
|
|
76
|
+
const CHALLENGE_TTL_S = 300;
|
|
77
|
+
async function boundCookie(e, sid) {
|
|
78
|
+
const attributes = 'Secure; HttpOnly; SameSite=Lax; Path=/';
|
|
79
|
+
const value = await signBound(e, 'cookie', sid, Math.floor(e.clock.now() / 1000) + BOUND_TTL_S);
|
|
80
|
+
return { header: `${BOUND_COOKIE}=${value}; ${attributes}; Max-Age=${BOUND_TTL_S}`, attributes };
|
|
81
|
+
}
|
|
82
|
+
const provenDevice = async (c) => {
|
|
83
|
+
const sid = await verifyBound(c.engine, 'cookie', readCookie(c, BOUND_COOKIE));
|
|
84
|
+
return sid ? state(c.engine).devices.get(sid)?.device_id : undefined;
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* The gate on the refresh route: a session bound to a key refreshes only with a fresh single-use proof from that key
|
|
88
|
+
* (401 `dpop_binding_required`); with mode `required` an unbound session cannot refresh (401 `session_binding_required`);
|
|
89
|
+
* a session bound to a device needs that device's bound cookie (401 `device_binding_required`).
|
|
90
|
+
*/
|
|
91
|
+
async function enforceSessionBinding(c, sessionId) {
|
|
92
|
+
const e = c.engine;
|
|
93
|
+
const s = e.db.sessions.get(sessionId);
|
|
94
|
+
if (!s || s.status !== 'active')
|
|
95
|
+
return;
|
|
96
|
+
const mode = bindingMode(e);
|
|
97
|
+
if (mode !== 'off') {
|
|
98
|
+
const binding = state(e).bindings.get(sessionId);
|
|
99
|
+
if (!binding) {
|
|
100
|
+
if (mode === 'required')
|
|
101
|
+
throw refused('This instance requires sessions to be bound to a key. Bind the session (POST /v1/client/session_binding) and retry.', 'session_binding_required');
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
const proof = await proofOf(c);
|
|
105
|
+
if (!proof || proof.jkt !== binding.jkt)
|
|
106
|
+
throw refused('This session is bound to a key. Send a DPoP proof signed by that key.', 'dpop_binding_required');
|
|
107
|
+
binding.last_proof_at = e.clock.now();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (state(e).config.device_bound_sessions) {
|
|
111
|
+
const device = state(e).devices.get(sessionId);
|
|
112
|
+
if (device && (await provenDevice(c)) !== device.device_id)
|
|
113
|
+
throw refused('This session is bound to a device. Renew the device credential and try again.', 'device_binding_required');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/** `Secure-Session-Registration` for a session handed out with a refresh cookie that is not bound to a device yet. */
|
|
117
|
+
async function dbscRegistrationHeaders(e, sessionId) {
|
|
118
|
+
if (!state(e).config.device_bound_sessions || state(e).devices.has(sessionId))
|
|
119
|
+
return {};
|
|
120
|
+
const challenge = await signBound(e, 'reg', sessionId, Math.floor(e.clock.now() / 1000) + CHALLENGE_TTL_S);
|
|
121
|
+
return { 'secure-session-registration': `(ES256 RS256);path="/v1/client/dbsc/start";challenge="${challenge}"` };
|
|
122
|
+
}
|
|
123
|
+
/** Native app attestation evidence: base64url JSON `{ p: 'ios' | 'ios_dc' | 'android' }`; anything else is refused (the emulator does not run Apple or Google verifiers). */
|
|
124
|
+
function attestationProvider(c) {
|
|
125
|
+
const raw = c.request.headers.get('atlas-attestation');
|
|
126
|
+
const bad = new errors_1.EmulatorError('APP_ATTESTATION_REQUIRED', raw ? 'The app attestation evidence is not valid.' : 'This request needs app attestation evidence.');
|
|
127
|
+
if (!raw)
|
|
128
|
+
throw bad;
|
|
129
|
+
try {
|
|
130
|
+
const p = JSON.parse(new TextDecoder().decode(Uint8Array.from(atob(raw.replace(/-/g, '+').replace(/_/g, '/')), (x) => x.charCodeAt(0)))).p;
|
|
131
|
+
if (p === 'ios' || p === 'ios_dc' || p === 'android')
|
|
132
|
+
return p;
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
/* falls through */
|
|
136
|
+
}
|
|
137
|
+
throw bad;
|
|
138
|
+
}
|
|
139
|
+
const bindingView = (b) => ({ object: 'session_binding', session_id: b.session_id, jkt: b.jkt, attested: b.attested, bound_at: b.bound_at });
|
|
140
|
+
function emu4TrustBindingHandlers() {
|
|
141
|
+
return [
|
|
142
|
+
// ── the trust switches (the real instance keeps these in its auth config) ──
|
|
143
|
+
{ method: 'GET', pattern: '/__emulator/trust/config', public: true, handler: (c) => ({ body: { object: 'trust_config', ...state(c.engine).config } }) },
|
|
144
|
+
{
|
|
145
|
+
method: 'PUT',
|
|
146
|
+
pattern: '/__emulator/trust/config',
|
|
147
|
+
public: true,
|
|
148
|
+
handler: (c) => {
|
|
149
|
+
const cfg = state(c.engine).config;
|
|
150
|
+
const b = c.body;
|
|
151
|
+
const sb = b.session_binding;
|
|
152
|
+
if (sb !== undefined) {
|
|
153
|
+
if (sb === null || typeof sb !== 'object' || Array.isArray(sb))
|
|
154
|
+
throw new errors_1.EmulatorError('VALIDATION_FAILED', 'session_binding must be an object.', 'session_binding');
|
|
155
|
+
if (sb.mode !== undefined && !['off', 'optional', 'required'].includes(sb.mode))
|
|
156
|
+
throw new errors_1.EmulatorError('VALIDATION_FAILED', 'session_binding.mode must be one of off, optional, required.', 'session_binding.mode');
|
|
157
|
+
if (sb.require_attestation !== undefined && typeof sb.require_attestation !== 'boolean')
|
|
158
|
+
throw new errors_1.EmulatorError('VALIDATION_FAILED', 'session_binding.require_attestation must be true or false.', 'session_binding.require_attestation');
|
|
159
|
+
}
|
|
160
|
+
for (const f of ['device_bound_sessions', 'app_attestation'])
|
|
161
|
+
if (b[f] !== undefined && typeof b[f] !== 'boolean')
|
|
162
|
+
throw new errors_1.EmulatorError('VALIDATION_FAILED', `${f} must be true or false.`, f);
|
|
163
|
+
if (sb)
|
|
164
|
+
cfg.session_binding = { ...cfg.session_binding, ...(sb.mode ? { mode: sb.mode } : {}), ...(sb.require_attestation !== undefined ? { require_attestation: sb.require_attestation } : {}) };
|
|
165
|
+
if (b.device_bound_sessions !== undefined)
|
|
166
|
+
cfg.device_bound_sessions = b.device_bound_sessions;
|
|
167
|
+
if (b.app_attestation !== undefined)
|
|
168
|
+
cfg.app_attestation = b.app_attestation;
|
|
169
|
+
return { body: { object: 'trust_config', ...cfg } };
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
// ── bind a session to a DPoP key (Frontend API) ──
|
|
173
|
+
{
|
|
174
|
+
method: 'POST',
|
|
175
|
+
pattern: '/v1/client/session_binding',
|
|
176
|
+
public: true,
|
|
177
|
+
handler: async (c) => {
|
|
178
|
+
const e = c.engine;
|
|
179
|
+
const policy = state(e).config.session_binding;
|
|
180
|
+
if (policy.mode === 'off')
|
|
181
|
+
throw new errors_1.EmulatorError('NOT_FOUND', 'Session binding is not enabled.');
|
|
182
|
+
const rt = refreshOf(c);
|
|
183
|
+
const sid = rt ? (0, sessions_1.sessionIdOfRefresh)(e, rt, true) : undefined;
|
|
184
|
+
const session = sid ? e.db.sessions.get(sid) : undefined;
|
|
185
|
+
if (!session || session.status !== 'active')
|
|
186
|
+
throw new errors_1.EmulatorError('UNAUTHENTICATED', 'No active session to bind.');
|
|
187
|
+
const proof = await proofOf(c);
|
|
188
|
+
if (!proof)
|
|
189
|
+
throw new errors_1.EmulatorError('VALIDATION_FAILED', 'Send a DPoP proof signed by the key to bind the session to.', 'dpop');
|
|
190
|
+
const sent = c.request.headers.get('atlas-attestation') !== null;
|
|
191
|
+
let provider = null;
|
|
192
|
+
if (policy.require_attestation || sent) {
|
|
193
|
+
if (!state(e).config.app_attestation)
|
|
194
|
+
throw Object.assign(new errors_1.EmulatorError('STRATEGY_DISABLED', 'App attestation is not enabled for this instance.'), { status: 422 });
|
|
195
|
+
provider = attestationProvider(c);
|
|
196
|
+
}
|
|
197
|
+
const existing = state(e).bindings.get(session.id);
|
|
198
|
+
if (existing) {
|
|
199
|
+
if (existing.jkt !== proof.jkt)
|
|
200
|
+
throw new errors_1.EmulatorError('CONFLICT', 'This session is already bound to a different key.', undefined, { meta: { reason: 'already_bound' } });
|
|
201
|
+
existing.last_proof_at = e.clock.now();
|
|
202
|
+
return { status: 200, body: bindingView(existing) };
|
|
203
|
+
}
|
|
204
|
+
const b = { session_id: session.id, jkt: proof.jkt, alg: proof.alg, attested: provider !== null, attestation_provider: provider, bound_at: e.clock.now(), last_proof_at: null };
|
|
205
|
+
state(e).bindings.set(session.id, b);
|
|
206
|
+
(0, emu4_trust_1.recordAudit)(e, { actor_type: 'user', actor_id: session.user_id, action: 'session.bound', target_type: 'session', target_id: session.id, metadata: { jkt: b.jkt, alg: b.alg, attested: b.attested } });
|
|
207
|
+
e.webhooks.emit('session.bound', { object: 'session_binding', session_id: session.id, user_id: session.user_id, jkt: b.jkt, attested: b.attested });
|
|
208
|
+
return { status: 201, body: bindingView(b) };
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
// ── the binding of one session, from the backend key ──
|
|
212
|
+
{
|
|
213
|
+
method: 'GET',
|
|
214
|
+
pattern: '/v1/sessions/:id/binding',
|
|
215
|
+
scope: 'sessions:read',
|
|
216
|
+
handler: (c) => {
|
|
217
|
+
const e = c.engine;
|
|
218
|
+
if (!e.db.sessions.get(c.params.id))
|
|
219
|
+
throw (0, errors_1.notFound)('Session');
|
|
220
|
+
const b = state(e).bindings.get(c.params.id);
|
|
221
|
+
if (!b)
|
|
222
|
+
return { body: { object: 'session_binding', session_id: c.params.id, bound: false, jkt: null, alg: null, attested: false, attestation_provider: null, bound_at: null, last_proof_at: null } };
|
|
223
|
+
// The key itself is never returned, only its thumbprint.
|
|
224
|
+
return { body: { object: 'session_binding', session_id: b.session_id, bound: true, jkt: b.jkt, alg: b.alg, attested: b.attested, attestation_provider: b.attestation_provider, bound_at: b.bound_at, last_proof_at: b.last_proof_at } };
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
method: 'DELETE',
|
|
229
|
+
pattern: '/v1/sessions/:id/binding',
|
|
230
|
+
scope: 'sessions:write',
|
|
231
|
+
handler: (c) => {
|
|
232
|
+
const e = c.engine;
|
|
233
|
+
if (!e.db.sessions.get(c.params.id))
|
|
234
|
+
throw (0, errors_1.notFound)('Session');
|
|
235
|
+
if (!state(e).bindings.delete(c.params.id))
|
|
236
|
+
throw new errors_1.EmulatorError('NOT_FOUND', 'This session is not bound.');
|
|
237
|
+
(0, emu4_trust_1.recordAudit)(e, { actor_type: 'api_key', actor_id: null, action: 'session.binding_removed', target_type: 'session', target_id: c.params.id, metadata: {} });
|
|
238
|
+
return { body: { object: 'session_binding', session_id: c.params.id, bound: false, deleted: true } };
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
// ── device-bound sessions (the browser DBSC protocol) ──
|
|
242
|
+
{
|
|
243
|
+
// The registration challenge a browser would read from `Secure-Session-Registration`: a test helper for clients that do not parse the header.
|
|
244
|
+
method: 'POST',
|
|
245
|
+
pattern: '/__emulator/dbsc/registration',
|
|
246
|
+
public: true,
|
|
247
|
+
handler: async (c) => {
|
|
248
|
+
const sid = String(c.body.session_id ?? '');
|
|
249
|
+
if (!c.engine.db.sessions.get(sid))
|
|
250
|
+
throw (0, errors_1.notFound)('Session');
|
|
251
|
+
const challenge = await signBound(c.engine, 'reg', sid, Math.floor(c.engine.clock.now() / 1000) + CHALLENGE_TTL_S);
|
|
252
|
+
return { body: { object: 'dbsc_registration', session_id: sid, challenge, path: '/v1/client/dbsc/start' } };
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
method: 'POST',
|
|
257
|
+
pattern: '/v1/client/dbsc/start',
|
|
258
|
+
public: true,
|
|
259
|
+
handler: async (c) => {
|
|
260
|
+
const e = c.engine;
|
|
261
|
+
if (!state(e).config.device_bound_sessions)
|
|
262
|
+
throw new errors_1.EmulatorError('NOT_FOUND', 'Device bound sessions are not enabled.');
|
|
263
|
+
const fail = (m) => new errors_1.EmulatorError('UNAUTHENTICATED', m);
|
|
264
|
+
const proof = await dbscProof(c, c.request.headers.get('secure-session-response'), '/dbsc/start');
|
|
265
|
+
const sid = proof && (await verifyBound(e, 'reg', proof.jti));
|
|
266
|
+
if (!proof || !sid)
|
|
267
|
+
throw fail('The registration proof is not valid.');
|
|
268
|
+
const rt = readCookie(c, '__atlas_rt');
|
|
269
|
+
const rtSid = rt ? (0, sessions_1.sessionIdOfRefresh)(e, decodeURIComponent(rt), true) : undefined;
|
|
270
|
+
const session = rtSid ? e.db.sessions.get(rtSid) : undefined;
|
|
271
|
+
if (!session || session.id !== sid || session.status !== 'active')
|
|
272
|
+
throw fail('No active session for this registration.');
|
|
273
|
+
// A browser that already proves a device (another account it holds) registers into that device.
|
|
274
|
+
const deviceId = (await provenDevice(c)) ?? crypto.randomUUID();
|
|
275
|
+
if (state(e).devices.has(sid))
|
|
276
|
+
throw fail('This session is already bound to a device.');
|
|
277
|
+
state(e).devices.set(sid, { session_id: sid, device_id: deviceId, jwk: proof.jwk, alg: proof.alg, challenge: null, challenge_expires_at: null });
|
|
278
|
+
const cookie = await boundCookie(e, sid);
|
|
279
|
+
return {
|
|
280
|
+
status: 200,
|
|
281
|
+
headers: { 'set-cookie': cookie.header },
|
|
282
|
+
body: {
|
|
283
|
+
session_identifier: sid,
|
|
284
|
+
refresh_url: '/v1/client/dbsc/refresh',
|
|
285
|
+
scope: { origin: new URL(c.request.url).origin, include_site: false, scope_specification: [] },
|
|
286
|
+
credentials: [{ type: 'cookie', name: BOUND_COOKIE, attributes: cookie.attributes }],
|
|
287
|
+
},
|
|
288
|
+
};
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
method: 'POST',
|
|
293
|
+
pattern: '/v1/client/dbsc/refresh',
|
|
294
|
+
public: true,
|
|
295
|
+
handler: async (c) => {
|
|
296
|
+
const e = c.engine;
|
|
297
|
+
if (!state(e).config.device_bound_sessions)
|
|
298
|
+
throw new errors_1.EmulatorError('NOT_FOUND', 'Device bound sessions are not enabled.');
|
|
299
|
+
const fail = (m) => new errors_1.EmulatorError('UNAUTHENTICATED', m);
|
|
300
|
+
const sid = c.request.headers.get('sec-secure-session-id');
|
|
301
|
+
const binding = sid ? state(e).devices.get(sid) : undefined;
|
|
302
|
+
if (!sid || !binding)
|
|
303
|
+
throw fail('Unknown device bound session.');
|
|
304
|
+
const session = e.db.sessions.get(sid);
|
|
305
|
+
if (!session || session.status !== 'active' || session.expires_at <= e.clock.now())
|
|
306
|
+
throw fail('That session is no longer active.');
|
|
307
|
+
const jwt = c.request.headers.get('secure-session-response');
|
|
308
|
+
if (!jwt) {
|
|
309
|
+
binding.challenge = (0, store_1.randomToken)(24);
|
|
310
|
+
binding.challenge_expires_at = e.clock.now() + CHALLENGE_TTL_S * 1000;
|
|
311
|
+
return { status: 403, headers: { 'secure-session-challenge': `"${binding.challenge}";id="${sid}"` } };
|
|
312
|
+
}
|
|
313
|
+
const proof = await dbscProof(c, jwt, '/dbsc/refresh', binding.jwk);
|
|
314
|
+
if (!proof || !binding.challenge || proof.jti !== binding.challenge || !binding.challenge_expires_at || binding.challenge_expires_at <= e.clock.now())
|
|
315
|
+
throw fail('The refresh proof is not valid.');
|
|
316
|
+
// Each challenge works once.
|
|
317
|
+
binding.challenge = null;
|
|
318
|
+
binding.challenge_expires_at = null;
|
|
319
|
+
return { status: 200, headers: { 'set-cookie': (await boundCookie(e, sid)).header }, body: { session_identifier: sid } };
|
|
320
|
+
},
|
|
321
|
+
},
|
|
322
|
+
];
|
|
323
|
+
}
|
|
324
|
+
/** Verify a `dbsc+jwt` proof: type, algorithm (ES256 or RS256), signature (the payload `key` at registration, the stored key at refresh), age of at most 5 minutes, audience suffix and a jti. */
|
|
325
|
+
async function dbscProof(c, jwt, audSuffix, jwk) {
|
|
326
|
+
const d = jwt ? (0, jws_1.decodeJwt)(jwt) : null;
|
|
327
|
+
if (!d || d.header.typ !== 'dbsc+jwt' || !['ES256', 'RS256'].includes(d.header.alg))
|
|
328
|
+
return null;
|
|
329
|
+
const key = jwk ?? d.payload.key;
|
|
330
|
+
if (!key || typeof key !== 'object' || 'd' in key || !(await (0, jws_1.verifyJws)(d, key)))
|
|
331
|
+
return null;
|
|
332
|
+
const now = c.engine.clock.now() / 1000;
|
|
333
|
+
if (typeof d.payload.iat !== 'number' || now - d.payload.iat > 300)
|
|
334
|
+
return null;
|
|
335
|
+
if (typeof d.payload.exp === 'number' && d.payload.exp <= now)
|
|
336
|
+
return null;
|
|
337
|
+
const aud = Array.isArray(d.payload.aud) ? d.payload.aud[0] : d.payload.aud;
|
|
338
|
+
if (typeof aud !== 'string' || !aud.split('?')[0].endsWith(audSuffix))
|
|
339
|
+
return null;
|
|
340
|
+
if (typeof d.payload.jti !== 'string' || !d.payload.jti)
|
|
341
|
+
return null;
|
|
342
|
+
return { jwk: key, alg: d.header.alg, jti: d.payload.jti };
|
|
343
|
+
}
|
|
344
|
+
//# sourceMappingURL=emu4-trust-binding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emu4-trust-binding.js","sourceRoot":"","sources":["../../src/handlers/emu4-trust-binding.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type ChainedAuditRow } from '@atlasauth/backend';
|
|
2
|
+
import type { Engine, KeyInfo, RouteDef } from '../engine';
|
|
3
|
+
import type { Obj } from '../openapi';
|
|
4
|
+
export interface AuditInput {
|
|
5
|
+
actor_type: string;
|
|
6
|
+
actor_id: string | null;
|
|
7
|
+
action: string;
|
|
8
|
+
target_type: string | null;
|
|
9
|
+
target_id: string | null;
|
|
10
|
+
metadata?: Obj;
|
|
11
|
+
ip?: string | null;
|
|
12
|
+
user_agent?: string | null;
|
|
13
|
+
}
|
|
14
|
+
/** Append one audit row (what the real service writes for every mutation); the oldest rows fall off at 20000, like retention. */
|
|
15
|
+
export declare function recordAudit(e: Engine, a: AuditInput): ChainedAuditRow;
|
|
16
|
+
/** Called by the engine after every successful write: leaves the audit row the real service would (names like `user.created`, `session.revoked`). */
|
|
17
|
+
export declare function auditMutation(e: Engine, w: {
|
|
18
|
+
method: string;
|
|
19
|
+
path: string;
|
|
20
|
+
params: Record<string, string>;
|
|
21
|
+
key: KeyInfo | null;
|
|
22
|
+
body: unknown;
|
|
23
|
+
}): void;
|
|
24
|
+
/**
|
|
25
|
+
* One pass of the real worker: link the settled rows, then (when the checkpoint interval passed) verify what was added since
|
|
26
|
+
* the last checkpoint and sign a new one. Nothing is signed over a chain that does not verify: `audit_chain.tamper_detected`
|
|
27
|
+
* is raised instead. `settle: false` links every row now (the test helper); the routes call it with the real 60 s delay.
|
|
28
|
+
*/
|
|
29
|
+
export declare function sweepChain(e: Engine, settle?: boolean): Promise<{
|
|
30
|
+
appended: number;
|
|
31
|
+
checkpoint: boolean;
|
|
32
|
+
tampered: boolean;
|
|
33
|
+
head_seq: number;
|
|
34
|
+
}>;
|
|
35
|
+
export declare function emu4TrustHandlers(): RouteDef[];
|