UNPKG

agentfootprint

Version:

The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.

91 lines • 4.38 kB
"use strict"; /** * hosting/signin/hostSignIn — a host's `signIn` option, judged once at * construction, plus the conversation door's per-socket sign-in watch. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.signInStillLive = exports.checkHandshake = exports.checkHostSignIn = void 0; const errors_js_1 = require("../errors.js"); const identityVerification_js_1 = require("../identityVerification.js"); const doorGuard_js_1 = require("../doorGuard.js"); const types_js_1 = require("./types.js"); /** RFC 6265 cookie-name characters (an HTTP token). */ const COOKIE_NAME = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/; /** Refuse a half-spelled `signIn` by name, before a socket exists. */ function checkHostSignIn(hostName, option, door = {}) { if (option === undefined) return undefined; refuseOpenBrowserRules(hostName, door); const cookieName = option.cookieName ?? types_js_1.SIGN_IN_COOKIE; if (typeof cookieName !== 'string' || !COOKIE_NAME.test(cookieName)) { throw new TypeError(`[hosting] ${hostName}: signIn.cookieName ${JSON.stringify(cookieName)} is not a cookie ` + `name (an HTTP token: letters, digits and !#$%&'*+-.^_\`|~).`); } const identity = option.identity; if (identity === undefined || identity === null || (typeof identity.verify !== 'function' && typeof identity.signIn?.identify !== 'function')) { throw new TypeError(`[hosting] ${hostName}: signIn needs 'identity' — the same object standingAgent takes — ` + `so the conversation door can verify a handshake before the 101. A door that stripped ` + `the cookie and checked nothing would hand a socket to anybody who asked.`); } return { cookieName, identity }; } exports.checkHostSignIn = checkHostSignIn; /** * Verify a handshake: the same funnel a request goes through. Resolves the * refusal, or `undefined` when the caller is proven. */ async function checkHandshake(signIn, headers, signInKey) { try { await (0, identityVerification_js_1.verifyRequestIdentity)(signIn.identity, headers, undefined, signInKey); return undefined; } catch (err) { if (err instanceof errors_js_1.VerifierUnavailableError) return { status: 503, error: err }; if (err instanceof errors_js_1.IdentityNotVerifiedError) return { status: 401, error: err }; return { status: 401, error: new errors_js_1.IdentityNotVerifiedError('unverifiable', false) }; } } exports.checkHandshake = checkHandshake; /** * Is the sign-in behind this socket still live? `'live'`, `'ended'`, or * `'unknown'` when the store could not answer (the frame is held back either * way; an unknown answer closes as an outage, never as a sign-out). */ async function signInStillLive(source, key) { try { return (await source.identify(key)) === undefined ? 'ended' : 'live'; } catch { return 'unknown'; } } exports.signInStillLive = signInStillLive; /** * H1 on the host (review idI34 S-7): a host that carries a sign-in cookie must * keep the browser rules on. A cookie rides along on every forged request, and * `SameSite=Strict` does not stop a same-site sibling page — the door guard is * the defence. So, with `signIn`: never `allowedOrigins: 'any'` (unset means * this door's own host, an allowlist of one), never `requireJsonContentType: * false`, never `allowedHosts: 'any'`, and `allowedHosts` set unless the host * binds a loopback address. */ function refuseOpenBrowserRules(hostName, door) { const refuse = (sentence) => { throw new TypeError(`[hosting] ${hostName}: signIn needs the browser rules on — ${sentence}. A sign-in cookie ` + `rides along on every forged request, and the door guard is what refuses them.`); }; if (door.allowedOrigins === 'any') refuse(`allowedOrigins may not be 'any'`); if (door.requireJsonContentType === false) refuse('requireJsonContentType may not be false'); if (door.allowedHosts === 'any') refuse(`allowedHosts may not be 'any'`); if (door.allowedHosts === undefined && !(0, doorGuard_js_1.isLoopbackBind)(door.bindHost)) { refuse('allowedHosts must list the names people use (the host does not bind a loopback address)'); } } //# sourceMappingURL=hostSignIn.js.map