@broberg/sso 0.20.0 → 0.21.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/index.cjs CHANGED
@@ -1,264 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var chunkKEBSZBHL_cjs = require('./chunk-KEBSZBHL.cjs');
4
- var fs = require('fs');
5
- var http = require('http');
3
+ var chunk2XMKZWC6_cjs = require('./chunk-2XMKZWC6.cjs');
6
4
  var jose = require('jose');
7
5
 
8
- async function createDpopKey() {
9
- const { privateKey, publicKey } = await jose.generateKeyPair("ES256", { extractable: false });
10
- const jwk = await jose.exportJWK(publicKey);
11
- const publicJwk = { kty: jwk.kty, crv: jwk.crv, x: jwk.x, y: jwk.y };
12
- return { privateKey, publicJwk, jkt: await jose.calculateJwkThumbprint(publicJwk) };
13
- }
14
- var enc = new TextEncoder();
15
- var b64url = (bytes) => btoa(String.fromCharCode(...new Uint8Array(bytes))).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
16
- async function accessTokenHash(ticket) {
17
- return b64url(await crypto.subtle.digest("SHA-256", enc.encode(ticket)));
18
- }
19
- function normalizeHtu(url) {
20
- const u = new URL(url);
21
- return `${u.protocol}//${u.host}${u.pathname}`;
22
- }
23
- async function createDpopProof(key, opts) {
24
- const payload = {
25
- jti: crypto.randomUUID(),
26
- htm: opts.method.toUpperCase(),
27
- htu: normalizeHtu(opts.url),
28
- iat: Math.floor((opts.now?.() ?? Date.now()) / 1e3)
29
- };
30
- if (opts.ticket !== void 0) payload.ath = await accessTokenHash(opts.ticket);
31
- return new jose.SignJWT(payload).setProtectedHeader({ typ: "dpop+jwt", alg: "ES256", jwk: key.publicJwk }).sign(key.privateKey);
32
- }
33
- function createMemoryReplayStore(now = () => Date.now()) {
34
- const entries = /* @__PURE__ */ new Map();
35
- return {
36
- async seen(key, ttlMs) {
37
- const t = now();
38
- for (const [k, until] of entries) if (until <= t) entries.delete(k);
39
- if (entries.has(key)) return true;
40
- entries.set(key, t + ttlMs);
41
- return false;
42
- }
43
- };
44
- }
45
- var ASYMMETRIC = /* @__PURE__ */ new Set(["ES256", "ES384", "ES512", "EdDSA", "PS256", "PS384", "PS512", "RS256", "RS384", "RS512"]);
46
- async function verifyDpopProof(proof, o) {
47
- let header;
48
- try {
49
- header = jose.decodeProtectedHeader(proof);
50
- } catch {
51
- throw new chunkKEBSZBHL_cjs.SsoError("DPoP proof is not a JWS");
52
- }
53
- if (header.typ !== "dpop+jwt") throw new chunkKEBSZBHL_cjs.SsoError(`DPoP proof has typ ${JSON.stringify(header.typ)}, not "dpop+jwt"`);
54
- if (!header.alg || !ASYMMETRIC.has(header.alg)) throw new chunkKEBSZBHL_cjs.SsoError(`DPoP proof alg ${JSON.stringify(header.alg)} is not an accepted asymmetric algorithm`);
55
- const jwk = header.jwk;
56
- if (!jwk || typeof jwk !== "object") throw new chunkKEBSZBHL_cjs.SsoError("DPoP proof carries no jwk");
57
- if ("d" in jwk) throw new chunkKEBSZBHL_cjs.SsoError("DPoP proof jwk contains a private key");
58
- let payload;
59
- try {
60
- const key = await jose.importJWK(jwk, header.alg);
61
- ({ payload } = await jose.jwtVerify(proof, key, { typ: "dpop+jwt", algorithms: [header.alg] }));
62
- } catch (e) {
63
- throw new chunkKEBSZBHL_cjs.SsoError(`DPoP proof signature rejected: ${e instanceof Error ? e.message : String(e)}`);
64
- }
65
- if (await jose.calculateJwkThumbprint(jwk) !== o.jkt) throw new chunkKEBSZBHL_cjs.SsoError("DPoP proof key does not match the ticket's cnf.jkt");
66
- if (payload.htm !== o.method.toUpperCase()) throw new chunkKEBSZBHL_cjs.SsoError(`DPoP proof is for ${JSON.stringify(payload.htm)}, the request is ${o.method.toUpperCase()}`);
67
- let htu;
68
- try {
69
- htu = normalizeHtu(String(payload.htu));
70
- } catch {
71
- throw new chunkKEBSZBHL_cjs.SsoError("DPoP proof htu is not a URL");
72
- }
73
- if (htu !== normalizeHtu(o.url)) throw new chunkKEBSZBHL_cjs.SsoError(`DPoP proof is for ${htu}, the request is ${normalizeHtu(o.url)}`);
74
- const nowSec = Math.floor(o.now() / 1e3);
75
- if (typeof payload.iat !== "number" || Math.abs(nowSec - payload.iat) > o.iatWindowSec) {
76
- throw new chunkKEBSZBHL_cjs.SsoError(`DPoP proof iat is outside \xB1${o.iatWindowSec}s`);
77
- }
78
- if (payload.ath !== await accessTokenHash(o.ticket)) throw new chunkKEBSZBHL_cjs.SsoError("DPoP proof ath does not match this ticket");
79
- if (typeof payload.jti !== "string" || payload.jti === "") throw new chunkKEBSZBHL_cjs.SsoError("DPoP proof has no jti");
80
- if (await o.replay.seen(`${o.jkt}:${payload.jti}`, o.iatWindowSec * 2 * 1e3)) {
81
- throw new chunkKEBSZBHL_cjs.SsoError("DPoP proof was already used (jti replay)");
82
- }
83
- }
84
-
85
- // src/fetch-ticket.ts
86
- var DEFAULT_ISSUER = "https://id.broberg.ai";
87
- var FLY_SOCKET = "/.fly/api";
88
- var NoWorkloadIdentityError = class extends Error {
89
- constructor(message) {
90
- super(message);
91
- this.name = "NoWorkloadIdentityError";
92
- }
93
- };
94
- var TicketExchangeError = class extends Error {
95
- constructor(message, code, status) {
96
- super(message);
97
- this.code = code;
98
- this.status = status;
99
- this.name = "TicketExchangeError";
100
- }
101
- code;
102
- status;
103
- };
104
- var TicketUnavailableError = class extends Error {
105
- constructor(message) {
106
- super(message);
107
- this.name = "TicketUnavailableError";
108
- }
109
- };
110
- function flyOidcOverSocket(aud) {
111
- return new Promise((resolve, reject) => {
112
- const body = JSON.stringify({ aud });
113
- const req = http.request(
114
- { socketPath: FLY_SOCKET, path: "/v1/tokens/oidc", method: "POST", headers: { "content-type": "application/json", "content-length": Buffer.byteLength(body) } },
115
- (res) => {
116
- let data = "";
117
- res.setEncoding("utf8");
118
- res.on("data", (c) => data += c);
119
- res.on("end", () => {
120
- if ((res.statusCode ?? 0) >= 200 && (res.statusCode ?? 0) < 300) resolve(data.trim());
121
- else reject(new TicketUnavailableError(`Fly OIDC answered ${res.statusCode}`));
122
- });
123
- }
124
- );
125
- req.on("error", (e) => reject(new TicketUnavailableError(`Fly OIDC socket: ${e.message}`)));
126
- req.end(body);
127
- });
128
- }
129
- function jwtExp(token) {
130
- try {
131
- const payload = JSON.parse(Buffer.from(token.split(".")[1] ?? "", "base64url").toString("utf8"));
132
- return typeof payload.exp === "number" ? payload.exp : null;
133
- } catch {
134
- return null;
135
- }
136
- }
137
- async function readTicketResponse(res, issuer, target, now) {
138
- let body = {};
139
- try {
140
- body = await res.json();
141
- } catch {
142
- }
143
- if (res.status >= 500) throw new TicketUnavailableError(`${issuer} answered ${res.status}`);
144
- if (!res.ok || !body.access_token) {
145
- const desc = body.error_description ?? "";
146
- const code = desc.includes(":") ? desc.slice(0, desc.indexOf(":")).trim() : body.error ?? "exchange_refused";
147
- throw new TicketExchangeError(`BID refused the ticket for ${target}: ${desc || body.error || res.status}`, code, res.status);
148
- }
149
- const nowSec = Math.floor(now() / 1e3);
150
- const exp = jwtExp(body.access_token) ?? nowSec + (body.expires_in ?? 300);
151
- return { token: body.access_token, exp };
152
- }
153
- function createTicketClient(options = {}) {
154
- const issuer = (options.issuer ?? DEFAULT_ISSUER).replace(/\/+$/, "");
155
- const renewBeforeSec = options.renewBeforeSec ?? 30;
156
- const env = options.env ?? process.env;
157
- const fetchImpl = options.fetchImpl ?? fetch;
158
- const now = options.now ?? (() => Date.now());
159
- const flyOidc = options.flyOidc ?? flyOidcOverSocket;
160
- const onFly = options.onFly ?? (() => !!env.FLY_APP_NAME && fs.existsSync(FLY_SOCKET));
161
- const cache = /* @__PURE__ */ new Map();
162
- const inFlight = /* @__PURE__ */ new Map();
163
- let dpopKey = null;
164
- const ownKey = () => dpopKey ??= createDpopKey();
165
- async function platformToken() {
166
- if (onFly()) return flyOidc(issuer);
167
- const url = env.ACTIONS_ID_TOKEN_REQUEST_URL;
168
- const bearer = env.ACTIONS_ID_TOKEN_REQUEST_TOKEN;
169
- if (url && bearer) {
170
- let res;
171
- try {
172
- res = await fetchImpl(`${url}&audience=${encodeURIComponent(issuer)}`, { headers: { authorization: `Bearer ${bearer}` } });
173
- } catch (e) {
174
- throw new TicketUnavailableError(`GitHub OIDC endpoint unreachable: ${e instanceof Error ? e.message : String(e)}`);
175
- }
176
- if (!res.ok) throw new TicketUnavailableError(`GitHub OIDC endpoint answered ${res.status}`);
177
- const { value } = await res.json();
178
- if (!value) throw new TicketUnavailableError("GitHub OIDC endpoint returned no token");
179
- return value;
180
- }
181
- throw new NoWorkloadIdentityError(
182
- "No workload identity to exchange for a ticket: not on a Fly machine (FLY_APP_NAME + /.fly/api) and not in a GitHub Actions job (ACTIONS_ID_TOKEN_REQUEST_URL/_TOKEN \u2014 add `permissions: id-token: write`). A Mac session keeps using its session key."
183
- );
184
- }
185
- async function exchange(audience, scope) {
186
- const subject = await platformToken();
187
- const form = new URLSearchParams({
188
- grant_type: "urn:ietf:params:oauth:grant-type:token-exchange",
189
- subject_token: subject,
190
- subject_token_type: "urn:ietf:params:oauth:token-type:jwt",
191
- audience
192
- });
193
- if (scope) form.set("scope", scope);
194
- let res;
195
- try {
196
- const tokenUrl = `${issuer}/oauth2/token`;
197
- const headers = { "content-type": "application/x-www-form-urlencoded" };
198
- if (options.dpop) headers.dpop = await createDpopProof(await ownKey(), { method: "POST", url: tokenUrl, now });
199
- res = await fetchImpl(tokenUrl, { method: "POST", headers, body: form });
200
- } catch (e) {
201
- throw new TicketUnavailableError(`${issuer} unreachable: ${e instanceof Error ? e.message : String(e)}`);
202
- }
203
- return readTicketResponse(res, issuer, audience, now);
204
- }
205
- const client = {
206
- async authHeaders({ audience, scope, method, url }) {
207
- const ticket = await client.get({ audience, scope });
208
- if (!options.dpop) return { authorization: `Bearer ${ticket}` };
209
- return { authorization: `DPoP ${ticket}`, dpop: await createDpopProof(await ownKey(), { method, url, ticket, now }) };
210
- },
211
- async get({ audience, scope }) {
212
- const key = `${audience} ${scope ?? ""}`;
213
- const hit = cache.get(key);
214
- if (hit && hit.exp - renewBeforeSec > now() / 1e3) return hit.token;
215
- const pending = inFlight.get(key);
216
- if (pending) return pending;
217
- const p = exchange(audience, scope).then((t) => {
218
- cache.set(key, t);
219
- return t.token;
220
- }).finally(() => inFlight.delete(key));
221
- inFlight.set(key, p);
222
- return p;
223
- }
224
- };
225
- return client;
226
- }
227
- var shared = null;
228
- function fetchTicket(opts) {
229
- shared ??= createTicketClient();
230
- return shared.get(opts);
231
- }
232
- async function exchangeUserToken(opts) {
233
- const issuer = (opts.issuer ?? DEFAULT_ISSUER).replace(/\/+$/, "");
234
- const target = opts.resource ?? opts.audience;
235
- if (!target) throw new TicketExchangeError("exchangeUserToken needs a receiver: resource (its URL) or audience (BID's name for it)", "malformed_request", 0);
236
- const fetchImpl = opts.fetchImpl ?? fetch;
237
- const now = opts.now ?? (() => Date.now());
238
- const form = new URLSearchParams({
239
- grant_type: "urn:ietf:params:oauth:grant-type:token-exchange",
240
- subject_token: opts.subjectToken,
241
- subject_token_type: "urn:ietf:params:oauth:token-type:access_token"
242
- });
243
- if (opts.resource) form.set("resource", opts.resource);
244
- if (opts.audience) form.set("audience", opts.audience);
245
- if (opts.scope) form.set("scope", opts.scope);
246
- const tokenUrl = `${issuer}/oauth2/token`;
247
- const headers = { "content-type": "application/x-www-form-urlencoded" };
248
- if (opts.clientSecret) {
249
- headers.authorization = `Basic ${btoa(`${encodeURIComponent(opts.clientId)}:${encodeURIComponent(opts.clientSecret)}`)}`;
250
- } else {
251
- form.set("client_id", opts.clientId);
252
- }
253
- if (opts.dpopKey) headers.dpop = await createDpopProof(opts.dpopKey, { method: "POST", url: tokenUrl, now });
254
- let res;
255
- try {
256
- res = await fetchImpl(tokenUrl, { method: "POST", headers, body: form });
257
- } catch (e) {
258
- throw new TicketUnavailableError(`${issuer} unreachable: ${e instanceof Error ? e.message : String(e)}`);
259
- }
260
- return readTicketResponse(res, issuer, target, now);
261
- }
262
6
  var PRINCIPAL_TYPES = ["human", "service", "agent", "user"];
263
7
  var TICKET_FORMAT_VERSION = 1;
264
8
  var MAX_ACT_DEPTH = 5;
@@ -273,11 +17,11 @@ function createTicketVerifier(options) {
273
17
  dpopIatWindowSec = 60,
274
18
  now = () => Date.now()
275
19
  } = options;
276
- const replayStore = options.replayStore ?? createMemoryReplayStore(now);
277
- if (!issuer) throw new chunkKEBSZBHL_cjs.SsoError("createTicketVerifier needs an issuer");
278
- if (!audience) throw new chunkKEBSZBHL_cjs.SsoError("createTicketVerifier needs this receiver's audience");
20
+ const replayStore = options.replayStore ?? chunk2XMKZWC6_cjs.createMemoryReplayStore(now);
21
+ if (!issuer) throw new chunk2XMKZWC6_cjs.SsoError("createTicketVerifier needs an issuer");
22
+ if (!audience) throw new chunk2XMKZWC6_cjs.SsoError("createTicketVerifier needs this receiver's audience");
279
23
  let cachePromise = null;
280
- const cacheFor = (jwksUri) => chunkKEBSZBHL_cjs.createJwksCache({
24
+ const cacheFor = (jwksUri) => chunk2XMKZWC6_cjs.createJwksCache({
281
25
  jwksUri,
282
26
  fetchImpl,
283
27
  ...options.warmUp ? { warmUp: true } : {},
@@ -293,12 +37,12 @@ function createTicketVerifier(options) {
293
37
  if (!res.ok) throw new Error(`answered ${res.status}`);
294
38
  doc = await res.json();
295
39
  } catch (cause) {
296
- throw new chunkKEBSZBHL_cjs.JwksUnavailableError(`${url}: ${cause instanceof Error ? cause.message : String(cause)}`);
40
+ throw new chunk2XMKZWC6_cjs.JwksUnavailableError(`${url}: ${cause instanceof Error ? cause.message : String(cause)}`);
297
41
  }
298
42
  if (doc.issuer !== issuer) {
299
- throw new chunkKEBSZBHL_cjs.SsoError(`issuer is ${issuer} but ${url} says ${doc.issuer} \u2014 they must match exactly`);
43
+ throw new chunk2XMKZWC6_cjs.SsoError(`issuer is ${issuer} but ${url} says ${doc.issuer} \u2014 they must match exactly`);
300
44
  }
301
- if (!doc.jwks_uri) throw new chunkKEBSZBHL_cjs.SsoError(`${url} names no jwks_uri`);
45
+ if (!doc.jwks_uri) throw new chunk2XMKZWC6_cjs.SsoError(`${url} names no jwks_uri`);
302
46
  return cacheFor(doc.jwks_uri);
303
47
  })().catch((err) => {
304
48
  cachePromise = null;
@@ -314,52 +58,52 @@ function createTicketVerifier(options) {
314
58
  try {
315
59
  header = jose.decodeProtectedHeader(token);
316
60
  } catch {
317
- throw new chunkKEBSZBHL_cjs.SsoError("ticket is not a JWS");
61
+ throw new chunk2XMKZWC6_cjs.SsoError("ticket is not a JWS");
318
62
  }
319
- if (!header.kid) throw new chunkKEBSZBHL_cjs.SsoError("ticket has no kid \u2014 cannot pick a signing key");
320
- if (header.typ === "logout+jwt") throw new chunkKEBSZBHL_cjs.SsoError("a logout token is not a ticket");
63
+ if (!header.kid) throw new chunk2XMKZWC6_cjs.SsoError("ticket has no kid \u2014 cannot pick a signing key");
64
+ if (header.typ === "logout+jwt") throw new chunk2XMKZWC6_cjs.SsoError("a logout token is not a ticket");
321
65
  const cache = await keys();
322
66
  let payload;
323
67
  try {
324
68
  ({ payload } = await jose.jwtVerify(token, async () => cache.getKey(header.kid, header.alg ?? "EdDSA"), {
325
69
  issuer,
326
70
  audience,
327
- algorithms: chunkKEBSZBHL_cjs.ALLOWED_ALGS,
71
+ algorithms: chunk2XMKZWC6_cjs.ALLOWED_ALGS,
328
72
  clockTolerance: clockToleranceSec,
329
73
  requiredClaims: ["exp", "iat", "jti", "sub"]
330
74
  }));
331
75
  } catch (e) {
332
- if (e instanceof chunkKEBSZBHL_cjs.JwksUnavailableError) throw e;
333
- throw new chunkKEBSZBHL_cjs.SsoError(`ticket rejected: ${e instanceof Error ? e.message : String(e)}`);
76
+ if (e instanceof chunk2XMKZWC6_cjs.JwksUnavailableError) throw e;
77
+ throw new chunk2XMKZWC6_cjs.SsoError(`ticket rejected: ${e instanceof Error ? e.message : String(e)}`);
334
78
  }
335
- if ("events" in payload) throw new chunkKEBSZBHL_cjs.SsoError("a logout token is not a ticket");
336
- if ("nonce" in payload) throw new chunkKEBSZBHL_cjs.SsoError("an ID token is not a ticket");
79
+ if ("events" in payload) throw new chunk2XMKZWC6_cjs.SsoError("a logout token is not a ticket");
80
+ if ("nonce" in payload) throw new chunk2XMKZWC6_cjs.SsoError("an ID token is not a ticket");
337
81
  const type = payload.principal_type;
338
82
  if (typeof type !== "string" || !PRINCIPAL_TYPES.includes(type)) {
339
- throw new chunkKEBSZBHL_cjs.SsoError(`ticket has no valid principal_type (got ${JSON.stringify(type)})`);
83
+ throw new chunk2XMKZWC6_cjs.SsoError(`ticket has no valid principal_type (got ${JSON.stringify(type)})`);
340
84
  }
341
85
  const lifetime = payload.exp - payload.iat;
342
86
  if (lifetime > maxLifetimeSec) {
343
- throw new chunkKEBSZBHL_cjs.SsoError(`ticket claims a ${lifetime}s lifetime; at most ${maxLifetimeSec}s is accepted`);
87
+ throw new chunk2XMKZWC6_cjs.SsoError(`ticket claims a ${lifetime}s lifetime; at most ${maxLifetimeSec}s is accepted`);
344
88
  }
345
- if (typeof payload.sub !== "string" || payload.sub === "") throw new chunkKEBSZBHL_cjs.SsoError("ticket has no sub");
89
+ if (typeof payload.sub !== "string" || payload.sub === "") throw new chunk2XMKZWC6_cjs.SsoError("ticket has no sub");
346
90
  const scopes = typeof payload.scope === "string" ? payload.scope.split(" ").filter(Boolean) : [];
347
91
  const required = opts.scope === void 0 ? [] : Array.isArray(opts.scope) ? opts.scope : [opts.scope];
348
92
  const missing = required.filter((s) => !scopes.includes(s));
349
- if (missing.length) throw new chunkKEBSZBHL_cjs.SsoError(`ticket lacks scope ${missing.join(", ")}`);
93
+ if (missing.length) throw new chunk2XMKZWC6_cjs.SsoError(`ticket lacks scope ${missing.join(", ")}`);
350
94
  const ver = payload.ver === void 0 ? 0 : payload.ver;
351
95
  if (typeof ver !== "number" || !Number.isInteger(ver) || ver < 0) {
352
- throw new chunkKEBSZBHL_cjs.SsoError(`ticket has an invalid ver (got ${JSON.stringify(payload.ver)})`);
96
+ throw new chunk2XMKZWC6_cjs.SsoError(`ticket has an invalid ver (got ${JSON.stringify(payload.ver)})`);
353
97
  }
354
98
  if (ver > TICKET_FORMAT_VERSION) {
355
- throw new chunkKEBSZBHL_cjs.SsoError(`ticket format version ${ver} is newer than this @broberg/sso understands (${TICKET_FORMAT_VERSION}) \u2014 upgrade @broberg/sso`);
99
+ throw new chunk2XMKZWC6_cjs.SsoError(`ticket format version ${ver} is newer than this @broberg/sso understands (${TICKET_FORMAT_VERSION}) \u2014 upgrade @broberg/sso`);
356
100
  }
357
101
  const act = payload.act === void 0 ? null : readActor(payload.act, 1);
358
102
  const cnfRaw = payload.cnf;
359
103
  const cnf = cnfRaw && typeof cnfRaw.jkt === "string" && cnfRaw.jkt ? { jkt: cnfRaw.jkt } : null;
360
104
  if (cnf) {
361
- if (!opts.dpop?.proof) throw new chunkKEBSZBHL_cjs.SsoError("ticket is DPoP-bound (cnf.jkt) but no DPoP proof was presented");
362
- await verifyDpopProof(opts.dpop.proof, {
105
+ if (!opts.dpop?.proof) throw new chunk2XMKZWC6_cjs.SsoError("ticket is DPoP-bound (cnf.jkt) but no DPoP proof was presented");
106
+ await chunk2XMKZWC6_cjs.verifyDpopProof(opts.dpop.proof, {
363
107
  method: opts.dpop.method,
364
108
  url: opts.dpop.url,
365
109
  ticket: token,
@@ -369,11 +113,11 @@ function createTicketVerifier(options) {
369
113
  now
370
114
  });
371
115
  } else if (requireDpop) {
372
- throw new chunkKEBSZBHL_cjs.SsoError(cnfRaw !== void 0 ? "ticket has a cnf without a string jkt \u2014 DPoP is required here" : "this receiver requires DPoP; the ticket is not bound (no cnf.jkt)");
116
+ throw new chunk2XMKZWC6_cjs.SsoError(cnfRaw !== void 0 ? "ticket has a cnf without a string jkt \u2014 DPoP is required here" : "this receiver requires DPoP; the ticket is not bound (no cnf.jkt)");
373
117
  }
374
118
  const named = (v) => typeof v === "string" && v ? v : null;
375
119
  const clientId = type === "user" ? named(payload.client_id) ?? named(payload.azp) : named(payload.client_id) ?? payload.sub;
376
- if (clientId === null) throw new chunkKEBSZBHL_cjs.SsoError("a user ticket names no app (no client_id or azp)");
120
+ if (clientId === null) throw new chunk2XMKZWC6_cjs.SsoError("a user ticket names no app (no client_id or azp)");
377
121
  return {
378
122
  principal: payload.sub,
379
123
  type,
@@ -390,141 +134,184 @@ function createTicketVerifier(options) {
390
134
  };
391
135
  }
392
136
  function readActor(raw, depth) {
393
- if (depth > MAX_ACT_DEPTH) throw new chunkKEBSZBHL_cjs.SsoError(`ticket's delegation chain is deeper than ${MAX_ACT_DEPTH}`);
137
+ if (depth > MAX_ACT_DEPTH) throw new chunk2XMKZWC6_cjs.SsoError(`ticket's delegation chain is deeper than ${MAX_ACT_DEPTH}`);
394
138
  const link = raw;
395
139
  if (!link || typeof link !== "object" || typeof link.sub !== "string" || link.sub === "") {
396
- throw new chunkKEBSZBHL_cjs.SsoError(`ticket's act (link ${depth}) has no string sub`);
140
+ throw new chunk2XMKZWC6_cjs.SsoError(`ticket's act (link ${depth}) has no string sub`);
397
141
  }
398
142
  return link.act === void 0 ? { sub: link.sub } : { sub: link.sub, act: readActor(link.act, depth + 1) };
399
143
  }
400
144
 
401
145
  Object.defineProperty(exports, "AVATAR_TYPES", {
402
146
  enumerable: true,
403
- get: function () { return chunkKEBSZBHL_cjs.AVATAR_TYPES; }
147
+ get: function () { return chunk2XMKZWC6_cjs.AVATAR_TYPES; }
148
+ });
149
+ Object.defineProperty(exports, "DEFAULT_ISSUER", {
150
+ enumerable: true,
151
+ get: function () { return chunk2XMKZWC6_cjs.DEFAULT_ISSUER; }
404
152
  });
405
153
  Object.defineProperty(exports, "DEFAULT_SESSION_MAX_AGE", {
406
154
  enumerable: true,
407
- get: function () { return chunkKEBSZBHL_cjs.DEFAULT_SESSION_MAX_AGE; }
155
+ get: function () { return chunk2XMKZWC6_cjs.DEFAULT_SESSION_MAX_AGE; }
408
156
  });
409
157
  Object.defineProperty(exports, "EMBEDDED_FLOW_MAX_AGE", {
410
158
  enumerable: true,
411
- get: function () { return chunkKEBSZBHL_cjs.EMBEDDED_FLOW_MAX_AGE; }
159
+ get: function () { return chunk2XMKZWC6_cjs.EMBEDDED_FLOW_MAX_AGE; }
160
+ });
161
+ Object.defineProperty(exports, "FLY_CLIENT_ASSERTION_TYPE", {
162
+ enumerable: true,
163
+ get: function () { return chunk2XMKZWC6_cjs.FLY_CLIENT_ASSERTION_TYPE; }
412
164
  });
413
165
  Object.defineProperty(exports, "JwksError", {
414
166
  enumerable: true,
415
- get: function () { return chunkKEBSZBHL_cjs.JwksError; }
167
+ get: function () { return chunk2XMKZWC6_cjs.JwksError; }
416
168
  });
417
169
  Object.defineProperty(exports, "JwksUnavailableError", {
418
170
  enumerable: true,
419
- get: function () { return chunkKEBSZBHL_cjs.JwksUnavailableError; }
171
+ get: function () { return chunk2XMKZWC6_cjs.JwksUnavailableError; }
420
172
  });
421
173
  Object.defineProperty(exports, "JwksUnknownKeyError", {
422
174
  enumerable: true,
423
- get: function () { return chunkKEBSZBHL_cjs.JwksUnknownKeyError; }
175
+ get: function () { return chunk2XMKZWC6_cjs.JwksUnknownKeyError; }
424
176
  });
425
177
  Object.defineProperty(exports, "MAX_AVATAR_BYTES", {
426
178
  enumerable: true,
427
- get: function () { return chunkKEBSZBHL_cjs.MAX_AVATAR_BYTES; }
179
+ get: function () { return chunk2XMKZWC6_cjs.MAX_AVATAR_BYTES; }
428
180
  });
429
181
  Object.defineProperty(exports, "MAX_INVITATIONS", {
430
182
  enumerable: true,
431
- get: function () { return chunkKEBSZBHL_cjs.MAX_INVITATIONS; }
183
+ get: function () { return chunk2XMKZWC6_cjs.MAX_INVITATIONS; }
184
+ });
185
+ Object.defineProperty(exports, "NoWorkloadIdentityError", {
186
+ enumerable: true,
187
+ get: function () { return chunk2XMKZWC6_cjs.NoWorkloadIdentityError; }
432
188
  });
433
189
  Object.defineProperty(exports, "SsoAppApiError", {
434
190
  enumerable: true,
435
- get: function () { return chunkKEBSZBHL_cjs.SsoAppApiError; }
191
+ get: function () { return chunk2XMKZWC6_cjs.SsoAppApiError; }
436
192
  });
437
193
  Object.defineProperty(exports, "SsoAvatarRejectedError", {
438
194
  enumerable: true,
439
- get: function () { return chunkKEBSZBHL_cjs.SsoAvatarRejectedError; }
195
+ get: function () { return chunk2XMKZWC6_cjs.SsoAvatarRejectedError; }
440
196
  });
441
197
  Object.defineProperty(exports, "SsoConfigError", {
442
198
  enumerable: true,
443
- get: function () { return chunkKEBSZBHL_cjs.SsoConfigError; }
199
+ get: function () { return chunk2XMKZWC6_cjs.SsoConfigError; }
444
200
  });
445
201
  Object.defineProperty(exports, "SsoError", {
446
202
  enumerable: true,
447
- get: function () { return chunkKEBSZBHL_cjs.SsoError; }
203
+ get: function () { return chunk2XMKZWC6_cjs.SsoError; }
448
204
  });
449
205
  Object.defineProperty(exports, "SsoInsufficientScopeError", {
450
206
  enumerable: true,
451
- get: function () { return chunkKEBSZBHL_cjs.SsoInsufficientScopeError; }
207
+ get: function () { return chunk2XMKZWC6_cjs.SsoInsufficientScopeError; }
452
208
  });
453
209
  Object.defineProperty(exports, "SsoIntrospectionUnavailableError", {
454
210
  enumerable: true,
455
- get: function () { return chunkKEBSZBHL_cjs.SsoIntrospectionUnavailableError; }
211
+ get: function () { return chunk2XMKZWC6_cjs.SsoIntrospectionUnavailableError; }
456
212
  });
457
213
  Object.defineProperty(exports, "SsoReauthError", {
458
214
  enumerable: true,
459
- get: function () { return chunkKEBSZBHL_cjs.SsoReauthError; }
215
+ get: function () { return chunk2XMKZWC6_cjs.SsoReauthError; }
460
216
  });
461
217
  Object.defineProperty(exports, "SsoTokenInactiveError", {
462
218
  enumerable: true,
463
- get: function () { return chunkKEBSZBHL_cjs.SsoTokenInactiveError; }
219
+ get: function () { return chunk2XMKZWC6_cjs.SsoTokenInactiveError; }
220
+ });
221
+ Object.defineProperty(exports, "TicketExchangeError", {
222
+ enumerable: true,
223
+ get: function () { return chunk2XMKZWC6_cjs.TicketExchangeError; }
224
+ });
225
+ Object.defineProperty(exports, "TicketUnavailableError", {
226
+ enumerable: true,
227
+ get: function () { return chunk2XMKZWC6_cjs.TicketUnavailableError; }
228
+ });
229
+ Object.defineProperty(exports, "accessTokenHash", {
230
+ enumerable: true,
231
+ get: function () { return chunk2XMKZWC6_cjs.accessTokenHash; }
464
232
  });
465
233
  Object.defineProperty(exports, "cookieHeader", {
466
234
  enumerable: true,
467
- get: function () { return chunkKEBSZBHL_cjs.cookieHeader; }
235
+ get: function () { return chunk2XMKZWC6_cjs.cookieHeader; }
236
+ });
237
+ Object.defineProperty(exports, "createDpopKey", {
238
+ enumerable: true,
239
+ get: function () { return chunk2XMKZWC6_cjs.createDpopKey; }
240
+ });
241
+ Object.defineProperty(exports, "createDpopProof", {
242
+ enumerable: true,
243
+ get: function () { return chunk2XMKZWC6_cjs.createDpopProof; }
468
244
  });
469
245
  Object.defineProperty(exports, "createJwksCache", {
470
246
  enumerable: true,
471
- get: function () { return chunkKEBSZBHL_cjs.createJwksCache; }
247
+ get: function () { return chunk2XMKZWC6_cjs.createJwksCache; }
248
+ });
249
+ Object.defineProperty(exports, "createMemoryReplayStore", {
250
+ enumerable: true,
251
+ get: function () { return chunk2XMKZWC6_cjs.createMemoryReplayStore; }
472
252
  });
473
253
  Object.defineProperty(exports, "createSsoClient", {
474
254
  enumerable: true,
475
- get: function () { return chunkKEBSZBHL_cjs.createSsoClient; }
255
+ get: function () { return chunk2XMKZWC6_cjs.createSsoClient; }
256
+ });
257
+ Object.defineProperty(exports, "createTicketClient", {
258
+ enumerable: true,
259
+ get: function () { return chunk2XMKZWC6_cjs.createTicketClient; }
260
+ });
261
+ Object.defineProperty(exports, "exchangeUserToken", {
262
+ enumerable: true,
263
+ get: function () { return chunk2XMKZWC6_cjs.exchangeUserToken; }
264
+ });
265
+ Object.defineProperty(exports, "fetchTicket", {
266
+ enumerable: true,
267
+ get: function () { return chunk2XMKZWC6_cjs.fetchTicket; }
476
268
  });
477
269
  Object.defineProperty(exports, "loadSsoConfig", {
478
270
  enumerable: true,
479
- get: function () { return chunkKEBSZBHL_cjs.loadSsoConfig; }
271
+ get: function () { return chunk2XMKZWC6_cjs.loadSsoConfig; }
480
272
  });
481
273
  Object.defineProperty(exports, "memoryTokenStore", {
482
274
  enumerable: true,
483
- get: function () { return chunkKEBSZBHL_cjs.memoryTokenStore; }
275
+ get: function () { return chunk2XMKZWC6_cjs.memoryTokenStore; }
276
+ });
277
+ Object.defineProperty(exports, "normalizeHtu", {
278
+ enumerable: true,
279
+ get: function () { return chunk2XMKZWC6_cjs.normalizeHtu; }
484
280
  });
485
281
  Object.defineProperty(exports, "openEmbeddedFlow", {
486
282
  enumerable: true,
487
- get: function () { return chunkKEBSZBHL_cjs.openEmbeddedFlow; }
283
+ get: function () { return chunk2XMKZWC6_cjs.openEmbeddedFlow; }
488
284
  });
489
285
  Object.defineProperty(exports, "readCookie", {
490
286
  enumerable: true,
491
- get: function () { return chunkKEBSZBHL_cjs.readCookie; }
287
+ get: function () { return chunk2XMKZWC6_cjs.readCookie; }
492
288
  });
493
289
  Object.defineProperty(exports, "sealEmbeddedFlow", {
494
290
  enumerable: true,
495
- get: function () { return chunkKEBSZBHL_cjs.sealEmbeddedFlow; }
291
+ get: function () { return chunk2XMKZWC6_cjs.sealEmbeddedFlow; }
496
292
  });
497
293
  Object.defineProperty(exports, "signSession", {
498
294
  enumerable: true,
499
- get: function () { return chunkKEBSZBHL_cjs.signSession; }
295
+ get: function () { return chunk2XMKZWC6_cjs.signSession; }
500
296
  });
501
297
  Object.defineProperty(exports, "signValue", {
502
298
  enumerable: true,
503
- get: function () { return chunkKEBSZBHL_cjs.signValue; }
299
+ get: function () { return chunk2XMKZWC6_cjs.signValue; }
300
+ });
301
+ Object.defineProperty(exports, "verifyDpopProof", {
302
+ enumerable: true,
303
+ get: function () { return chunk2XMKZWC6_cjs.verifyDpopProof; }
504
304
  });
505
305
  Object.defineProperty(exports, "verifySession", {
506
306
  enumerable: true,
507
- get: function () { return chunkKEBSZBHL_cjs.verifySession; }
307
+ get: function () { return chunk2XMKZWC6_cjs.verifySession; }
508
308
  });
509
309
  Object.defineProperty(exports, "verifyValue", {
510
310
  enumerable: true,
511
- get: function () { return chunkKEBSZBHL_cjs.verifyValue; }
311
+ get: function () { return chunk2XMKZWC6_cjs.verifyValue; }
512
312
  });
513
- exports.DEFAULT_ISSUER = DEFAULT_ISSUER;
514
313
  exports.MAX_ACT_DEPTH = MAX_ACT_DEPTH;
515
- exports.NoWorkloadIdentityError = NoWorkloadIdentityError;
516
314
  exports.TICKET_FORMAT_VERSION = TICKET_FORMAT_VERSION;
517
- exports.TicketExchangeError = TicketExchangeError;
518
- exports.TicketUnavailableError = TicketUnavailableError;
519
- exports.accessTokenHash = accessTokenHash;
520
- exports.createDpopKey = createDpopKey;
521
- exports.createDpopProof = createDpopProof;
522
- exports.createMemoryReplayStore = createMemoryReplayStore;
523
- exports.createTicketClient = createTicketClient;
524
315
  exports.createTicketVerifier = createTicketVerifier;
525
- exports.exchangeUserToken = exchangeUserToken;
526
- exports.fetchTicket = fetchTicket;
527
- exports.normalizeHtu = normalizeHtu;
528
- exports.verifyDpopProof = verifyDpopProof;
529
316
  //# sourceMappingURL=index.cjs.map
530
317
  //# sourceMappingURL=index.cjs.map