@muze-nl/metro-oidc 0.6.0 → 0.8.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/browser.js CHANGED
@@ -5,19 +5,19 @@
5
5
  __defProp(target, name, { get: all[name], enumerable: true });
6
6
  };
7
7
 
8
- // node_modules/@muze-nl/metro/src/metro.mjs
9
- var metro_exports = {};
10
- __export(metro_exports, {
8
+ // ../metro-core/src/index.mjs
9
+ var src_exports = {};
10
+ __export(src_exports, {
11
11
  Client: () => Client,
12
12
  client: () => client,
13
13
  deepClone: () => deepClone,
14
- formdata: () => formdata,
15
14
  metroError: () => metroError,
16
15
  request: () => request,
17
16
  response: () => response,
18
- trace: () => trace,
19
17
  url: () => url
20
18
  });
19
+
20
+ // ../metro-core/src/metro.mjs
21
21
  var metroURL = "https://metro.muze.nl/details/";
22
22
  if (!Symbol.metroProxy) {
23
23
  Symbol.metroProxy = /* @__PURE__ */ Symbol("isProxy");
@@ -65,11 +65,14 @@
65
65
  }
66
66
  for (const verb of this.clientOptions.verbs) {
67
67
  this[verb] = async function(...options2) {
68
- return this.fetch(request(
69
- this.clientOptions,
70
- ...options2,
71
- { method: verb.toUpperCase() }
72
- ));
68
+ return this.fetch(
69
+ request(
70
+ this.clientOptions,
71
+ ...options2,
72
+ { method: verb.toUpperCase() }
73
+ ),
74
+ fetchOptionsFrom(...options2)
75
+ );
73
76
  };
74
77
  }
75
78
  }
@@ -113,23 +116,22 @@
113
116
  };
114
117
  let middlewares = [metrofetch].concat(this.clientOptions?.middlewares?.slice() || []);
115
118
  options = Object.assign({}, this.clientOptions, options);
119
+ const traceContext = createTraceContext(req, options);
120
+ const middlewareContext = createMiddlewareContext(this, options, traceContext);
116
121
  let next;
117
122
  for (let middleware of middlewares) {
118
123
  next = /* @__PURE__ */ (function(next2, middleware2) {
119
124
  return async function(req2) {
120
125
  let res;
121
- let tracers = Object.values(_Client.tracers);
122
- for (let tracer of tracers) {
123
- if (tracer.request) {
124
- tracer.request.call(tracer, req2, middleware2);
125
- }
126
- }
127
- res = await middleware2(req2, next2);
128
- for (let tracer of tracers) {
129
- if (tracer.response) {
130
- tracer.response.call(tracer, res, middleware2);
131
- }
126
+ let tracers = traceContext.tracers;
127
+ callTracers(tracers, "request", req2, middleware2, traceContext);
128
+ try {
129
+ res = await middleware2(req2, next2, middlewareContext);
130
+ } catch (error2) {
131
+ callTracers(tracers, "error", error2, req2, middleware2, traceContext);
132
+ throw error2;
132
133
  }
134
+ callTracers(tracers, "response", res, middleware2, traceContext);
133
135
  return res;
134
136
  };
135
137
  })(next, middleware);
@@ -143,6 +145,146 @@
143
145
  return this.clientOptions.url;
144
146
  }
145
147
  };
148
+ var traceContextId = 0;
149
+ var TRACE_OPTION_KEYS = ["trace", "tracer", "tracers"];
150
+ function fetchOptionsFrom(...options) {
151
+ const result = {};
152
+ for (const option of options) {
153
+ if (!isPlainObject(option)) {
154
+ continue;
155
+ }
156
+ for (const key of TRACE_OPTION_KEYS) {
157
+ if (key in option) {
158
+ result[key] = option[key];
159
+ }
160
+ }
161
+ }
162
+ return result;
163
+ }
164
+ function createTraceContext(req, options = {}) {
165
+ const parent = traceParentFrom(options.trace || options.tracer || options.tracers);
166
+ let localTracers = [];
167
+ if (parent) {
168
+ localTracers = parent.localTracers || [];
169
+ } else {
170
+ localTracers = normalizeTracers(options.trace).concat(normalizeTracers(options.tracer)).concat(normalizeTracers(options.tracers));
171
+ }
172
+ const globalTracers = Object.values(Client.tracers || {});
173
+ const context = {
174
+ __metroTraceContext: true,
175
+ id: "metro-trace-context-" + ++traceContextId,
176
+ parent,
177
+ request: req,
178
+ options,
179
+ globalTracers,
180
+ localTracers,
181
+ tracers: globalTracers.concat(localTracers)
182
+ };
183
+ return context;
184
+ }
185
+ function traceParentFrom(value) {
186
+ if (!value) {
187
+ return null;
188
+ }
189
+ if (value.context?.__metroTraceContext) {
190
+ return value.context;
191
+ }
192
+ if (value.__metroTraceContext) {
193
+ return value;
194
+ }
195
+ return null;
196
+ }
197
+ function normalizeTracers(value) {
198
+ if (!value || value.__metroTraceContext || value.context?.__metroTraceContext) {
199
+ return [];
200
+ }
201
+ if (Array.isArray(value)) {
202
+ return value.flatMap(normalizeTracers);
203
+ }
204
+ if (isTracer(value)) {
205
+ return [value];
206
+ }
207
+ if (isPlainObject(value)) {
208
+ return Object.values(value).flatMap(normalizeTracers);
209
+ }
210
+ return [];
211
+ }
212
+ function isTracer(value) {
213
+ return value && typeof value == "object" && [
214
+ "request",
215
+ "response",
216
+ "error",
217
+ "event",
218
+ "diagnostic",
219
+ "span",
220
+ "link",
221
+ "current"
222
+ ].some((name) => typeof value[name] == "function");
223
+ }
224
+ function createMiddlewareContext(client2, options, traceContext) {
225
+ const trace = createTraceAPI(traceContext);
226
+ return Object.freeze({
227
+ client: client2,
228
+ options,
229
+ trace,
230
+ fetch(req, fetchOptions = {}) {
231
+ return client2.fetch(req, Object.assign({}, fetchOptions, { trace }));
232
+ }
233
+ });
234
+ }
235
+ function createTraceAPI(context) {
236
+ const api = {
237
+ __metroTraceContext: true,
238
+ context,
239
+ event(name, data = {}) {
240
+ callTracers(context.tracers, "event", name, data, context);
241
+ },
242
+ diagnostic(diagnostic = {}) {
243
+ callTracers(context.tracers, "diagnostic", diagnostic, context);
244
+ },
245
+ current() {
246
+ for (const tracer of context.tracers) {
247
+ if (typeof tracer.current == "function") {
248
+ const current = tracer.current(context);
249
+ if (current) {
250
+ return current;
251
+ }
252
+ }
253
+ }
254
+ return { traceId: null, spanId: null };
255
+ },
256
+ async span(name, fn, data = {}) {
257
+ const tracer = context.tracers.find((tracer2) => typeof tracer2.span == "function");
258
+ if (!tracer) {
259
+ return fn();
260
+ }
261
+ return tracer.span(name, fn, data, context);
262
+ },
263
+ link(key) {
264
+ let traceId = null;
265
+ for (const tracer of context.tracers) {
266
+ if (typeof tracer.link == "function") {
267
+ traceId = tracer.link(key, void 0, context) || traceId;
268
+ }
269
+ }
270
+ return traceId;
271
+ },
272
+ options(extra = {}) {
273
+ return Object.assign({}, extra, { trace: api });
274
+ }
275
+ };
276
+ return api;
277
+ }
278
+ function callTracers(tracers, method, ...args) {
279
+ for (const tracer of tracers) {
280
+ if (tracer && typeof tracer[method] == "function") {
281
+ tracer[method].call(tracer, ...args);
282
+ }
283
+ }
284
+ }
285
+ function isPlainObject(value) {
286
+ return value && typeof value == "object" && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
287
+ }
146
288
  function client(...options) {
147
289
  return new Client(...deepClone(options));
148
290
  }
@@ -215,7 +357,7 @@
215
357
  let r = new Request(requestParams.url, requestParams);
216
358
  let data = requestParams.body;
217
359
  if (data) {
218
- if (typeof data == "object" && !(data instanceof String) && !(data instanceof ReadableStream) && !(data instanceof Blob) && !(data instanceof ArrayBuffer) && !(data instanceof DataView) && !(data instanceof FormData) && !(data instanceof URLSearchParams) && (typeof globalThis.TypedArray == "undefined" || !(data instanceof globalThis.TypedArray))) {
360
+ if (typeof data == "object" && !(data instanceof String) && !(data instanceof ReadableStream) && !(data instanceof Blob) && !(data instanceof ArrayBuffer) && !(data instanceof DataView) && !(data instanceof FormData) && !(data instanceof URLSearchParams) && (globalThis.ArrayBuffer && ArrayBuffer.isView(data))) {
219
361
  if (typeof data.toString == "function") {
220
362
  requestParams.body = data.toString({ headers: r.headers });
221
363
  r = new Request(requestParams.url, requestParams);
@@ -235,7 +377,7 @@
235
377
  break;
236
378
  case "with":
237
379
  result = function(...options2) {
238
- if (data) {
380
+ if (typeof data !== "undefined") {
239
381
  options2.unshift({ body: data });
240
382
  }
241
383
  return request(target, ...options2);
@@ -247,8 +389,16 @@
247
389
  default:
248
390
  if (target[prop] instanceof Function) {
249
391
  if (prop === "clone") {
392
+ result = function() {
393
+ const cloned = target.clone();
394
+ if (typeof data != "undefined" && !(typeof ReadableStream != "undefined" && data instanceof ReadableStream)) {
395
+ return request(cloned, { body: data });
396
+ }
397
+ return request(cloned);
398
+ };
399
+ } else {
400
+ result = target[prop].bind(target);
250
401
  }
251
- result = target[prop].bind(target);
252
402
  } else {
253
403
  result = target[prop];
254
404
  }
@@ -329,7 +479,7 @@
329
479
  result = data;
330
480
  break;
331
481
  case "ok":
332
- result = target.status >= 200 && target.status < 400;
482
+ result = target.status >= 200 && target.status < 300;
333
483
  break;
334
484
  default:
335
485
  if (typeof target[prop] == "function") {
@@ -353,9 +503,19 @@
353
503
  });
354
504
  }
355
505
  }
506
+ function appendHashParams(value, params) {
507
+ const target = value[Symbol.metroSource] || value;
508
+ if (!(params instanceof URLSearchParams)) {
509
+ params = new URLSearchParams(params);
510
+ }
511
+ let hash = target.hash || "#";
512
+ hash += "?" + params;
513
+ return url(target, { hash });
514
+ }
356
515
  function url(...options) {
357
516
  let validParams = [
358
517
  "hash",
518
+ "fragment",
359
519
  "host",
360
520
  "hostname",
361
521
  "href",
@@ -365,9 +525,11 @@
365
525
  "protocol",
366
526
  "username",
367
527
  "search",
368
- "searchParams"
528
+ "searchParams",
529
+ "hashParams"
369
530
  ];
370
531
  let u = new URL("https://localhost/");
532
+ let hParams = null;
371
533
  for (let option of options) {
372
534
  if (typeof option == "string" || option instanceof String) {
373
535
  u = new URL(option, u);
@@ -392,6 +554,16 @@
392
554
  if (!validParams.includes(param)) {
393
555
  throw metroError("metro.url: unknown url parameter " + metroURL + "url/unknown-param-name/", param);
394
556
  }
557
+ if (param == "fragment") {
558
+ let fragment = option.fragment;
559
+ if (fragment && typeof fragment == "string" && fragment[0] != "#") {
560
+ fragment = "#" + fragment;
561
+ }
562
+ option.hash = fragment;
563
+ param = "hash";
564
+ } else if (param == "hashParams") {
565
+ hParams = option.hashParams;
566
+ }
395
567
  if (typeof option[param] == "function") {
396
568
  option[param](u[param], u);
397
569
  } else if (typeof option[param] == "string" || option[param] instanceof String || typeof option[param] == "number" || option[param] instanceof Number || typeof option[param] == "boolean" || option[param] instanceof Boolean) {
@@ -408,6 +580,16 @@
408
580
  throw metroError("metro.url: unsupported option value " + metroURL + "url/unsupported-option-value/", option);
409
581
  }
410
582
  }
583
+ if (hParams) {
584
+ if (!u.hash) {
585
+ u.hash = "#";
586
+ }
587
+ if (typeof hParams == "string") {
588
+ u.hash += hParams;
589
+ } else {
590
+ u = appendHashParams(u, hParams);
591
+ }
592
+ }
411
593
  Object.freeze(u);
412
594
  return new Proxy(u, {
413
595
  get(target, prop) {
@@ -428,7 +610,7 @@
428
610
  result = target.pathname.split("/").pop();
429
611
  break;
430
612
  case "folderpath":
431
- result = target.pathname.substring(0, target.pathname.lastIndexOf("\\") + 1);
613
+ result = target.pathname.substring(0, target.pathname.lastIndexOf("/") + 1);
432
614
  break;
433
615
  case "authority":
434
616
  result = target.username ?? "";
@@ -439,11 +621,6 @@
439
621
  result += "/";
440
622
  result = target.protocol + "//" + result;
441
623
  break;
442
- case "origin":
443
- result = target.protocol + "//" + target.hostname;
444
- result += target.port ? ":" + target.port : "";
445
- result += "/";
446
- break;
447
624
  case "fragment":
448
625
  result = target.hash.substring(1);
449
626
  break;
@@ -466,67 +643,12 @@
466
643
  }
467
644
  });
468
645
  }
469
- function formdata(...options) {
470
- var params = new FormData();
471
- for (let option of options) {
472
- if (option instanceof HTMLFormElement) {
473
- option = new FormData(option);
474
- }
475
- if (option instanceof FormData) {
476
- for (let entry of option.entries()) {
477
- params.append(entry[0], entry[1]);
478
- }
479
- } else if (option && typeof option == "object") {
480
- for (let entry of Object.entries(option)) {
481
- if (Array.isArray(entry[1])) {
482
- for (let value of entry[1]) {
483
- params.append(entry[0], value);
484
- }
485
- } else {
486
- params.append(entry[0], entry[1]);
487
- }
488
- }
489
- } else {
490
- throw new metroError("metro.formdata: unknown option type " + metroURL + "formdata/unknown-option-value/", option);
491
- }
492
- }
493
- Object.freeze(params);
494
- return new Proxy(params, {
495
- get(target, prop) {
496
- let result;
497
- switch (prop) {
498
- case Symbol.metroProxy:
499
- result = true;
500
- break;
501
- case Symbol.metroSource:
502
- result = target;
503
- break;
504
- //TODO: add toString() that can check
505
- //headers param: toString({headers:request.headers})
506
- //for the content-type
507
- case "with":
508
- result = function(...options2) {
509
- return formdata(target, ...options2);
510
- };
511
- break;
512
- default:
513
- if (target[prop] instanceof Function) {
514
- result = target[prop].bind(target);
515
- } else {
516
- result = target[prop];
517
- }
518
- break;
519
- }
520
- return result;
521
- }
522
- });
523
- }
524
646
  var metroConsole = {
525
- error: (message, ...details) => {
526
- console.error("\u24C2\uFE0F ", message, ...details);
647
+ error: (message2, ...details) => {
648
+ console.error("\u24C2\uFE0F ", message2, ...details);
527
649
  },
528
- info: (message, ...details) => {
529
- console.info("\u24C2\uFE0F ", message, ...details);
650
+ info: (message2, ...details) => {
651
+ console.info("\u24C2\uFE0F ", message2, ...details);
530
652
  },
531
653
  group: (name) => {
532
654
  console.group("\u24C2\uFE0F " + name);
@@ -535,59 +657,16 @@
535
657
  console.groupEnd("\u24C2\uFE0F " + name);
536
658
  }
537
659
  };
538
- function metroError(message, ...details) {
539
- metroConsole.error(message, ...details);
540
- return new Error(message, ...details);
660
+ function metroError(message2, ...details) {
661
+ metroConsole.error(message2, ...details);
662
+ return new Error(message2, ...details);
541
663
  }
542
- var trace = {
543
- /**
544
- * Adds a named tracer function
545
- * @param {string} name - the name of the tracer
546
- * @param {Function} tracer - the tracer function to call
547
- */
548
- add(name, tracer) {
549
- Client.tracers[name] = tracer;
550
- },
551
- /**
552
- * Removes a named tracer function
553
- * @param {string} name
554
- */
555
- delete(name) {
556
- delete Client.tracers[name];
557
- },
558
- /**
559
- * Removes all tracer functions
560
- */
561
- clear() {
562
- Client.tracers = {};
563
- },
564
- /**
565
- * Returns a set of request and response tracer functions that use the
566
- * console.group feature to shows nested request/response pairs, with
567
- * most commonly needed information for debugging
568
- */
569
- group() {
570
- let group = 0;
571
- return {
572
- request: (req, middleware) => {
573
- group++;
574
- metroConsole.group(group);
575
- metroConsole.info(req?.url, req, middleware);
576
- },
577
- response: (res, middleware) => {
578
- metroConsole.info(res?.body ? res.body[Symbol.metroSource] : null, res, middleware);
579
- metroConsole.groupEnd(group);
580
- group--;
581
- }
582
- };
583
- }
584
- };
585
664
  function deepClone(object) {
586
665
  if (Array.isArray(object)) {
587
666
  return object.slice().map(deepClone);
588
667
  }
589
668
  if (object && typeof object === "object") {
590
- if (object.__proto__.constructor == Object || !object.__proto__) {
669
+ if (object.__proto__?.constructor == Object || !object.__proto__) {
591
670
  let result = Object.assign({}, object);
592
671
  Object.keys(result).forEach((key) => {
593
672
  result[key] = deepClone(object[key]);
@@ -600,158 +679,7 @@
600
679
  return object;
601
680
  }
602
681
 
603
- // node_modules/@muze-nl/metro/src/mw/json.mjs
604
- function jsonmw(options) {
605
- options = Object.assign({
606
- contentType: "application/json",
607
- reviver: null,
608
- replacer: null,
609
- space: ""
610
- }, options);
611
- return async function json(req, next) {
612
- if (!req.headers.get("Accept")) {
613
- req = req.with({
614
- headers: {
615
- "Accept": options.accept ?? options.contentType
616
- }
617
- });
618
- }
619
- if (req.method !== "GET" && req.method !== "HEAD") {
620
- if (req.data && typeof req.data == "object" && !(req.data instanceof ReadableStream)) {
621
- const contentType = req.headers.get("Content-Type");
622
- if (!contentType || isPlainText(contentType)) {
623
- req = req.with({
624
- headers: {
625
- "Content-Type": options.contentType
626
- }
627
- });
628
- }
629
- if (isJSON(req.headers.get("Content-Type"))) {
630
- req = req.with({
631
- body: JSON.stringify(req.data, options.replacer, options.space)
632
- });
633
- }
634
- }
635
- }
636
- let res = await next(req);
637
- if (res && isJSON(res.headers?.get("Content-Type"))) {
638
- let tempRes = res.clone();
639
- let body = await tempRes.text();
640
- try {
641
- let json2 = JSON.parse(body, options.reviver);
642
- return res.with({
643
- body: json2
644
- });
645
- } catch (e) {
646
- }
647
- }
648
- return res;
649
- };
650
- }
651
- var jsonRE = /^application\/([a-zA-Z0-9\-_]+\+)?json\b/;
652
- function isJSON(contentType) {
653
- return jsonRE.exec(contentType);
654
- }
655
- function isPlainText(contentType) {
656
- return /^text\/plain\b/.exec(contentType);
657
- }
658
-
659
- // node_modules/@muze-nl/metro/src/mw/thrower.mjs
660
- function throwermw(options) {
661
- return async function thrower(req, next) {
662
- let res = await next(req);
663
- if (!res.ok) {
664
- if (options && typeof options[res.status] == "function") {
665
- res = options[res.status].apply(res, req);
666
- } else {
667
- throw new Error(res.status + ": " + res.statusText, {
668
- cause: res
669
- });
670
- }
671
- }
672
- return res;
673
- };
674
- }
675
-
676
- // node_modules/@muze-nl/metro/src/mw/getdata.mjs
677
- function getdatamw() {
678
- return async function getdata(req, next) {
679
- let res = await next(req);
680
- if (res.ok && res.data) {
681
- return res.data;
682
- }
683
- return res;
684
- };
685
- }
686
-
687
- // node_modules/@muze-nl/metro/src/api.mjs
688
- var API = class extends Client {
689
- constructor(base, methods, bind = null) {
690
- if (base instanceof Client) {
691
- super(base.clientOptions, throwermw(), getdatamw());
692
- } else {
693
- super(base, throwermw(), getdatamw());
694
- }
695
- if (!bind) {
696
- bind = this;
697
- }
698
- for (const methodName in methods) {
699
- if (typeof methods[methodName] == "function") {
700
- this[methodName] = methods[methodName].bind(bind);
701
- } else if (methods[methodName] && typeof methods[methodName] == "object") {
702
- this[methodName] = new this.constructor(base, methods[methodName], bind);
703
- } else {
704
- this[methodName] = methods[methodName];
705
- }
706
- }
707
- }
708
- };
709
- var JsonAPI = class extends API {
710
- constructor(base, methods, bind = null) {
711
- if (base instanceof Client) {
712
- super(base.with(jsonmw()), methods, bind);
713
- } else {
714
- super(client(base, jsonmw()), methods, bind);
715
- }
716
- }
717
- };
718
- function api(...options) {
719
- return new API(...deepClone(options));
720
- }
721
- function jsonApi(...options) {
722
- return new JsonAPI(...deepClone(options));
723
- }
724
-
725
- // node_modules/@muze-nl/metro/src/everything.mjs
726
- var metro = Object.assign({}, metro_exports, {
727
- mw: {
728
- json: jsonmw,
729
- thrower: throwermw,
730
- getdata: getdatamw
731
- },
732
- api,
733
- jsonApi
734
- });
735
- if (!globalThis.metro) {
736
- globalThis.metro = metro;
737
- }
738
- var everything_default = metro;
739
-
740
- // node_modules/@muze-nl/metro-oauth2/src/oauth2.mjs
741
- var oauth2_exports = {};
742
- __export(oauth2_exports, {
743
- base64url_encode: () => base64url_encode,
744
- createState: () => createState,
745
- default: () => oauth2mw,
746
- generateCodeChallenge: () => generateCodeChallenge,
747
- generateCodeVerifier: () => generateCodeVerifier,
748
- getExpires: () => getExpires,
749
- isAuthorized: () => isAuthorized,
750
- isExpired: () => isExpired,
751
- isRedirected: () => isRedirected
752
- });
753
-
754
- // node_modules/@muze-nl/assert/src/assert.mjs
682
+ // ../../node_modules/@muze-nl/assert/src/assert.mjs
755
683
  globalThis.assertEnabled = false;
756
684
  function enable() {
757
685
  globalThis.assertEnabled = true;
@@ -957,10 +885,10 @@
957
885
  }
958
886
  return false;
959
887
  }
960
- function error(message, found, expected, path, problems) {
888
+ function error(message2, found, expected, path, problems) {
961
889
  let result = {
962
890
  path,
963
- message,
891
+ message: message2,
964
892
  found,
965
893
  expected
966
894
  };
@@ -969,8 +897,8 @@
969
897
  }
970
898
  return result;
971
899
  }
972
- function warn(message, data, pattern, path) {
973
- console.warn("\u{1F170}\uFE0F Assert: " + path, message, pattern, data);
900
+ function warn(message2, data, pattern, path) {
901
+ console.warn("\u{1F170}\uFE0F Assert: " + path, message2, pattern, data);
974
902
  }
975
903
  globalThis.assert = {
976
904
  warn,
@@ -991,7 +919,7 @@
991
919
  fails
992
920
  };
993
921
 
994
- // node_modules/@muze-nl/metro-oauth2/src/tokenstore.mjs
922
+ // ../metro-oauth2/src/tokenstore.mjs
995
923
  function tokenStore(site) {
996
924
  let localState, localTokens;
997
925
  if (typeof localStorage !== "undefined") {
@@ -999,7 +927,7 @@
999
927
  get: () => localStorage.getItem("metro/state:" + site),
1000
928
  set: (value) => localStorage.setItem("metro/state:" + site, value),
1001
929
  has: () => localStorage.getItem("metro/state:" + site) !== null,
1002
- delete: () => localStorage.remoteItem("metro/state:" + site)
930
+ delete: () => localStorage.removeItem("metro/state:" + site)
1003
931
  };
1004
932
  localTokens = {
1005
933
  get: (name) => JSON.parse(localStorage.getItem(site + ":" + name)),
@@ -1023,7 +951,16 @@
1023
951
  };
1024
952
  }
1025
953
 
1026
- // node_modules/@muze-nl/metro-oauth2/src/oauth2.mjs
954
+ // ../metro-oauth2/src/oauth2.mjs
955
+ var SUPPORTED_TOKEN_TYPES = /* @__PURE__ */ new Map([
956
+ ["bearer", "Bearer"],
957
+ ["dpop", "DPoP"]
958
+ ]);
959
+ var SUPPORTED_TOKEN_ENDPOINT_AUTH_METHODS = /* @__PURE__ */ new Set([
960
+ "none",
961
+ "client_secret_post",
962
+ "client_secret_basic"
963
+ ]);
1027
964
  function oauth2mw(options) {
1028
965
  const defaultOptions = {
1029
966
  client: client(),
@@ -1044,9 +981,9 @@
1044
981
  }
1045
982
  };
1046
983
  assert(options, {});
1047
- const oauth22 = Object.assign({}, defaultOptions.oauth2_configuration, options?.oauth2_configuration);
984
+ const oauth2 = Object.assign({}, defaultOptions.oauth2_configuration, options?.oauth2_configuration);
1048
985
  options = Object.assign({}, defaultOptions, options);
1049
- options.oauth2_configuration = oauth22;
986
+ options.oauth2_configuration = oauth2;
1050
987
  const store = tokenStore(options.site);
1051
988
  if (!options.tokens) {
1052
989
  options.tokens = store.tokens;
@@ -1063,12 +1000,12 @@
1063
1000
  redirect_uri: Required(validURL)
1064
1001
  }
1065
1002
  });
1066
- for (let option in oauth22) {
1003
+ for (let option in oauth2) {
1067
1004
  switch (option) {
1068
1005
  case "access_token":
1069
1006
  case "authorization_code":
1070
1007
  case "refresh_token":
1071
- options.tokens.set(option, oauth22[option]);
1008
+ options.tokens.set(option, normalizeInitialToken(option, oauth2[option]));
1072
1009
  break;
1073
1010
  }
1074
1011
  }
@@ -1076,32 +1013,11 @@
1076
1013
  if (options.force_authorization) {
1077
1014
  return oauth2authorized(req, next);
1078
1015
  }
1079
- let res;
1080
- try {
1081
- res = await next(req);
1082
- if (res.ok) {
1083
- return res;
1084
- }
1085
- } catch (err) {
1086
- switch (res?.status) {
1087
- case 400:
1088
- // Oauth2.1 RFC 3.2.4
1089
- case 401:
1090
- return oauth2authorized(req, next);
1091
- break;
1092
- }
1093
- throw err;
1094
- }
1095
- if (!res.ok) {
1096
- switch (res.status) {
1097
- case 400:
1098
- // Oauth2.1 RFC 3.2.4
1099
- case 401:
1100
- return oauth2authorized(req, next);
1101
- break;
1102
- }
1016
+ const res = await next(req);
1017
+ if (res.ok || !shouldAuthorizeResponse(res)) {
1018
+ return res;
1103
1019
  }
1104
- return res;
1020
+ return oauth2authorized(req, next);
1105
1021
  };
1106
1022
  async function oauth2authorized(req, next) {
1107
1023
  getTokensFromLocation();
@@ -1109,23 +1025,15 @@
1109
1025
  const refreshToken = options.tokens.get("refresh_token");
1110
1026
  const tokenIsExpired = isExpired(accessToken);
1111
1027
  if (!accessToken || tokenIsExpired && !refreshToken) {
1112
- try {
1113
- let token = await fetchAccessToken();
1114
- if (!token) {
1115
- return response("false");
1116
- }
1117
- } catch (e) {
1118
- throw e;
1028
+ const token = await fetchAccessToken();
1029
+ if (!token) {
1030
+ return response("false");
1119
1031
  }
1120
1032
  return oauth2authorized(req, next);
1121
1033
  } else if (tokenIsExpired && refreshToken) {
1122
- try {
1123
- let token = await refreshAccessToken();
1124
- if (!token) {
1125
- return response("false");
1126
- }
1127
- } catch (e) {
1128
- throw e;
1034
+ const token = await refreshAccessToken();
1035
+ if (!token) {
1036
+ return response("false");
1129
1037
  }
1130
1038
  return oauth2authorized(req, next);
1131
1039
  } else {
@@ -1141,7 +1049,7 @@
1141
1049
  if (typeof window !== "undefined" && window?.location) {
1142
1050
  let url2 = url(window.location);
1143
1051
  let code, state, params;
1144
- if (url2.searchParams.has("code")) {
1052
+ if (url2.searchParams.has("code") || url2.searchParams.has("error")) {
1145
1053
  params = url2.searchParams;
1146
1054
  url2 = url2.with({ search: "" });
1147
1055
  history.pushState({}, "", url2.href);
@@ -1152,12 +1060,12 @@
1152
1060
  history.pushState({}, "", url2.href);
1153
1061
  }
1154
1062
  if (params) {
1063
+ if (params.has("error")) {
1064
+ throw metroError("oauth2mw: authorization failed: " + params.get("error") + (params.get("error_description") ? " (" + params.get("error_description") + ")" : ""));
1065
+ }
1155
1066
  code = params.get("code");
1156
1067
  state = params.get("state");
1157
- let storedState = options.state.get("metro/state");
1158
- if (!state || state !== storedState) {
1159
- return;
1160
- }
1068
+ validateState(state);
1161
1069
  if (code) {
1162
1070
  options.tokens.set("authorization_code", code);
1163
1071
  }
@@ -1165,14 +1073,14 @@
1165
1073
  }
1166
1074
  }
1167
1075
  async function fetchAccessToken() {
1168
- if (oauth22.grant_type === "authorization_code" && !options.tokens.has("authorization_code")) {
1076
+ if (oauth2.grant_type === "authorization_code" && !options.tokens.has("authorization_code")) {
1169
1077
  let authReqURL = await getAuthorizationCodeURL();
1170
1078
  if (!options.authorize_callback || typeof options.authorize_callback !== "function") {
1171
1079
  throw metroError("oauth2mw: oauth2 with grant_type:authorization_code requires a callback function in client options.authorize_callback");
1172
1080
  }
1173
- let token = await options.authorize_callback(authReqURL);
1174
- if (token) {
1175
- options.tokens.set("authorization_code", token);
1081
+ let authorization = await options.authorize_callback(authReqURL);
1082
+ if (authorization) {
1083
+ storeAuthorizationResult(authorization);
1176
1084
  } else {
1177
1085
  return false;
1178
1086
  }
@@ -1184,18 +1092,7 @@
1184
1092
  throw metroError("OAuth2mw: fetch access_token: " + response2.status + ": " + response2.statusText + " (" + msg + ")", { cause: tokenReq });
1185
1093
  }
1186
1094
  let data = await response2.json();
1187
- options.tokens.set("access_token", {
1188
- value: data.access_token,
1189
- expires: getExpires(data.expires_in),
1190
- type: data.token_type,
1191
- scope: data.scope
1192
- });
1193
- if (data.refresh_token) {
1194
- let token = {
1195
- value: data.refresh_token
1196
- };
1197
- options.tokens.set("refresh_token", token);
1198
- }
1095
+ storeTokenResponse(data);
1199
1096
  options.tokens.delete("authorization_code");
1200
1097
  return data;
1201
1098
  }
@@ -1203,88 +1100,72 @@
1203
1100
  let refreshTokenReq = getAccessTokenRequest("refresh_token");
1204
1101
  let response2 = await options.client.post(refreshTokenReq);
1205
1102
  if (!response2.ok) {
1206
- throw metroError("OAuth2mw: refresh access_token: " + response2.status + ": " + response2.statusText, { cause: refreshTokenReq });
1103
+ let msg = await response2.text();
1104
+ throw metroError("OAuth2mw: refresh access_token: " + response2.status + ": " + response2.statusText + " (" + msg + ")", { cause: refreshTokenReq });
1207
1105
  }
1208
1106
  let data = await response2.json();
1209
- options.tokens.set("access_token", {
1210
- value: data.access_token,
1211
- expires: getExpires(data.expires_in),
1212
- type: data.token_type,
1213
- scope: data.scope
1214
- });
1215
- if (data.refresh_token) {
1216
- let token = {
1217
- value: data.refresh_token
1218
- };
1219
- options.tokens.set("refresh_token", token);
1220
- } else {
1221
- return false;
1222
- }
1107
+ storeTokenResponse(data);
1223
1108
  return data;
1224
1109
  }
1225
1110
  async function getAuthorizationCodeURL() {
1226
- if (!oauth22.authorization_endpoint) {
1111
+ if (!oauth2.authorization_endpoint) {
1227
1112
  throw metroError("oauth2mw: Missing options.oauth2_configuration.authorization_endpoint");
1228
1113
  }
1229
- let url2 = url(oauth22.authorization_endpoint, { hash: "" });
1230
- assert(oauth22, {
1114
+ let url2 = url(oauth2.authorization_endpoint, { hash: "" });
1115
+ assert(oauth2, {
1231
1116
  client_id: /.+/,
1232
1117
  redirect_uri: /.+/,
1233
1118
  scope: /.*/
1234
1119
  });
1235
1120
  let search = {
1236
1121
  response_type: "code",
1237
- // implicit flow uses 'token' here, but is not considered safe, so not supported
1238
- client_id: oauth22.client_id,
1239
- redirect_uri: oauth22.redirect_uri,
1240
- state: oauth22.state || createState(40)
1241
- // OAuth2.1 RFC says optional, but its a good idea to always add/check it
1122
+ client_id: oauth2.client_id,
1123
+ redirect_uri: oauth2.redirect_uri,
1124
+ state: oauth2.state || createState(40)
1242
1125
  };
1243
- if (oauth22.response_type) {
1244
- search.response_type = oauth22.response_type;
1126
+ if (oauth2.response_type) {
1127
+ search.response_type = oauth2.response_type;
1245
1128
  }
1246
- if (oauth22.response_mode) {
1247
- search.response_mode = oauth22.response_mode;
1129
+ if (oauth2.response_mode) {
1130
+ search.response_mode = oauth2.response_mode;
1248
1131
  }
1249
1132
  options.state.set(search.state);
1250
- if (oauth22.client_secret) {
1251
- search.client_secret = oauth22.client_secret;
1252
- }
1253
- if (oauth22.code_verifier) {
1254
- options.tokens.set("code_verifier", oauth22.code_verifier);
1255
- search.code_challenge = await generateCodeChallenge(oauth22.code_verifier);
1133
+ if (oauth2.code_verifier) {
1134
+ options.tokens.set("code_verifier", oauth2.code_verifier);
1135
+ search.code_challenge = await generateCodeChallenge(oauth2.code_verifier);
1256
1136
  search.code_challenge_method = "S256";
1257
1137
  }
1258
- if (oauth22.scope) {
1259
- search.scope = oauth22.scope;
1138
+ if (oauth2.scope) {
1139
+ search.scope = oauth2.scope;
1140
+ }
1141
+ if (oauth2.prompt) {
1142
+ search.prompt = oauth2.prompt;
1260
1143
  }
1261
- if (oauth22.prompt) {
1262
- search.prompt = oauth22.prompt;
1144
+ if (oauth2.nonce) {
1145
+ search.nonce = oauth2.nonce;
1263
1146
  }
1264
1147
  return url(url2, { search });
1265
1148
  }
1266
1149
  function getAccessTokenRequest(grant_type = null) {
1267
- assert(oauth22, {
1150
+ assert(oauth2, {
1268
1151
  client_id: /.+/,
1269
1152
  redirect_uri: /.+/
1270
1153
  });
1271
- if (!oauth22.token_endpoint) {
1154
+ if (!oauth2.token_endpoint) {
1272
1155
  throw metroError("oauth2mw: Missing options.endpoints.token url");
1273
1156
  }
1274
- let url2 = url(oauth22.token_endpoint, { hash: "" });
1157
+ let url2 = url(oauth2.token_endpoint, { hash: "" });
1275
1158
  let params = {
1276
- grant_type: grant_type || oauth22.grant_type,
1277
- client_id: oauth22.client_id
1159
+ grant_type: grant_type || oauth2.grant_type
1278
1160
  };
1279
- if (oauth22.client_secret) {
1280
- params.client_secret = oauth22.client_secret;
1281
- }
1282
- if (oauth22.scope) {
1283
- params.scope = oauth22.scope;
1161
+ let headers = {};
1162
+ applyTokenEndpointAuthentication(params, headers);
1163
+ if (oauth2.scope) {
1164
+ params.scope = oauth2.scope;
1284
1165
  }
1285
1166
  switch (params.grant_type) {
1286
1167
  case "authorization_code":
1287
- params.redirect_uri = oauth22.redirect_uri;
1168
+ params.redirect_uri = oauth2.redirect_uri;
1288
1169
  params.code = options.tokens.get("authorization_code");
1289
1170
  const code_verifier = options.tokens.get("code_verifier");
1290
1171
  if (code_verifier) {
@@ -1294,24 +1175,146 @@
1294
1175
  case "client_credentials":
1295
1176
  break;
1296
1177
  case "refresh_token":
1297
- params.refresh_token = options.tokens.get("refresh_token");
1178
+ params.refresh_token = tokenValue(options.tokens.get("refresh_token"));
1298
1179
  break;
1299
1180
  default:
1300
- throw new Error("Unknown grant_type: ".oauth2.grant_type);
1181
+ throw new Error("Unknown grant_type: " + params.grant_type);
1301
1182
  break;
1302
1183
  }
1303
- return request(url2, { method: "POST", body: new URLSearchParams(params) });
1184
+ return request(url2, { method: "POST", headers, body: new URLSearchParams(params) });
1304
1185
  }
1305
- }
1306
- function isExpired(token) {
1307
- if (!token) {
1308
- return true;
1186
+ function applyTokenEndpointAuthentication(params, headers) {
1187
+ const method = tokenEndpointAuthMethod(oauth2);
1188
+ if (method === "none") {
1189
+ params.client_id = oauth2.client_id;
1190
+ return;
1191
+ }
1192
+ if (!oauth2.client_secret) {
1193
+ throw metroError("oauth2mw: token_endpoint_auth_method " + method + " requires oauth2_configuration.client_secret");
1194
+ }
1195
+ if (method === "client_secret_post") {
1196
+ params.client_id = oauth2.client_id;
1197
+ params.client_secret = oauth2.client_secret;
1198
+ return;
1199
+ }
1200
+ if (method === "client_secret_basic") {
1201
+ headers.Authorization = basicAuth(oauth2.client_id, oauth2.client_secret);
1202
+ return;
1203
+ }
1309
1204
  }
1310
- let expires = new Date(token.expires);
1311
- let now = /* @__PURE__ */ new Date();
1312
- return now.getTime() > expires.getTime();
1313
- }
1314
- function getExpires(duration) {
1205
+ function storeAuthorizationResult(authorization) {
1206
+ let code = authorization;
1207
+ if (authorization && typeof authorization === "object") {
1208
+ if (authorization.error) {
1209
+ throw metroError("oauth2mw: authorization failed: " + authorization.error);
1210
+ }
1211
+ validateState(authorization.state);
1212
+ code = authorization.authorization_code || authorization.code;
1213
+ }
1214
+ if (!code) {
1215
+ throw metroError("oauth2mw: authorization callback did not return an authorization code");
1216
+ }
1217
+ options.tokens.set("authorization_code", code);
1218
+ }
1219
+ function validateState(state) {
1220
+ let storedState = options.state.get();
1221
+ if (!state || state !== storedState) {
1222
+ throw metroError("oauth2mw: authorization state mismatch");
1223
+ }
1224
+ }
1225
+ function storeTokenResponse(data) {
1226
+ const token = validateTokenResponse(data);
1227
+ options.tokens.set("access_token", token);
1228
+ if (data.refresh_token) {
1229
+ options.tokens.set("refresh_token", { value: data.refresh_token });
1230
+ }
1231
+ }
1232
+ }
1233
+ function shouldAuthorizeResponse(res) {
1234
+ if (!res) {
1235
+ return false;
1236
+ }
1237
+ if (res.status === 400) {
1238
+ return true;
1239
+ }
1240
+ const challenge = parseBearerChallenge(res.headers?.get("WWW-Authenticate"));
1241
+ if (challenge?.error === "insufficient_scope") {
1242
+ return false;
1243
+ }
1244
+ return res.status === 401;
1245
+ }
1246
+ function normalizeInitialToken(name, token) {
1247
+ if (name === "access_token" && token && typeof token === "object") {
1248
+ return token;
1249
+ }
1250
+ if (name === "access_token") {
1251
+ return { value: token, type: "Bearer", expires: null };
1252
+ }
1253
+ if (name === "refresh_token" && token && typeof token === "object") {
1254
+ return token;
1255
+ }
1256
+ return token;
1257
+ }
1258
+ function validateTokenResponse(data) {
1259
+ if (!data || typeof data !== "object") {
1260
+ throw metroError("OAuth2mw: token endpoint did not return a JSON object");
1261
+ }
1262
+ if (!data.access_token) {
1263
+ throw metroError("OAuth2mw: token response did not include access_token");
1264
+ }
1265
+ if (!data.token_type) {
1266
+ throw metroError("OAuth2mw: token response did not include token_type");
1267
+ }
1268
+ const tokenType = normalizeTokenType(data.token_type);
1269
+ return {
1270
+ value: data.access_token,
1271
+ expires: data.expires_in === void 0 ? null : getExpires(data.expires_in),
1272
+ type: tokenType,
1273
+ scope: data.scope
1274
+ };
1275
+ }
1276
+ function normalizeTokenType(type) {
1277
+ const normalized = SUPPORTED_TOKEN_TYPES.get(String(type).toLowerCase());
1278
+ if (!normalized) {
1279
+ throw metroError("OAuth2mw: unsupported token_type " + type);
1280
+ }
1281
+ return normalized;
1282
+ }
1283
+ function tokenEndpointAuthMethod(oauth2) {
1284
+ const method = oauth2.token_endpoint_auth_method || (oauth2.client_secret ? "client_secret_post" : "none");
1285
+ if (!SUPPORTED_TOKEN_ENDPOINT_AUTH_METHODS.has(method)) {
1286
+ throw metroError("oauth2mw: unsupported token_endpoint_auth_method " + method);
1287
+ }
1288
+ return method;
1289
+ }
1290
+ function basicAuth(clientId, clientSecret) {
1291
+ const value = formEncode(clientId) + ":" + formEncode(clientSecret);
1292
+ return "Basic " + base64_encode(value);
1293
+ }
1294
+ function formEncode(value) {
1295
+ return encodeURIComponent(value).replace(/%20/g, "+");
1296
+ }
1297
+ function base64_encode(value) {
1298
+ if (typeof btoa === "function") {
1299
+ return btoa(value);
1300
+ }
1301
+ return Buffer.from(value, "binary").toString("base64");
1302
+ }
1303
+ function tokenValue(token) {
1304
+ return token && typeof token === "object" ? token.value : token;
1305
+ }
1306
+ function isExpired(token) {
1307
+ if (!token) {
1308
+ return true;
1309
+ }
1310
+ if (!token.expires) {
1311
+ return false;
1312
+ }
1313
+ let expires = new Date(token.expires);
1314
+ let now = /* @__PURE__ */ new Date();
1315
+ return now.getTime() > expires.getTime();
1316
+ }
1317
+ function getExpires(duration) {
1315
1318
  if (duration instanceof Date) {
1316
1319
  return new Date(duration.getTime());
1317
1320
  }
@@ -1328,8 +1331,8 @@
1328
1331
  return base64url_encode(code_verifier);
1329
1332
  }
1330
1333
  async function generateCodeChallenge(code_verifier) {
1331
- const encoder2 = new TextEncoder();
1332
- const data = encoder2.encode(code_verifier);
1334
+ const encoder3 = new TextEncoder();
1335
+ const data = encoder3.encode(code_verifier);
1333
1336
  const challenge = await globalThis.crypto.subtle.digest("SHA-256", data);
1334
1337
  return base64url_encode(challenge);
1335
1338
  }
@@ -1338,6 +1341,11 @@
1338
1341
  return btoa(byteString).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
1339
1342
  }
1340
1343
  function createState(length) {
1344
+ const bytes = new Uint8Array(Math.ceil(length * 3 / 4) + 1);
1345
+ if (globalThis.crypto?.getRandomValues) {
1346
+ globalThis.crypto.getRandomValues(bytes);
1347
+ return base64url_encode(bytes).slice(0, length);
1348
+ }
1341
1349
  const validChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
1342
1350
  let randomState = "";
1343
1351
  let counter = 0;
@@ -1361,330 +1369,31 @@
1361
1369
  }
1362
1370
  return true;
1363
1371
  }
1364
- function isAuthorized(tokens) {
1365
- if (typeof tokens == "string") {
1366
- tokens = tokenStore(tokens).tokens;
1372
+ function parseBearerChallenge(value) {
1373
+ if (!value || typeof value !== "string") {
1374
+ return null;
1367
1375
  }
1368
- let accessToken = tokens.get("access_token");
1369
- if (accessToken && !isExpired(accessToken)) {
1370
- return true;
1371
- }
1372
- let refreshToken = tokens.get("refresh_token");
1373
- if (refreshToken) {
1374
- return true;
1375
- }
1376
- return false;
1377
- }
1378
-
1379
- // node_modules/@muze-nl/metro-oauth2/src/oauth2.mockserver.mjs
1380
- var oauth2_mockserver_exports = {};
1381
- __export(oauth2_mockserver_exports, {
1382
- default: () => oauth2mockserver
1383
- });
1384
- var baseResponse = {
1385
- status: 200,
1386
- statusText: "OK",
1387
- headers: {
1388
- "Content-Type": "application/json"
1389
- }
1390
- };
1391
- var badRequest = (error3) => {
1392
- return {
1393
- status: 400,
1394
- statusText: "Bad Request",
1395
- headers: {
1396
- "Content-Type": "application/json"
1397
- },
1398
- body: JSON.stringify({
1399
- error: "invalid_request",
1400
- error_description: error3
1401
- })
1402
- };
1403
- };
1404
- var error2;
1405
- var pkce = {};
1406
- function oauth2mockserver(options = {}) {
1407
- const defaultOptions = {
1408
- "PKCE": false,
1409
- "DPoP": false
1410
- };
1411
- options = Object.assign({}, defaultOptions, options);
1412
- return async (req, next) => {
1413
- let url2 = everything_default.url(req.url);
1414
- switch (url2.pathname) {
1415
- case "/authorize/":
1416
- if (error2 = fails(url2.searchParams, {
1417
- response_type: "code",
1418
- client_id: "mockClientId",
1419
- state: Optional(/.*/)
1420
- })) {
1421
- return everything_default.response(badRequest(error2));
1422
- }
1423
- if (url2.searchParams.has("code_challenge")) {
1424
- if (!url2.searchParams.has("code_challenge_method")) {
1425
- return everything_default.response(badRequest("missing code_challenge_method"));
1426
- }
1427
- pkce.code_challenge = url2.searchParams.get("code_challenge");
1428
- pkce.code_challenge_method = url2.searchParams.get("code_challenge_method");
1429
- }
1430
- return everything_default.response(baseResponse, {
1431
- body: JSON.stringify({
1432
- code: "mockAuthorizeToken",
1433
- state: url2.searchParams.get("state")
1434
- })
1435
- });
1436
- break;
1437
- case "/token/":
1438
- if (req.data instanceof URLSearchParams) {
1439
- let body = {};
1440
- req.data.forEach((value, key) => body[key] = value);
1441
- req = req.with({ body });
1442
- }
1443
- if (error2 = fails(req, {
1444
- method: "POST",
1445
- data: {
1446
- grant_type: oneOf("refresh_token", "authorization_code")
1447
- }
1448
- })) {
1449
- return everything_default.response(badRequest(error2));
1450
- }
1451
- switch (req.data.grant_type) {
1452
- case "refresh_token":
1453
- if (error2 = fails(req.data, oneOf({
1454
- refresh_token: "mockRefreshToken",
1455
- client_id: "mockClientId",
1456
- client_secret: "mockClientSecret"
1457
- }, {
1458
- refresh_token: "mockRefreshToken",
1459
- client_id: "mockClientId",
1460
- code_verifier: /.+/
1461
- }))) {
1462
- return everything_default.response(badRequest(error2));
1463
- }
1464
- break;
1465
- case "access_token":
1466
- if (error2 = fails(req.data, oneOf({
1467
- client_id: "mockClientId",
1468
- client_secret: "mockClientSecret"
1469
- }, {
1470
- client_id: "mockClientId",
1471
- code_challenge: /.*/,
1472
- //FIXME: check that this matches code_verifier
1473
- code_challenge_method: "S256"
1474
- }))) {
1475
- return everything_default.response(badRequest(error2));
1476
- }
1477
- break;
1478
- }
1479
- return everything_default.response(baseResponse, {
1480
- body: JSON.stringify({
1481
- access_token: "mockAccessToken",
1482
- token_type: "mockExample",
1483
- expires_in: 3600,
1484
- refresh_token: "mockRefreshToken",
1485
- example_parameter: "mockExampleValue"
1486
- })
1487
- });
1488
- break;
1489
- case "/protected/":
1490
- let auth = req.headers.get("Authorization");
1491
- let [type, token] = auth ? auth.split(" ") : [];
1492
- if (!token || token !== "mockAccessToken") {
1493
- return everything_default.response({
1494
- status: 401,
1495
- statusText: "Forbidden",
1496
- body: "401 Forbidden"
1497
- });
1498
- }
1499
- return everything_default.response(baseResponse, {
1500
- body: JSON.stringify({
1501
- result: "Success"
1502
- })
1503
- });
1504
- break;
1505
- case "/public/":
1506
- return everything_default.response(baseResponse, {
1507
- body: JSON.stringify({
1508
- result: "Success"
1509
- })
1510
- });
1511
- break;
1512
- default:
1513
- return everything_default.response({
1514
- status: 404,
1515
- statusText: "not found",
1516
- body: "404 Not Found " + url2
1517
- });
1518
- break;
1519
- }
1520
- };
1521
- }
1522
-
1523
- // node_modules/@muze-nl/metro-oauth2/src/oauth2.discovery.mjs
1524
- var oauth2_discovery_exports = {};
1525
- __export(oauth2_discovery_exports, {
1526
- default: () => makeClient
1527
- });
1528
- var validAlgorithms = [
1529
- "HS256",
1530
- "HS384",
1531
- "HS512",
1532
- "RS256",
1533
- "RS384",
1534
- "RS512",
1535
- "ES256",
1536
- "ES384",
1537
- "ES512"
1538
- ];
1539
- var validAuthMethods = [
1540
- "client_secret_post",
1541
- "client_secret_base",
1542
- "client_secret_jwt",
1543
- "private_key_jwt"
1544
- ];
1545
- var oauth_authorization_server_metadata = {
1546
- issuer: Required(validURL),
1547
- authorization_endpoint: Required(validURL),
1548
- token_endpoint: Required(validURL),
1549
- jwks_uri: Optional(validURL),
1550
- registration_endpoint: Optional(validURL),
1551
- scopes_supported: Recommended([]),
1552
- response_types_supported: Required(anyOf("code", "token")),
1553
- response_modes_supported: Optional([]),
1554
- grant_types_supported: Optional([]),
1555
- token_endpoint_auth_methods_supported: Optional([]),
1556
- token_endpoint_auth_signing_alg_values_supported: Optional([]),
1557
- service_documentation: Optional(validURL),
1558
- ui_locales_supported: Optional([]),
1559
- op_policy_uri: Optional(validURL),
1560
- op_tos_uri: Optional(validURL),
1561
- revocation_endpoint: Optional(validURL),
1562
- revocation_endpoint_auth_methods_supported: Optional(validAuthMethods),
1563
- revocation_endpoint_auth_signing_alg_values_supported: Optional(validAlgorithms),
1564
- introspection_endpoint: Optional(validURL),
1565
- introspection_endpoint_auth_methods_supported: Optional(validAuthMethods),
1566
- introspection_endpoint_auth_signing_alg_values_supported: Optional(validAlgorithms),
1567
- code_challendge_methods_supported: Optional([])
1568
- };
1569
- function makeClient(options = {}) {
1570
- const defaultOptions = {
1571
- client: everything_default.client()
1572
- };
1573
- options = Object.assign({}, defaultOptions, options);
1574
- assert(options, {
1575
- issuer: Required(validURL)
1576
- });
1577
- const oauth_authorization_server_configuration = fetchWellknownOauthAuthorizationServer(options.issuer);
1578
- return options.client.with(options.issuer);
1579
- }
1580
- async function fetchWellknownOauthAuthorizationServer(issuer, client2) {
1581
- let res = client2.get(everything_default.url(issuer, ".wellknown/oauth_authorization_server"));
1582
- if (res.ok) {
1583
- assert(res.headers.get("Content-Type"), /application\/json.*/);
1584
- let configuration = await res.json();
1585
- assert(configuration, oauth_authorization_server_metadata);
1586
- return configuration;
1376
+ const trimmed = value.trim();
1377
+ const index = trimmed.search(/\s/);
1378
+ const scheme = index < 0 ? trimmed : trimmed.slice(0, index);
1379
+ const rest = index < 0 ? "" : trimmed.slice(index + 1);
1380
+ if (!["bearer", "dpop"].includes(scheme.toLowerCase())) {
1381
+ return null;
1587
1382
  }
1588
- throw everything_default.metroError("metro.oidcmw: Error while fetching " + issuer + ".wellknown/oauth_authorization_server", res);
1589
- }
1590
-
1591
- // node_modules/@muze-nl/metro-oauth2/src/oauth2.popup.mjs
1592
- function handleRedirect(origin = null) {
1593
- let success = false;
1594
- origin = origin || window.location.origin;
1595
- let params = new URLSearchParams(window.location.search);
1596
- if (!params.has("code") && window.location.hash) {
1597
- let query = window.location.hash.substr(1);
1598
- params = new URLSearchParams("?" + query);
1599
- }
1600
- let parent = window.parent !== window ? window.parent : window.opener;
1601
- if (!parent) {
1602
- console.error("No parent window found, cannot post authorization code (or error)");
1603
- } else {
1604
- if (params.has("code")) {
1605
- parent.postMessage({
1606
- authorization_code: params.get("code")
1607
- }, origin);
1608
- success = true;
1609
- } else if (params.has("error")) {
1610
- parent.postMessage({
1611
- error: params.get("error")
1612
- }, origin);
1613
- } else {
1614
- parent.postMessage({
1615
- error: "Could not find an authorization_code"
1616
- }, origin);
1383
+ const result = { scheme };
1384
+ const pattern = /([A-Za-z][A-Za-z0-9_-]*)=("(?:[^"\\]|\\.)*"|[^,\s]*)/g;
1385
+ let match;
1386
+ while (match = pattern.exec(rest)) {
1387
+ let value2 = match[2];
1388
+ if (value2.startsWith('"') && value2.endsWith('"')) {
1389
+ value2 = value2.slice(1, -1).replace(/\\"/g, '"');
1617
1390
  }
1391
+ result[match[1]] = value2;
1618
1392
  }
1619
- return success;
1620
- }
1621
- function authorizePopup(authorizationCodeURL) {
1622
- return new Promise((resolve, reject) => {
1623
- addEventListener("message", (event) => {
1624
- if (event.data.authorization_code) {
1625
- resolve(event.data.authorization_code);
1626
- } else if (event.data.error) {
1627
- reject(event.data.error);
1628
- } else {
1629
- reject("Unknown authorization error");
1630
- }
1631
- }, { once: true });
1632
- window.open(authorizationCodeURL);
1633
- });
1634
- }
1635
-
1636
- // node_modules/@muze-nl/metro-oauth2/src/keysstore.mjs
1637
- function keysStore() {
1638
- return new Promise((resolve, reject) => {
1639
- const request2 = globalThis.indexedDB.open("metro", 1);
1640
- request2.onupgradeneeded = () => request2.result.createObjectStore("keyPairs", { keyPath: "domain" });
1641
- request2.onerror = (event) => {
1642
- reject(event);
1643
- };
1644
- request2.onsuccess = (event) => {
1645
- const db = event.target.result;
1646
- resolve({
1647
- set: function(value, key) {
1648
- return new Promise((resolve2, reject2) => {
1649
- const tx = db.transaction("keyPairs", "readwrite", { durability: "strict" });
1650
- const objectStore = tx.objectStore("keyPairs");
1651
- tx.oncomplete = () => {
1652
- resolve2();
1653
- };
1654
- tx.onerror = reject2;
1655
- objectStore.put(value, key);
1656
- });
1657
- },
1658
- get: function(key) {
1659
- return new Promise((resolve2, reject2) => {
1660
- const tx = db.transaction("keyPairs", "readonly");
1661
- const objectStore = tx.objectStore("keyPairs");
1662
- const request3 = objectStore.get(key);
1663
- request3.onsuccess = () => {
1664
- resolve2(request3.result);
1665
- };
1666
- request3.onerror = reject2;
1667
- tx.onerror = reject2;
1668
- });
1669
- },
1670
- clear: function() {
1671
- return new Promise((resolve2, reject2) => {
1672
- const tx = db.transaction("keyPairs", "readwrite");
1673
- const objectStore = tx.objectStore("keyPairs");
1674
- const request3 = objectStore.clear();
1675
- request3.onsuccess = () => {
1676
- resolve2();
1677
- };
1678
- request3.onerror = reject2;
1679
- tx.onerror = reject2;
1680
- });
1681
- }
1682
- });
1683
- };
1684
- });
1393
+ return result;
1685
1394
  }
1686
1395
 
1687
- // node_modules/dpop/build/index.js
1396
+ // ../../node_modules/dpop/build/index.js
1688
1397
  var encoder = new TextEncoder();
1689
1398
  var decoder = new TextDecoder();
1690
1399
  function buf(input) {
@@ -1749,17 +1458,17 @@
1749
1458
  return encodeBase64Url(input);
1750
1459
  }
1751
1460
  var UnsupportedOperationError = class extends Error {
1752
- constructor(message) {
1461
+ constructor(message2) {
1753
1462
  var _a;
1754
- super(message !== null && message !== void 0 ? message : "operation not supported");
1463
+ super(message2 !== null && message2 !== void 0 ? message2 : "operation not supported");
1755
1464
  this.name = this.constructor.name;
1756
1465
  (_a = Error.captureStackTrace) === null || _a === void 0 ? void 0 : _a.call(Error, this, this.constructor);
1757
1466
  }
1758
1467
  };
1759
1468
  var OperationProcessingError = class extends Error {
1760
- constructor(message) {
1469
+ constructor(message2) {
1761
1470
  var _a;
1762
- super(message);
1471
+ super(message2);
1763
1472
  this.name = this.constructor.name;
1764
1473
  (_a = Error.captureStackTrace) === null || _a === void 0 ? void 0 : _a.call(Error, this, this.constructor);
1765
1474
  }
@@ -1893,7 +1602,58 @@
1893
1602
  return crypto.subtle.generateKey(algorithm, (_a = options === null || options === void 0 ? void 0 : options.extractable) !== null && _a !== void 0 ? _a : false, ["sign", "verify"]);
1894
1603
  }
1895
1604
 
1896
- // node_modules/@muze-nl/metro-oauth2/src/oauth2.dpop.mjs
1605
+ // ../metro-oauth2/src/keysstore.mjs
1606
+ function keysStore() {
1607
+ return new Promise((resolve, reject) => {
1608
+ const request2 = globalThis.indexedDB.open("metro", 1);
1609
+ request2.onupgradeneeded = () => request2.result.createObjectStore("keyPairs", { keyPath: "domain" });
1610
+ request2.onerror = (event) => {
1611
+ reject(event);
1612
+ };
1613
+ request2.onsuccess = (event) => {
1614
+ const db = event.target.result;
1615
+ resolve({
1616
+ set: function(value, key) {
1617
+ return new Promise((resolve2, reject2) => {
1618
+ const tx = db.transaction("keyPairs", "readwrite", { durability: "strict" });
1619
+ const objectStore = tx.objectStore("keyPairs");
1620
+ tx.oncomplete = () => {
1621
+ resolve2();
1622
+ };
1623
+ tx.onerror = reject2;
1624
+ objectStore.put(value, key);
1625
+ });
1626
+ },
1627
+ get: function(key) {
1628
+ return new Promise((resolve2, reject2) => {
1629
+ const tx = db.transaction("keyPairs", "readonly");
1630
+ const objectStore = tx.objectStore("keyPairs");
1631
+ const request3 = objectStore.get(key);
1632
+ request3.onsuccess = () => {
1633
+ resolve2(request3.result);
1634
+ };
1635
+ request3.onerror = reject2;
1636
+ tx.onerror = reject2;
1637
+ });
1638
+ },
1639
+ clear: function() {
1640
+ return new Promise((resolve2, reject2) => {
1641
+ const tx = db.transaction("keyPairs", "readwrite");
1642
+ const objectStore = tx.objectStore("keyPairs");
1643
+ const request3 = objectStore.clear();
1644
+ request3.onsuccess = () => {
1645
+ resolve2();
1646
+ };
1647
+ request3.onerror = reject2;
1648
+ tx.onerror = reject2;
1649
+ });
1650
+ }
1651
+ });
1652
+ };
1653
+ });
1654
+ }
1655
+
1656
+ // ../metro-oauth2/src/oauth2.dpop.mjs
1897
1657
  function dpopmw(options) {
1898
1658
  assert(options, {
1899
1659
  site: Required(validURL),
@@ -1910,7 +1670,7 @@
1910
1670
  keyInfo = { domain: options.site, keyPair };
1911
1671
  await keys.set(keyInfo);
1912
1672
  }
1913
- const url2 = everything_default.url(req.url);
1673
+ const url2 = url(req.url);
1914
1674
  if (req.url.startsWith(options.authorization_endpoint)) {
1915
1675
  let params = req.body;
1916
1676
  if (params instanceof URLSearchParams || params instanceof FormData) {
@@ -1944,47 +1704,106 @@
1944
1704
  };
1945
1705
  }
1946
1706
 
1947
- // node_modules/@muze-nl/metro-oauth2/src/browser.mjs
1948
- var oauth2 = Object.assign({}, oauth2_exports, {
1949
- oauth2mw,
1950
- mockserver: oauth2_mockserver_exports,
1951
- discover: oauth2_discovery_exports,
1952
- tokenstore: tokenStore,
1953
- dpopmw,
1954
- keysstore: keysStore,
1955
- authorizePopup,
1956
- popupHandleRedirect: handleRedirect
1957
- });
1958
- if (!globalThis.metro.oauth2) {
1959
- globalThis.metro.oauth2 = oauth2;
1960
- }
1961
-
1962
- // src/oidc.util.mjs
1963
- var MustHave = (...options) => (value, root) => {
1964
- if (options.filter((o) => root.hasOwnKey(o)).length > 0) {
1965
- return false;
1966
- }
1967
- return error("root data must have all of", root, options);
1968
- };
1969
- var MustInclude = (...options) => (value) => {
1970
- if (Array.isArray(value) && options.filter((o) => !value.includes(o)).length == 0) {
1971
- return false;
1972
- } else {
1973
- return error("data must be an array which includes", value, options);
1974
- }
1975
- };
1976
- var validJWA = [
1977
- "HS256",
1978
- "HS384",
1979
- "HS512",
1980
- "RS256",
1981
- "RS384",
1982
- "RS512",
1983
- "ES256",
1984
- "ES384",
1985
- "ES512"
1707
+ // ../metro-middleware/src/json.mjs
1708
+ function jsonmw(options) {
1709
+ options = Object.assign({
1710
+ contentType: "application/json",
1711
+ reviver: null,
1712
+ replacer: null,
1713
+ space: ""
1714
+ }, options);
1715
+ return async function json(req, next) {
1716
+ if (!req.headers.get("Accept")) {
1717
+ req = req.with({
1718
+ headers: {
1719
+ "Accept": options.accept ?? options.contentType
1720
+ }
1721
+ });
1722
+ }
1723
+ if (req.method !== "GET" && req.method !== "HEAD") {
1724
+ if (req.data && typeof req.data == "object" && !(req.data instanceof ReadableStream)) {
1725
+ const contentType = req.headers.get("Content-Type");
1726
+ if (!contentType || isPlainText(contentType)) {
1727
+ req = req.with({
1728
+ headers: {
1729
+ "Content-Type": options.contentType
1730
+ }
1731
+ });
1732
+ }
1733
+ if (isJSON(req.headers.get("Content-Type"))) {
1734
+ req = req.with({
1735
+ body: JSON.stringify(req.data, options.replacer, options.space)
1736
+ });
1737
+ }
1738
+ }
1739
+ }
1740
+ let res = await next(req);
1741
+ if (res && isJSON(res.headers?.get("Content-Type"))) {
1742
+ let tempRes = res.clone();
1743
+ let body = await tempRes.text();
1744
+ try {
1745
+ let json2 = JSON.parse(body, options.reviver);
1746
+ return res.with({
1747
+ body: json2
1748
+ });
1749
+ } catch (e) {
1750
+ }
1751
+ }
1752
+ return res;
1753
+ };
1754
+ }
1755
+ var jsonRE = /^application\/([a-zA-Z0-9\-_]+\+)?json\b/;
1756
+ function isJSON(contentType) {
1757
+ return jsonRE.exec(contentType);
1758
+ }
1759
+ function isPlainText(contentType) {
1760
+ return /^text\/plain\b/.exec(contentType);
1761
+ }
1762
+
1763
+ // ../metro-middleware/src/thrower.mjs
1764
+ function throwermw(options) {
1765
+ return async function thrower(req, next) {
1766
+ let res = await next(req);
1767
+ if (!res.ok) {
1768
+ if (options && typeof options[res.status] == "function") {
1769
+ res = options[res.status].apply(res, req);
1770
+ } else {
1771
+ throw new Error(res.status + ": " + res.statusText, {
1772
+ cause: res
1773
+ });
1774
+ }
1775
+ }
1776
+ return res;
1777
+ };
1778
+ }
1779
+
1780
+ // src/oidc.util.mjs
1781
+ var MustHave = (...options) => (value, root) => {
1782
+ if (options.filter((o) => root.hasOwnKey(o)).length > 0) {
1783
+ return false;
1784
+ }
1785
+ return error("root data must have all of", root, options);
1786
+ };
1787
+ var MustInclude = (...options) => (value) => {
1788
+ if (Array.isArray(value) && options.filter((o) => !value.includes(o)).length == 0) {
1789
+ return false;
1790
+ } else {
1791
+ return error("data must be an array which includes", value, options);
1792
+ }
1793
+ };
1794
+ var validJWA = [
1795
+ "HS256",
1796
+ "HS384",
1797
+ "HS512",
1798
+ "RS256",
1799
+ "RS384",
1800
+ "RS512",
1801
+ "ES256",
1802
+ "ES384",
1803
+ "ES512"
1986
1804
  ];
1987
- var validAuthMethods2 = [
1805
+ var validAuthMethods = [
1806
+ "none",
1988
1807
  "client_secret_post",
1989
1808
  "client_secret_basic",
1990
1809
  "client_secret_jwt",
@@ -1994,14 +1813,15 @@
1994
1813
  // src/oidc.discovery.mjs
1995
1814
  async function oidcDiscovery(options = {}) {
1996
1815
  assert(options, {
1997
- client: Optional(instanceOf(everything_default.client().constructor)),
1816
+ client: Optional(instanceOf(client().constructor)),
1998
1817
  issuer: Required(validURL)
1999
1818
  });
2000
1819
  const defaultOptions = {
2001
- client: everything_default.client().with(throwermw()).with(jsonmw()),
1820
+ client: client().with(throwermw()).with(jsonmw()),
2002
1821
  requireDynamicRegistration: false
2003
1822
  };
2004
1823
  options = Object.assign({}, defaultOptions, options);
1824
+ options.client = options.client.with(throwermw()).with(jsonmw());
2005
1825
  const TestSucceeded = false;
2006
1826
  function MustUseHTTPS(url2) {
2007
1827
  return TestSucceeded;
@@ -2030,7 +1850,7 @@
2030
1850
  // not testing for 'none'
2031
1851
  request_object_encryption_alg_values_supported: Optional([]),
2032
1852
  request_object_encryption_enc_values_supported: Optional([]),
2033
- token_endpoint_auth_methods_supported: Optional(anyOf(...validAuthMethods2)),
1853
+ token_endpoint_auth_methods_supported: Optional(anyOf(...validAuthMethods)),
2034
1854
  token_endpoint_auth_signing_alg_values_supported: Optional(MustInclude("RS256"), not(MustInclude("none"))),
2035
1855
  display_values_supported: Optional(anyOf("page", "popup", "touch", "wap")),
2036
1856
  claim_types_supported: Optional(anyOf("normal", "aggregated", "distributed")),
@@ -2044,7 +1864,7 @@
2044
1864
  op_policy_uri: Optional(validURL),
2045
1865
  op_tos_uri: Optional(validURL)
2046
1866
  };
2047
- const configURL = everything_default.url(options.issuer, ".well-known/openid-configuration");
1867
+ const configURL = url(options.issuer, ".well-known/openid-configuration");
2048
1868
  const response2 = await options.client.get(
2049
1869
  // https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationRequest
2050
1870
  // note: this allows path components in the options.issuer url
@@ -2083,7 +1903,7 @@
2083
1903
  request_object_signing_alg: Optional(oneOf(...validJWA)),
2084
1904
  request_object_encryption_alg: Optional(oneOf(...validJWA)),
2085
1905
  request_object_encryption_enc: Optional(oneOf(...validJWA)),
2086
- token_endpoint_auth_method: Optional(oneOf(...validAuthMethods2)),
1906
+ token_endpoint_auth_method: Optional(oneOf(...validAuthMethods)),
2087
1907
  token_endpoint_auth_signing_alg: Optional(oneOf(...validJWA)),
2088
1908
  default_max_age: Optional(Number),
2089
1909
  require_auth_time: Optional(Boolean),
@@ -2092,17 +1912,18 @@
2092
1912
  request_uris: Optional([validURL])
2093
1913
  };
2094
1914
  assert(options, {
2095
- client: Optional(instanceOf(everything_default.client().constructor)),
1915
+ client: Optional(instanceOf(client().constructor)),
2096
1916
  registration_endpoint: validURL,
2097
1917
  client_info: openid_client_metadata
2098
1918
  });
2099
1919
  const defaultOptions = {
2100
- client: everything_default.client().with(throwermw()).with(jsonmw()),
1920
+ client: client().with(throwermw()).with(jsonmw()),
2101
1921
  client_info: {
2102
1922
  redirect_uris: [globalThis.document?.location.href]
2103
1923
  }
2104
1924
  };
2105
1925
  options = Object.assign({}, defaultOptions, options);
1926
+ options.client = options.client.with(throwermw()).with(jsonmw());
2106
1927
  if (!options.client_info) {
2107
1928
  options.client_info = {};
2108
1929
  }
@@ -2113,8 +1934,8 @@
2113
1934
  body: options.client_info
2114
1935
  });
2115
1936
  let info = response2.data;
2116
- if (!info.client_id || !info.client_secret) {
2117
- throw everything_default.metroError("metro.oidc: Error: dynamic registration of client failed, no client_id or client_secret returned", response2);
1937
+ if (!info.client_id) {
1938
+ throw metroError("metro.oidc: Error: dynamic registration of client failed, no client_id returned", response2);
2118
1939
  }
2119
1940
  options.client_info = Object.assign(options.client_info, info);
2120
1941
  return options.client_info;
@@ -2140,6 +1961,1292 @@
2140
1961
  return store;
2141
1962
  }
2142
1963
 
1964
+ // ../../node_modules/jose/dist/webapi/lib/buffer_utils.js
1965
+ var encoder2 = new TextEncoder();
1966
+ var decoder2 = new TextDecoder();
1967
+ var MAX_INT32 = 2 ** 32;
1968
+ function concat(...buffers) {
1969
+ const size = buffers.reduce((acc, { length }) => acc + length, 0);
1970
+ const buf2 = new Uint8Array(size);
1971
+ let i = 0;
1972
+ for (const buffer of buffers) {
1973
+ buf2.set(buffer, i);
1974
+ i += buffer.length;
1975
+ }
1976
+ return buf2;
1977
+ }
1978
+ function encode(string) {
1979
+ const bytes = new Uint8Array(string.length);
1980
+ for (let i = 0; i < string.length; i++) {
1981
+ const code = string.charCodeAt(i);
1982
+ if (code > 127) {
1983
+ throw new TypeError("non-ASCII string encountered in encode()");
1984
+ }
1985
+ bytes[i] = code;
1986
+ }
1987
+ return bytes;
1988
+ }
1989
+
1990
+ // ../../node_modules/jose/dist/webapi/lib/base64.js
1991
+ function decodeBase64(encoded) {
1992
+ if (Uint8Array.fromBase64) {
1993
+ return Uint8Array.fromBase64(encoded);
1994
+ }
1995
+ const binary = atob(encoded);
1996
+ const bytes = new Uint8Array(binary.length);
1997
+ for (let i = 0; i < binary.length; i++) {
1998
+ bytes[i] = binary.charCodeAt(i);
1999
+ }
2000
+ return bytes;
2001
+ }
2002
+
2003
+ // ../../node_modules/jose/dist/webapi/util/base64url.js
2004
+ function decode(input) {
2005
+ if (Uint8Array.fromBase64) {
2006
+ return Uint8Array.fromBase64(typeof input === "string" ? input : decoder2.decode(input), {
2007
+ alphabet: "base64url"
2008
+ });
2009
+ }
2010
+ let encoded = input;
2011
+ if (encoded instanceof Uint8Array) {
2012
+ encoded = decoder2.decode(encoded);
2013
+ }
2014
+ encoded = encoded.replace(/-/g, "+").replace(/_/g, "/");
2015
+ try {
2016
+ return decodeBase64(encoded);
2017
+ } catch {
2018
+ throw new TypeError("The input to be decoded is not correctly encoded.");
2019
+ }
2020
+ }
2021
+
2022
+ // ../../node_modules/jose/dist/webapi/lib/crypto_key.js
2023
+ var unusable = (name, prop = "algorithm.name") => new TypeError(`CryptoKey does not support this operation, its ${prop} must be ${name}`);
2024
+ var isAlgorithm = (algorithm, name) => algorithm.name === name;
2025
+ function getHashLength(hash) {
2026
+ return parseInt(hash.name.slice(4), 10);
2027
+ }
2028
+ function checkHashLength(algorithm, expected) {
2029
+ const actual = getHashLength(algorithm.hash);
2030
+ if (actual !== expected)
2031
+ throw unusable(`SHA-${expected}`, "algorithm.hash");
2032
+ }
2033
+ function getNamedCurve(alg) {
2034
+ switch (alg) {
2035
+ case "ES256":
2036
+ return "P-256";
2037
+ case "ES384":
2038
+ return "P-384";
2039
+ case "ES512":
2040
+ return "P-521";
2041
+ default:
2042
+ throw new Error("unreachable");
2043
+ }
2044
+ }
2045
+ function checkUsage(key, usage) {
2046
+ if (usage && !key.usages.includes(usage)) {
2047
+ throw new TypeError(`CryptoKey does not support this operation, its usages must include ${usage}.`);
2048
+ }
2049
+ }
2050
+ function checkSigCryptoKey(key, alg, usage) {
2051
+ switch (alg) {
2052
+ case "HS256":
2053
+ case "HS384":
2054
+ case "HS512": {
2055
+ if (!isAlgorithm(key.algorithm, "HMAC"))
2056
+ throw unusable("HMAC");
2057
+ checkHashLength(key.algorithm, parseInt(alg.slice(2), 10));
2058
+ break;
2059
+ }
2060
+ case "RS256":
2061
+ case "RS384":
2062
+ case "RS512": {
2063
+ if (!isAlgorithm(key.algorithm, "RSASSA-PKCS1-v1_5"))
2064
+ throw unusable("RSASSA-PKCS1-v1_5");
2065
+ checkHashLength(key.algorithm, parseInt(alg.slice(2), 10));
2066
+ break;
2067
+ }
2068
+ case "PS256":
2069
+ case "PS384":
2070
+ case "PS512": {
2071
+ if (!isAlgorithm(key.algorithm, "RSA-PSS"))
2072
+ throw unusable("RSA-PSS");
2073
+ checkHashLength(key.algorithm, parseInt(alg.slice(2), 10));
2074
+ break;
2075
+ }
2076
+ case "Ed25519":
2077
+ case "EdDSA": {
2078
+ if (!isAlgorithm(key.algorithm, "Ed25519"))
2079
+ throw unusable("Ed25519");
2080
+ break;
2081
+ }
2082
+ case "ML-DSA-44":
2083
+ case "ML-DSA-65":
2084
+ case "ML-DSA-87": {
2085
+ if (!isAlgorithm(key.algorithm, alg))
2086
+ throw unusable(alg);
2087
+ break;
2088
+ }
2089
+ case "ES256":
2090
+ case "ES384":
2091
+ case "ES512": {
2092
+ if (!isAlgorithm(key.algorithm, "ECDSA"))
2093
+ throw unusable("ECDSA");
2094
+ const expected = getNamedCurve(alg);
2095
+ const actual = key.algorithm.namedCurve;
2096
+ if (actual !== expected)
2097
+ throw unusable(expected, "algorithm.namedCurve");
2098
+ break;
2099
+ }
2100
+ default:
2101
+ throw new TypeError("CryptoKey does not support this operation");
2102
+ }
2103
+ checkUsage(key, usage);
2104
+ }
2105
+
2106
+ // ../../node_modules/jose/dist/webapi/lib/invalid_key_input.js
2107
+ function message(msg, actual, ...types) {
2108
+ types = types.filter(Boolean);
2109
+ if (types.length > 2) {
2110
+ const last = types.pop();
2111
+ msg += `one of type ${types.join(", ")}, or ${last}.`;
2112
+ } else if (types.length === 2) {
2113
+ msg += `one of type ${types[0]} or ${types[1]}.`;
2114
+ } else {
2115
+ msg += `of type ${types[0]}.`;
2116
+ }
2117
+ if (actual == null) {
2118
+ msg += ` Received ${actual}`;
2119
+ } else if (typeof actual === "function" && actual.name) {
2120
+ msg += ` Received function ${actual.name}`;
2121
+ } else if (typeof actual === "object" && actual != null) {
2122
+ if (actual.constructor?.name) {
2123
+ msg += ` Received an instance of ${actual.constructor.name}`;
2124
+ }
2125
+ }
2126
+ return msg;
2127
+ }
2128
+ var invalidKeyInput = (actual, ...types) => message("Key must be ", actual, ...types);
2129
+ var withAlg = (alg, actual, ...types) => message(`Key for the ${alg} algorithm must be `, actual, ...types);
2130
+
2131
+ // ../../node_modules/jose/dist/webapi/util/errors.js
2132
+ var JOSEError = class extends Error {
2133
+ static code = "ERR_JOSE_GENERIC";
2134
+ code = "ERR_JOSE_GENERIC";
2135
+ constructor(message2, options) {
2136
+ super(message2, options);
2137
+ this.name = this.constructor.name;
2138
+ Error.captureStackTrace?.(this, this.constructor);
2139
+ }
2140
+ };
2141
+ var JWTClaimValidationFailed = class extends JOSEError {
2142
+ static code = "ERR_JWT_CLAIM_VALIDATION_FAILED";
2143
+ code = "ERR_JWT_CLAIM_VALIDATION_FAILED";
2144
+ claim;
2145
+ reason;
2146
+ payload;
2147
+ constructor(message2, payload, claim = "unspecified", reason = "unspecified") {
2148
+ super(message2, { cause: { claim, reason, payload } });
2149
+ this.claim = claim;
2150
+ this.reason = reason;
2151
+ this.payload = payload;
2152
+ }
2153
+ };
2154
+ var JWTExpired = class extends JOSEError {
2155
+ static code = "ERR_JWT_EXPIRED";
2156
+ code = "ERR_JWT_EXPIRED";
2157
+ claim;
2158
+ reason;
2159
+ payload;
2160
+ constructor(message2, payload, claim = "unspecified", reason = "unspecified") {
2161
+ super(message2, { cause: { claim, reason, payload } });
2162
+ this.claim = claim;
2163
+ this.reason = reason;
2164
+ this.payload = payload;
2165
+ }
2166
+ };
2167
+ var JOSEAlgNotAllowed = class extends JOSEError {
2168
+ static code = "ERR_JOSE_ALG_NOT_ALLOWED";
2169
+ code = "ERR_JOSE_ALG_NOT_ALLOWED";
2170
+ };
2171
+ var JOSENotSupported = class extends JOSEError {
2172
+ static code = "ERR_JOSE_NOT_SUPPORTED";
2173
+ code = "ERR_JOSE_NOT_SUPPORTED";
2174
+ };
2175
+ var JWSInvalid = class extends JOSEError {
2176
+ static code = "ERR_JWS_INVALID";
2177
+ code = "ERR_JWS_INVALID";
2178
+ };
2179
+ var JWTInvalid = class extends JOSEError {
2180
+ static code = "ERR_JWT_INVALID";
2181
+ code = "ERR_JWT_INVALID";
2182
+ };
2183
+ var JWKSInvalid = class extends JOSEError {
2184
+ static code = "ERR_JWKS_INVALID";
2185
+ code = "ERR_JWKS_INVALID";
2186
+ };
2187
+ var JWKSNoMatchingKey = class extends JOSEError {
2188
+ static code = "ERR_JWKS_NO_MATCHING_KEY";
2189
+ code = "ERR_JWKS_NO_MATCHING_KEY";
2190
+ constructor(message2 = "no applicable key found in the JSON Web Key Set", options) {
2191
+ super(message2, options);
2192
+ }
2193
+ };
2194
+ var JWKSMultipleMatchingKeys = class extends JOSEError {
2195
+ [Symbol.asyncIterator];
2196
+ static code = "ERR_JWKS_MULTIPLE_MATCHING_KEYS";
2197
+ code = "ERR_JWKS_MULTIPLE_MATCHING_KEYS";
2198
+ constructor(message2 = "multiple matching keys found in the JSON Web Key Set", options) {
2199
+ super(message2, options);
2200
+ }
2201
+ };
2202
+ var JWSSignatureVerificationFailed = class extends JOSEError {
2203
+ static code = "ERR_JWS_SIGNATURE_VERIFICATION_FAILED";
2204
+ code = "ERR_JWS_SIGNATURE_VERIFICATION_FAILED";
2205
+ constructor(message2 = "signature verification failed", options) {
2206
+ super(message2, options);
2207
+ }
2208
+ };
2209
+
2210
+ // ../../node_modules/jose/dist/webapi/lib/is_key_like.js
2211
+ var isCryptoKey2 = (key) => {
2212
+ if (key?.[Symbol.toStringTag] === "CryptoKey")
2213
+ return true;
2214
+ try {
2215
+ return key instanceof CryptoKey;
2216
+ } catch {
2217
+ return false;
2218
+ }
2219
+ };
2220
+ var isKeyObject = (key) => key?.[Symbol.toStringTag] === "KeyObject";
2221
+ var isKeyLike = (key) => isCryptoKey2(key) || isKeyObject(key);
2222
+
2223
+ // ../../node_modules/jose/dist/webapi/lib/helpers.js
2224
+ function decodeBase64url(value, label, ErrorClass) {
2225
+ try {
2226
+ return decode(value);
2227
+ } catch {
2228
+ throw new ErrorClass(`Failed to base64url decode the ${label}`);
2229
+ }
2230
+ }
2231
+
2232
+ // ../../node_modules/jose/dist/webapi/lib/type_checks.js
2233
+ var isObjectLike = (value) => typeof value === "object" && value !== null;
2234
+ function isObject(input) {
2235
+ if (!isObjectLike(input) || Object.prototype.toString.call(input) !== "[object Object]") {
2236
+ return false;
2237
+ }
2238
+ if (Object.getPrototypeOf(input) === null) {
2239
+ return true;
2240
+ }
2241
+ let proto = input;
2242
+ while (Object.getPrototypeOf(proto) !== null) {
2243
+ proto = Object.getPrototypeOf(proto);
2244
+ }
2245
+ return Object.getPrototypeOf(input) === proto;
2246
+ }
2247
+ function isDisjoint(...headers) {
2248
+ const sources = headers.filter(Boolean);
2249
+ if (sources.length === 0 || sources.length === 1) {
2250
+ return true;
2251
+ }
2252
+ let acc;
2253
+ for (const header of sources) {
2254
+ const parameters = Object.keys(header);
2255
+ if (!acc || acc.size === 0) {
2256
+ acc = new Set(parameters);
2257
+ continue;
2258
+ }
2259
+ for (const parameter of parameters) {
2260
+ if (acc.has(parameter)) {
2261
+ return false;
2262
+ }
2263
+ acc.add(parameter);
2264
+ }
2265
+ }
2266
+ return true;
2267
+ }
2268
+ var isJWK = (key) => isObject(key) && typeof key.kty === "string";
2269
+ var isPrivateJWK = (key) => key.kty !== "oct" && (key.kty === "AKP" && typeof key.priv === "string" || typeof key.d === "string");
2270
+ var isPublicJWK = (key) => key.kty !== "oct" && key.d === void 0 && key.priv === void 0;
2271
+ var isSecretJWK = (key) => key.kty === "oct" && typeof key.k === "string";
2272
+
2273
+ // ../../node_modules/jose/dist/webapi/lib/signing.js
2274
+ function checkKeyLength(alg, key) {
2275
+ if (alg.startsWith("RS") || alg.startsWith("PS")) {
2276
+ const { modulusLength } = key.algorithm;
2277
+ if (typeof modulusLength !== "number" || modulusLength < 2048) {
2278
+ throw new TypeError(`${alg} requires key modulusLength to be 2048 bits or larger`);
2279
+ }
2280
+ }
2281
+ }
2282
+ function subtleAlgorithm2(alg, algorithm) {
2283
+ const hash = `SHA-${alg.slice(-3)}`;
2284
+ switch (alg) {
2285
+ case "HS256":
2286
+ case "HS384":
2287
+ case "HS512":
2288
+ return { hash, name: "HMAC" };
2289
+ case "PS256":
2290
+ case "PS384":
2291
+ case "PS512":
2292
+ return { hash, name: "RSA-PSS", saltLength: parseInt(alg.slice(-3), 10) >> 3 };
2293
+ case "RS256":
2294
+ case "RS384":
2295
+ case "RS512":
2296
+ return { hash, name: "RSASSA-PKCS1-v1_5" };
2297
+ case "ES256":
2298
+ case "ES384":
2299
+ case "ES512":
2300
+ return { hash, name: "ECDSA", namedCurve: algorithm.namedCurve };
2301
+ case "Ed25519":
2302
+ case "EdDSA":
2303
+ return { name: "Ed25519" };
2304
+ case "ML-DSA-44":
2305
+ case "ML-DSA-65":
2306
+ case "ML-DSA-87":
2307
+ return { name: alg };
2308
+ default:
2309
+ throw new JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`);
2310
+ }
2311
+ }
2312
+ async function getSigKey(alg, key, usage) {
2313
+ if (key instanceof Uint8Array) {
2314
+ if (!alg.startsWith("HS")) {
2315
+ throw new TypeError(invalidKeyInput(key, "CryptoKey", "KeyObject", "JSON Web Key"));
2316
+ }
2317
+ return crypto.subtle.importKey("raw", key, { hash: `SHA-${alg.slice(-3)}`, name: "HMAC" }, false, [usage]);
2318
+ }
2319
+ checkSigCryptoKey(key, alg, usage);
2320
+ return key;
2321
+ }
2322
+ async function verify(alg, key, signature, data) {
2323
+ const cryptoKey = await getSigKey(alg, key, "verify");
2324
+ checkKeyLength(alg, cryptoKey);
2325
+ const algorithm = subtleAlgorithm2(alg, cryptoKey.algorithm);
2326
+ try {
2327
+ return await crypto.subtle.verify(algorithm, cryptoKey, signature, data);
2328
+ } catch {
2329
+ return false;
2330
+ }
2331
+ }
2332
+
2333
+ // ../../node_modules/jose/dist/webapi/lib/jwk_to_key.js
2334
+ var unsupportedAlg = 'Invalid or unsupported JWK "alg" (Algorithm) Parameter value';
2335
+ function subtleMapping(jwk) {
2336
+ let algorithm;
2337
+ let keyUsages;
2338
+ switch (jwk.kty) {
2339
+ case "AKP": {
2340
+ switch (jwk.alg) {
2341
+ case "ML-DSA-44":
2342
+ case "ML-DSA-65":
2343
+ case "ML-DSA-87":
2344
+ algorithm = { name: jwk.alg };
2345
+ keyUsages = jwk.priv ? ["sign"] : ["verify"];
2346
+ break;
2347
+ default:
2348
+ throw new JOSENotSupported(unsupportedAlg);
2349
+ }
2350
+ break;
2351
+ }
2352
+ case "RSA": {
2353
+ switch (jwk.alg) {
2354
+ case "PS256":
2355
+ case "PS384":
2356
+ case "PS512":
2357
+ algorithm = { name: "RSA-PSS", hash: `SHA-${jwk.alg.slice(-3)}` };
2358
+ keyUsages = jwk.d ? ["sign"] : ["verify"];
2359
+ break;
2360
+ case "RS256":
2361
+ case "RS384":
2362
+ case "RS512":
2363
+ algorithm = { name: "RSASSA-PKCS1-v1_5", hash: `SHA-${jwk.alg.slice(-3)}` };
2364
+ keyUsages = jwk.d ? ["sign"] : ["verify"];
2365
+ break;
2366
+ case "RSA-OAEP":
2367
+ case "RSA-OAEP-256":
2368
+ case "RSA-OAEP-384":
2369
+ case "RSA-OAEP-512":
2370
+ algorithm = {
2371
+ name: "RSA-OAEP",
2372
+ hash: `SHA-${parseInt(jwk.alg.slice(-3), 10) || 1}`
2373
+ };
2374
+ keyUsages = jwk.d ? ["decrypt", "unwrapKey"] : ["encrypt", "wrapKey"];
2375
+ break;
2376
+ default:
2377
+ throw new JOSENotSupported(unsupportedAlg);
2378
+ }
2379
+ break;
2380
+ }
2381
+ case "EC": {
2382
+ switch (jwk.alg) {
2383
+ case "ES256":
2384
+ case "ES384":
2385
+ case "ES512":
2386
+ algorithm = {
2387
+ name: "ECDSA",
2388
+ namedCurve: { ES256: "P-256", ES384: "P-384", ES512: "P-521" }[jwk.alg]
2389
+ };
2390
+ keyUsages = jwk.d ? ["sign"] : ["verify"];
2391
+ break;
2392
+ case "ECDH-ES":
2393
+ case "ECDH-ES+A128KW":
2394
+ case "ECDH-ES+A192KW":
2395
+ case "ECDH-ES+A256KW":
2396
+ algorithm = { name: "ECDH", namedCurve: jwk.crv };
2397
+ keyUsages = jwk.d ? ["deriveBits"] : [];
2398
+ break;
2399
+ default:
2400
+ throw new JOSENotSupported(unsupportedAlg);
2401
+ }
2402
+ break;
2403
+ }
2404
+ case "OKP": {
2405
+ switch (jwk.alg) {
2406
+ case "Ed25519":
2407
+ case "EdDSA":
2408
+ algorithm = { name: "Ed25519" };
2409
+ keyUsages = jwk.d ? ["sign"] : ["verify"];
2410
+ break;
2411
+ case "ECDH-ES":
2412
+ case "ECDH-ES+A128KW":
2413
+ case "ECDH-ES+A192KW":
2414
+ case "ECDH-ES+A256KW":
2415
+ algorithm = { name: jwk.crv };
2416
+ keyUsages = jwk.d ? ["deriveBits"] : [];
2417
+ break;
2418
+ default:
2419
+ throw new JOSENotSupported(unsupportedAlg);
2420
+ }
2421
+ break;
2422
+ }
2423
+ default:
2424
+ throw new JOSENotSupported('Invalid or unsupported JWK "kty" (Key Type) Parameter value');
2425
+ }
2426
+ return { algorithm, keyUsages };
2427
+ }
2428
+ async function jwkToKey(jwk) {
2429
+ if (!jwk.alg) {
2430
+ throw new TypeError('"alg" argument is required when "jwk.alg" is not present');
2431
+ }
2432
+ const { algorithm, keyUsages } = subtleMapping(jwk);
2433
+ const keyData = { ...jwk };
2434
+ if (keyData.kty !== "AKP") {
2435
+ delete keyData.alg;
2436
+ }
2437
+ delete keyData.use;
2438
+ return crypto.subtle.importKey("jwk", keyData, algorithm, jwk.ext ?? (jwk.d || jwk.priv ? false : true), jwk.key_ops ?? keyUsages);
2439
+ }
2440
+
2441
+ // ../../node_modules/jose/dist/webapi/lib/normalize_key.js
2442
+ var unusableForAlg = "given KeyObject instance cannot be used for this algorithm";
2443
+ var cache;
2444
+ var handleJWK = async (key, jwk, alg, freeze = false) => {
2445
+ cache ||= /* @__PURE__ */ new WeakMap();
2446
+ let cached = cache.get(key);
2447
+ if (cached?.[alg]) {
2448
+ return cached[alg];
2449
+ }
2450
+ const cryptoKey = await jwkToKey({ ...jwk, alg });
2451
+ if (freeze)
2452
+ Object.freeze(key);
2453
+ if (!cached) {
2454
+ cache.set(key, { [alg]: cryptoKey });
2455
+ } else {
2456
+ cached[alg] = cryptoKey;
2457
+ }
2458
+ return cryptoKey;
2459
+ };
2460
+ var handleKeyObject = (keyObject, alg) => {
2461
+ cache ||= /* @__PURE__ */ new WeakMap();
2462
+ let cached = cache.get(keyObject);
2463
+ if (cached?.[alg]) {
2464
+ return cached[alg];
2465
+ }
2466
+ const isPublic = keyObject.type === "public";
2467
+ const extractable = isPublic ? true : false;
2468
+ let cryptoKey;
2469
+ if (keyObject.asymmetricKeyType === "x25519") {
2470
+ switch (alg) {
2471
+ case "ECDH-ES":
2472
+ case "ECDH-ES+A128KW":
2473
+ case "ECDH-ES+A192KW":
2474
+ case "ECDH-ES+A256KW":
2475
+ break;
2476
+ default:
2477
+ throw new TypeError(unusableForAlg);
2478
+ }
2479
+ cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, isPublic ? [] : ["deriveBits"]);
2480
+ }
2481
+ if (keyObject.asymmetricKeyType === "ed25519") {
2482
+ if (alg !== "EdDSA" && alg !== "Ed25519") {
2483
+ throw new TypeError(unusableForAlg);
2484
+ }
2485
+ cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, [
2486
+ isPublic ? "verify" : "sign"
2487
+ ]);
2488
+ }
2489
+ switch (keyObject.asymmetricKeyType) {
2490
+ case "ml-dsa-44":
2491
+ case "ml-dsa-65":
2492
+ case "ml-dsa-87": {
2493
+ if (alg !== keyObject.asymmetricKeyType.toUpperCase()) {
2494
+ throw new TypeError(unusableForAlg);
2495
+ }
2496
+ cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, [
2497
+ isPublic ? "verify" : "sign"
2498
+ ]);
2499
+ }
2500
+ }
2501
+ if (keyObject.asymmetricKeyType === "rsa") {
2502
+ let hash;
2503
+ switch (alg) {
2504
+ case "RSA-OAEP":
2505
+ hash = "SHA-1";
2506
+ break;
2507
+ case "RS256":
2508
+ case "PS256":
2509
+ case "RSA-OAEP-256":
2510
+ hash = "SHA-256";
2511
+ break;
2512
+ case "RS384":
2513
+ case "PS384":
2514
+ case "RSA-OAEP-384":
2515
+ hash = "SHA-384";
2516
+ break;
2517
+ case "RS512":
2518
+ case "PS512":
2519
+ case "RSA-OAEP-512":
2520
+ hash = "SHA-512";
2521
+ break;
2522
+ default:
2523
+ throw new TypeError(unusableForAlg);
2524
+ }
2525
+ if (alg.startsWith("RSA-OAEP")) {
2526
+ return keyObject.toCryptoKey({
2527
+ name: "RSA-OAEP",
2528
+ hash
2529
+ }, extractable, isPublic ? ["encrypt"] : ["decrypt"]);
2530
+ }
2531
+ cryptoKey = keyObject.toCryptoKey({
2532
+ name: alg.startsWith("PS") ? "RSA-PSS" : "RSASSA-PKCS1-v1_5",
2533
+ hash
2534
+ }, extractable, [isPublic ? "verify" : "sign"]);
2535
+ }
2536
+ if (keyObject.asymmetricKeyType === "ec") {
2537
+ const nist = /* @__PURE__ */ new Map([
2538
+ ["prime256v1", "P-256"],
2539
+ ["secp384r1", "P-384"],
2540
+ ["secp521r1", "P-521"]
2541
+ ]);
2542
+ const namedCurve = nist.get(keyObject.asymmetricKeyDetails?.namedCurve);
2543
+ if (!namedCurve) {
2544
+ throw new TypeError(unusableForAlg);
2545
+ }
2546
+ const expectedCurve = { ES256: "P-256", ES384: "P-384", ES512: "P-521" };
2547
+ if (expectedCurve[alg] && namedCurve === expectedCurve[alg]) {
2548
+ cryptoKey = keyObject.toCryptoKey({
2549
+ name: "ECDSA",
2550
+ namedCurve
2551
+ }, extractable, [isPublic ? "verify" : "sign"]);
2552
+ }
2553
+ if (alg.startsWith("ECDH-ES")) {
2554
+ cryptoKey = keyObject.toCryptoKey({
2555
+ name: "ECDH",
2556
+ namedCurve
2557
+ }, extractable, isPublic ? [] : ["deriveBits"]);
2558
+ }
2559
+ }
2560
+ if (!cryptoKey) {
2561
+ throw new TypeError(unusableForAlg);
2562
+ }
2563
+ if (!cached) {
2564
+ cache.set(keyObject, { [alg]: cryptoKey });
2565
+ } else {
2566
+ cached[alg] = cryptoKey;
2567
+ }
2568
+ return cryptoKey;
2569
+ };
2570
+ async function normalizeKey(key, alg) {
2571
+ if (key instanceof Uint8Array) {
2572
+ return key;
2573
+ }
2574
+ if (isCryptoKey2(key)) {
2575
+ return key;
2576
+ }
2577
+ if (isKeyObject(key)) {
2578
+ if (key.type === "secret") {
2579
+ return key.export();
2580
+ }
2581
+ if ("toCryptoKey" in key && typeof key.toCryptoKey === "function") {
2582
+ try {
2583
+ return handleKeyObject(key, alg);
2584
+ } catch (err) {
2585
+ if (err instanceof TypeError) {
2586
+ throw err;
2587
+ }
2588
+ }
2589
+ }
2590
+ let jwk = key.export({ format: "jwk" });
2591
+ return handleJWK(key, jwk, alg);
2592
+ }
2593
+ if (isJWK(key)) {
2594
+ if (key.k) {
2595
+ return decode(key.k);
2596
+ }
2597
+ return handleJWK(key, key, alg, true);
2598
+ }
2599
+ throw new Error("unreachable");
2600
+ }
2601
+
2602
+ // ../../node_modules/jose/dist/webapi/key/import.js
2603
+ async function importJWK(jwk, alg, options) {
2604
+ if (!isObject(jwk)) {
2605
+ throw new TypeError("JWK must be an object");
2606
+ }
2607
+ let ext;
2608
+ alg ??= jwk.alg;
2609
+ ext ??= options?.extractable ?? jwk.ext;
2610
+ switch (jwk.kty) {
2611
+ case "oct":
2612
+ if (typeof jwk.k !== "string" || !jwk.k) {
2613
+ throw new TypeError('missing "k" (Key Value) Parameter value');
2614
+ }
2615
+ return decode(jwk.k);
2616
+ case "RSA":
2617
+ if ("oth" in jwk && jwk.oth !== void 0) {
2618
+ throw new JOSENotSupported('RSA JWK "oth" (Other Primes Info) Parameter value is not supported');
2619
+ }
2620
+ return jwkToKey({ ...jwk, alg, ext });
2621
+ case "AKP": {
2622
+ if (typeof jwk.alg !== "string" || !jwk.alg) {
2623
+ throw new TypeError('missing "alg" (Algorithm) Parameter value');
2624
+ }
2625
+ if (alg !== void 0 && alg !== jwk.alg) {
2626
+ throw new TypeError("JWK alg and alg option value mismatch");
2627
+ }
2628
+ return jwkToKey({ ...jwk, ext });
2629
+ }
2630
+ case "EC":
2631
+ case "OKP":
2632
+ return jwkToKey({ ...jwk, alg, ext });
2633
+ default:
2634
+ throw new JOSENotSupported('Unsupported "kty" (Key Type) Parameter value');
2635
+ }
2636
+ }
2637
+
2638
+ // ../../node_modules/jose/dist/webapi/lib/validate_crit.js
2639
+ function validateCrit(Err, recognizedDefault, recognizedOption, protectedHeader, joseHeader) {
2640
+ if (joseHeader.crit !== void 0 && protectedHeader?.crit === void 0) {
2641
+ throw new Err('"crit" (Critical) Header Parameter MUST be integrity protected');
2642
+ }
2643
+ if (!protectedHeader || protectedHeader.crit === void 0) {
2644
+ return /* @__PURE__ */ new Set();
2645
+ }
2646
+ if (!Array.isArray(protectedHeader.crit) || protectedHeader.crit.length === 0 || protectedHeader.crit.some((input) => typeof input !== "string" || input.length === 0)) {
2647
+ throw new Err('"crit" (Critical) Header Parameter MUST be an array of non-empty strings when present');
2648
+ }
2649
+ let recognized;
2650
+ if (recognizedOption !== void 0) {
2651
+ recognized = new Map([...Object.entries(recognizedOption), ...recognizedDefault.entries()]);
2652
+ } else {
2653
+ recognized = recognizedDefault;
2654
+ }
2655
+ for (const parameter of protectedHeader.crit) {
2656
+ if (!recognized.has(parameter)) {
2657
+ throw new JOSENotSupported(`Extension Header Parameter "${parameter}" is not recognized`);
2658
+ }
2659
+ if (joseHeader[parameter] === void 0) {
2660
+ throw new Err(`Extension Header Parameter "${parameter}" is missing`);
2661
+ }
2662
+ if (recognized.get(parameter) && protectedHeader[parameter] === void 0) {
2663
+ throw new Err(`Extension Header Parameter "${parameter}" MUST be integrity protected`);
2664
+ }
2665
+ }
2666
+ return new Set(protectedHeader.crit);
2667
+ }
2668
+
2669
+ // ../../node_modules/jose/dist/webapi/lib/validate_algorithms.js
2670
+ function validateAlgorithms(option, algorithms) {
2671
+ if (algorithms !== void 0 && (!Array.isArray(algorithms) || algorithms.some((s) => typeof s !== "string"))) {
2672
+ throw new TypeError(`"${option}" option must be an array of strings`);
2673
+ }
2674
+ if (!algorithms) {
2675
+ return void 0;
2676
+ }
2677
+ return new Set(algorithms);
2678
+ }
2679
+
2680
+ // ../../node_modules/jose/dist/webapi/lib/check_key_type.js
2681
+ var tag = (key) => key?.[Symbol.toStringTag];
2682
+ var jwkMatchesOp = (alg, key, usage) => {
2683
+ if (key.use !== void 0) {
2684
+ let expected;
2685
+ switch (usage) {
2686
+ case "sign":
2687
+ case "verify":
2688
+ expected = "sig";
2689
+ break;
2690
+ case "encrypt":
2691
+ case "decrypt":
2692
+ expected = "enc";
2693
+ break;
2694
+ }
2695
+ if (key.use !== expected) {
2696
+ throw new TypeError(`Invalid key for this operation, its "use" must be "${expected}" when present`);
2697
+ }
2698
+ }
2699
+ if (key.alg !== void 0 && key.alg !== alg) {
2700
+ throw new TypeError(`Invalid key for this operation, its "alg" must be "${alg}" when present`);
2701
+ }
2702
+ if (Array.isArray(key.key_ops)) {
2703
+ let expectedKeyOp;
2704
+ switch (true) {
2705
+ case (usage === "sign" || usage === "verify"):
2706
+ case alg === "dir":
2707
+ case alg.includes("CBC-HS"):
2708
+ expectedKeyOp = usage;
2709
+ break;
2710
+ case alg.startsWith("PBES2"):
2711
+ expectedKeyOp = "deriveBits";
2712
+ break;
2713
+ case /^A\d{3}(?:GCM)?(?:KW)?$/.test(alg):
2714
+ if (!alg.includes("GCM") && alg.endsWith("KW")) {
2715
+ expectedKeyOp = usage === "encrypt" ? "wrapKey" : "unwrapKey";
2716
+ } else {
2717
+ expectedKeyOp = usage;
2718
+ }
2719
+ break;
2720
+ case (usage === "encrypt" && alg.startsWith("RSA")):
2721
+ expectedKeyOp = "wrapKey";
2722
+ break;
2723
+ case usage === "decrypt":
2724
+ expectedKeyOp = alg.startsWith("RSA") ? "unwrapKey" : "deriveBits";
2725
+ break;
2726
+ }
2727
+ if (expectedKeyOp && key.key_ops?.includes?.(expectedKeyOp) === false) {
2728
+ throw new TypeError(`Invalid key for this operation, its "key_ops" must include "${expectedKeyOp}" when present`);
2729
+ }
2730
+ }
2731
+ return true;
2732
+ };
2733
+ var symmetricTypeCheck = (alg, key, usage) => {
2734
+ if (key instanceof Uint8Array)
2735
+ return;
2736
+ if (isJWK(key)) {
2737
+ if (isSecretJWK(key) && jwkMatchesOp(alg, key, usage))
2738
+ return;
2739
+ throw new TypeError(`JSON Web Key for symmetric algorithms must have JWK "kty" (Key Type) equal to "oct" and the JWK "k" (Key Value) present`);
2740
+ }
2741
+ if (!isKeyLike(key)) {
2742
+ throw new TypeError(withAlg(alg, key, "CryptoKey", "KeyObject", "JSON Web Key", "Uint8Array"));
2743
+ }
2744
+ if (key.type !== "secret") {
2745
+ throw new TypeError(`${tag(key)} instances for symmetric algorithms must be of type "secret"`);
2746
+ }
2747
+ };
2748
+ var asymmetricTypeCheck = (alg, key, usage) => {
2749
+ if (isJWK(key)) {
2750
+ switch (usage) {
2751
+ case "decrypt":
2752
+ case "sign":
2753
+ if (isPrivateJWK(key) && jwkMatchesOp(alg, key, usage))
2754
+ return;
2755
+ throw new TypeError(`JSON Web Key for this operation must be a private JWK`);
2756
+ case "encrypt":
2757
+ case "verify":
2758
+ if (isPublicJWK(key) && jwkMatchesOp(alg, key, usage))
2759
+ return;
2760
+ throw new TypeError(`JSON Web Key for this operation must be a public JWK`);
2761
+ }
2762
+ }
2763
+ if (!isKeyLike(key)) {
2764
+ throw new TypeError(withAlg(alg, key, "CryptoKey", "KeyObject", "JSON Web Key"));
2765
+ }
2766
+ if (key.type === "secret") {
2767
+ throw new TypeError(`${tag(key)} instances for asymmetric algorithms must not be of type "secret"`);
2768
+ }
2769
+ if (key.type === "public") {
2770
+ switch (usage) {
2771
+ case "sign":
2772
+ throw new TypeError(`${tag(key)} instances for asymmetric algorithm signing must be of type "private"`);
2773
+ case "decrypt":
2774
+ throw new TypeError(`${tag(key)} instances for asymmetric algorithm decryption must be of type "private"`);
2775
+ }
2776
+ }
2777
+ if (key.type === "private") {
2778
+ switch (usage) {
2779
+ case "verify":
2780
+ throw new TypeError(`${tag(key)} instances for asymmetric algorithm verifying must be of type "public"`);
2781
+ case "encrypt":
2782
+ throw new TypeError(`${tag(key)} instances for asymmetric algorithm encryption must be of type "public"`);
2783
+ }
2784
+ }
2785
+ };
2786
+ function checkKeyType(alg, key, usage) {
2787
+ switch (alg.substring(0, 2)) {
2788
+ case "A1":
2789
+ case "A2":
2790
+ case "di":
2791
+ case "HS":
2792
+ case "PB":
2793
+ symmetricTypeCheck(alg, key, usage);
2794
+ break;
2795
+ default:
2796
+ asymmetricTypeCheck(alg, key, usage);
2797
+ }
2798
+ }
2799
+
2800
+ // ../../node_modules/jose/dist/webapi/jws/flattened/verify.js
2801
+ async function flattenedVerify(jws, key, options) {
2802
+ if (!isObject(jws)) {
2803
+ throw new JWSInvalid("Flattened JWS must be an object");
2804
+ }
2805
+ if (jws.protected === void 0 && jws.header === void 0) {
2806
+ throw new JWSInvalid('Flattened JWS must have either of the "protected" or "header" members');
2807
+ }
2808
+ if (jws.protected !== void 0 && typeof jws.protected !== "string") {
2809
+ throw new JWSInvalid("JWS Protected Header incorrect type");
2810
+ }
2811
+ if (jws.payload === void 0) {
2812
+ throw new JWSInvalid("JWS Payload missing");
2813
+ }
2814
+ if (typeof jws.signature !== "string") {
2815
+ throw new JWSInvalid("JWS Signature missing or incorrect type");
2816
+ }
2817
+ if (jws.header !== void 0 && !isObject(jws.header)) {
2818
+ throw new JWSInvalid("JWS Unprotected Header incorrect type");
2819
+ }
2820
+ let parsedProt = {};
2821
+ if (jws.protected) {
2822
+ try {
2823
+ const protectedHeader = decode(jws.protected);
2824
+ parsedProt = JSON.parse(decoder2.decode(protectedHeader));
2825
+ } catch {
2826
+ throw new JWSInvalid("JWS Protected Header is invalid");
2827
+ }
2828
+ }
2829
+ if (!isDisjoint(parsedProt, jws.header)) {
2830
+ throw new JWSInvalid("JWS Protected and JWS Unprotected Header Parameter names must be disjoint");
2831
+ }
2832
+ const joseHeader = {
2833
+ ...parsedProt,
2834
+ ...jws.header
2835
+ };
2836
+ const extensions = validateCrit(JWSInvalid, /* @__PURE__ */ new Map([["b64", true]]), options?.crit, parsedProt, joseHeader);
2837
+ let b64 = true;
2838
+ if (extensions.has("b64")) {
2839
+ b64 = parsedProt.b64;
2840
+ if (typeof b64 !== "boolean") {
2841
+ throw new JWSInvalid('The "b64" (base64url-encode payload) Header Parameter must be a boolean');
2842
+ }
2843
+ }
2844
+ const { alg } = joseHeader;
2845
+ if (typeof alg !== "string" || !alg) {
2846
+ throw new JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid');
2847
+ }
2848
+ const algorithms = options && validateAlgorithms("algorithms", options.algorithms);
2849
+ if (algorithms && !algorithms.has(alg)) {
2850
+ throw new JOSEAlgNotAllowed('"alg" (Algorithm) Header Parameter value not allowed');
2851
+ }
2852
+ if (b64) {
2853
+ if (typeof jws.payload !== "string") {
2854
+ throw new JWSInvalid("JWS Payload must be a string");
2855
+ }
2856
+ } else if (typeof jws.payload !== "string" && !(jws.payload instanceof Uint8Array)) {
2857
+ throw new JWSInvalid("JWS Payload must be a string or an Uint8Array instance");
2858
+ }
2859
+ let resolvedKey = false;
2860
+ if (typeof key === "function") {
2861
+ key = await key(parsedProt, jws);
2862
+ resolvedKey = true;
2863
+ }
2864
+ checkKeyType(alg, key, "verify");
2865
+ const data = concat(jws.protected !== void 0 ? encode(jws.protected) : new Uint8Array(), encode("."), typeof jws.payload === "string" ? b64 ? encode(jws.payload) : encoder2.encode(jws.payload) : jws.payload);
2866
+ const signature = decodeBase64url(jws.signature, "signature", JWSInvalid);
2867
+ const k = await normalizeKey(key, alg);
2868
+ const verified = await verify(alg, k, signature, data);
2869
+ if (!verified) {
2870
+ throw new JWSSignatureVerificationFailed();
2871
+ }
2872
+ let payload;
2873
+ if (b64) {
2874
+ payload = decodeBase64url(jws.payload, "payload", JWSInvalid);
2875
+ } else if (typeof jws.payload === "string") {
2876
+ payload = encoder2.encode(jws.payload);
2877
+ } else {
2878
+ payload = jws.payload;
2879
+ }
2880
+ const result = { payload };
2881
+ if (jws.protected !== void 0) {
2882
+ result.protectedHeader = parsedProt;
2883
+ }
2884
+ if (jws.header !== void 0) {
2885
+ result.unprotectedHeader = jws.header;
2886
+ }
2887
+ if (resolvedKey) {
2888
+ return { ...result, key: k };
2889
+ }
2890
+ return result;
2891
+ }
2892
+
2893
+ // ../../node_modules/jose/dist/webapi/jws/compact/verify.js
2894
+ async function compactVerify(jws, key, options) {
2895
+ if (jws instanceof Uint8Array) {
2896
+ jws = decoder2.decode(jws);
2897
+ }
2898
+ if (typeof jws !== "string") {
2899
+ throw new JWSInvalid("Compact JWS must be a string or Uint8Array");
2900
+ }
2901
+ const { 0: protectedHeader, 1: payload, 2: signature, length } = jws.split(".");
2902
+ if (length !== 3) {
2903
+ throw new JWSInvalid("Invalid Compact JWS");
2904
+ }
2905
+ const verified = await flattenedVerify({ payload, protected: protectedHeader, signature }, key, options);
2906
+ const result = { payload: verified.payload, protectedHeader: verified.protectedHeader };
2907
+ if (typeof key === "function") {
2908
+ return { ...result, key: verified.key };
2909
+ }
2910
+ return result;
2911
+ }
2912
+
2913
+ // ../../node_modules/jose/dist/webapi/lib/jwt_claims_set.js
2914
+ var epoch = (date) => Math.floor(date.getTime() / 1e3);
2915
+ var minute = 60;
2916
+ var hour = minute * 60;
2917
+ var day = hour * 24;
2918
+ var week = day * 7;
2919
+ var year = day * 365.25;
2920
+ var REGEX = /^(\+|\-)? ?(\d+|\d+\.\d+) ?(seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)(?: (ago|from now))?$/i;
2921
+ function secs(str) {
2922
+ const matched = REGEX.exec(str);
2923
+ if (!matched || matched[4] && matched[1]) {
2924
+ throw new TypeError("Invalid time period format");
2925
+ }
2926
+ const value = parseFloat(matched[2]);
2927
+ const unit = matched[3].toLowerCase();
2928
+ let numericDate;
2929
+ switch (unit) {
2930
+ case "sec":
2931
+ case "secs":
2932
+ case "second":
2933
+ case "seconds":
2934
+ case "s":
2935
+ numericDate = Math.round(value);
2936
+ break;
2937
+ case "minute":
2938
+ case "minutes":
2939
+ case "min":
2940
+ case "mins":
2941
+ case "m":
2942
+ numericDate = Math.round(value * minute);
2943
+ break;
2944
+ case "hour":
2945
+ case "hours":
2946
+ case "hr":
2947
+ case "hrs":
2948
+ case "h":
2949
+ numericDate = Math.round(value * hour);
2950
+ break;
2951
+ case "day":
2952
+ case "days":
2953
+ case "d":
2954
+ numericDate = Math.round(value * day);
2955
+ break;
2956
+ case "week":
2957
+ case "weeks":
2958
+ case "w":
2959
+ numericDate = Math.round(value * week);
2960
+ break;
2961
+ default:
2962
+ numericDate = Math.round(value * year);
2963
+ break;
2964
+ }
2965
+ if (matched[1] === "-" || matched[4] === "ago") {
2966
+ return -numericDate;
2967
+ }
2968
+ return numericDate;
2969
+ }
2970
+ var normalizeTyp = (value) => {
2971
+ if (value.includes("/")) {
2972
+ return value.toLowerCase();
2973
+ }
2974
+ return `application/${value.toLowerCase()}`;
2975
+ };
2976
+ var checkAudiencePresence = (audPayload, audOption) => {
2977
+ if (typeof audPayload === "string") {
2978
+ return audOption.includes(audPayload);
2979
+ }
2980
+ if (Array.isArray(audPayload)) {
2981
+ return audOption.some(Set.prototype.has.bind(new Set(audPayload)));
2982
+ }
2983
+ return false;
2984
+ };
2985
+ function validateClaimsSet(protectedHeader, encodedPayload, options = {}) {
2986
+ let payload;
2987
+ try {
2988
+ payload = JSON.parse(decoder2.decode(encodedPayload));
2989
+ } catch {
2990
+ }
2991
+ if (!isObject(payload)) {
2992
+ throw new JWTInvalid("JWT Claims Set must be a top-level JSON object");
2993
+ }
2994
+ const { typ } = options;
2995
+ if (typ && (typeof protectedHeader.typ !== "string" || normalizeTyp(protectedHeader.typ) !== normalizeTyp(typ))) {
2996
+ throw new JWTClaimValidationFailed('unexpected "typ" JWT header value', payload, "typ", "check_failed");
2997
+ }
2998
+ const { requiredClaims = [], issuer, subject, audience, maxTokenAge } = options;
2999
+ const presenceCheck = [...requiredClaims];
3000
+ if (maxTokenAge !== void 0)
3001
+ presenceCheck.push("iat");
3002
+ if (audience !== void 0)
3003
+ presenceCheck.push("aud");
3004
+ if (subject !== void 0)
3005
+ presenceCheck.push("sub");
3006
+ if (issuer !== void 0)
3007
+ presenceCheck.push("iss");
3008
+ for (const claim of new Set(presenceCheck.reverse())) {
3009
+ if (!(claim in payload)) {
3010
+ throw new JWTClaimValidationFailed(`missing required "${claim}" claim`, payload, claim, "missing");
3011
+ }
3012
+ }
3013
+ if (issuer && !(Array.isArray(issuer) ? issuer : [issuer]).includes(payload.iss)) {
3014
+ throw new JWTClaimValidationFailed('unexpected "iss" claim value', payload, "iss", "check_failed");
3015
+ }
3016
+ if (subject && payload.sub !== subject) {
3017
+ throw new JWTClaimValidationFailed('unexpected "sub" claim value', payload, "sub", "check_failed");
3018
+ }
3019
+ if (audience && !checkAudiencePresence(payload.aud, typeof audience === "string" ? [audience] : audience)) {
3020
+ throw new JWTClaimValidationFailed('unexpected "aud" claim value', payload, "aud", "check_failed");
3021
+ }
3022
+ let tolerance;
3023
+ switch (typeof options.clockTolerance) {
3024
+ case "string":
3025
+ tolerance = secs(options.clockTolerance);
3026
+ break;
3027
+ case "number":
3028
+ tolerance = options.clockTolerance;
3029
+ break;
3030
+ case "undefined":
3031
+ tolerance = 0;
3032
+ break;
3033
+ default:
3034
+ throw new TypeError("Invalid clockTolerance option type");
3035
+ }
3036
+ const { currentDate } = options;
3037
+ const now = epoch(currentDate || /* @__PURE__ */ new Date());
3038
+ if ((payload.iat !== void 0 || maxTokenAge) && typeof payload.iat !== "number") {
3039
+ throw new JWTClaimValidationFailed('"iat" claim must be a number', payload, "iat", "invalid");
3040
+ }
3041
+ if (payload.nbf !== void 0) {
3042
+ if (typeof payload.nbf !== "number") {
3043
+ throw new JWTClaimValidationFailed('"nbf" claim must be a number', payload, "nbf", "invalid");
3044
+ }
3045
+ if (payload.nbf > now + tolerance) {
3046
+ throw new JWTClaimValidationFailed('"nbf" claim timestamp check failed', payload, "nbf", "check_failed");
3047
+ }
3048
+ }
3049
+ if (payload.exp !== void 0) {
3050
+ if (typeof payload.exp !== "number") {
3051
+ throw new JWTClaimValidationFailed('"exp" claim must be a number', payload, "exp", "invalid");
3052
+ }
3053
+ if (payload.exp <= now - tolerance) {
3054
+ throw new JWTExpired('"exp" claim timestamp check failed', payload, "exp", "check_failed");
3055
+ }
3056
+ }
3057
+ if (maxTokenAge) {
3058
+ const age = now - payload.iat;
3059
+ const max = typeof maxTokenAge === "number" ? maxTokenAge : secs(maxTokenAge);
3060
+ if (age - tolerance > max) {
3061
+ throw new JWTExpired('"iat" claim timestamp check failed (too far in the past)', payload, "iat", "check_failed");
3062
+ }
3063
+ if (age < 0 - tolerance) {
3064
+ throw new JWTClaimValidationFailed('"iat" claim timestamp check failed (it should be in the past)', payload, "iat", "check_failed");
3065
+ }
3066
+ }
3067
+ return payload;
3068
+ }
3069
+
3070
+ // ../../node_modules/jose/dist/webapi/jwt/verify.js
3071
+ async function jwtVerify(jwt2, key, options) {
3072
+ const verified = await compactVerify(jwt2, key, options);
3073
+ if (verified.protectedHeader.crit?.includes("b64") && verified.protectedHeader.b64 === false) {
3074
+ throw new JWTInvalid("JWTs MUST NOT use unencoded payload");
3075
+ }
3076
+ const payload = validateClaimsSet(verified.protectedHeader, verified.payload, options);
3077
+ const result = { payload, protectedHeader: verified.protectedHeader };
3078
+ if (typeof key === "function") {
3079
+ return { ...result, key: verified.key };
3080
+ }
3081
+ return result;
3082
+ }
3083
+
3084
+ // ../../node_modules/jose/dist/webapi/jwks/local.js
3085
+ function getKtyFromAlg(alg) {
3086
+ switch (typeof alg === "string" && alg.slice(0, 2)) {
3087
+ case "RS":
3088
+ case "PS":
3089
+ return "RSA";
3090
+ case "ES":
3091
+ return "EC";
3092
+ case "Ed":
3093
+ return "OKP";
3094
+ case "ML":
3095
+ return "AKP";
3096
+ default:
3097
+ throw new JOSENotSupported('Unsupported "alg" value for a JSON Web Key Set');
3098
+ }
3099
+ }
3100
+ function isJWKSLike(jwks) {
3101
+ return jwks && typeof jwks === "object" && Array.isArray(jwks.keys) && jwks.keys.every(isJWKLike);
3102
+ }
3103
+ function isJWKLike(key) {
3104
+ return isObject(key);
3105
+ }
3106
+ var LocalJWKSet = class {
3107
+ #jwks;
3108
+ #cached = /* @__PURE__ */ new WeakMap();
3109
+ constructor(jwks) {
3110
+ if (!isJWKSLike(jwks)) {
3111
+ throw new JWKSInvalid("JSON Web Key Set malformed");
3112
+ }
3113
+ this.#jwks = structuredClone(jwks);
3114
+ }
3115
+ jwks() {
3116
+ return this.#jwks;
3117
+ }
3118
+ async getKey(protectedHeader, token) {
3119
+ const { alg, kid } = { ...protectedHeader, ...token?.header };
3120
+ const kty = getKtyFromAlg(alg);
3121
+ const candidates = this.#jwks.keys.filter((jwk2) => {
3122
+ let candidate = kty === jwk2.kty;
3123
+ if (candidate && typeof kid === "string") {
3124
+ candidate = kid === jwk2.kid;
3125
+ }
3126
+ if (candidate && (typeof jwk2.alg === "string" || kty === "AKP")) {
3127
+ candidate = alg === jwk2.alg;
3128
+ }
3129
+ if (candidate && typeof jwk2.use === "string") {
3130
+ candidate = jwk2.use === "sig";
3131
+ }
3132
+ if (candidate && Array.isArray(jwk2.key_ops)) {
3133
+ candidate = jwk2.key_ops.includes("verify");
3134
+ }
3135
+ if (candidate) {
3136
+ switch (alg) {
3137
+ case "ES256":
3138
+ candidate = jwk2.crv === "P-256";
3139
+ break;
3140
+ case "ES384":
3141
+ candidate = jwk2.crv === "P-384";
3142
+ break;
3143
+ case "ES512":
3144
+ candidate = jwk2.crv === "P-521";
3145
+ break;
3146
+ case "Ed25519":
3147
+ case "EdDSA":
3148
+ candidate = jwk2.crv === "Ed25519";
3149
+ break;
3150
+ }
3151
+ }
3152
+ return candidate;
3153
+ });
3154
+ const { 0: jwk, length } = candidates;
3155
+ if (length === 0) {
3156
+ throw new JWKSNoMatchingKey();
3157
+ }
3158
+ if (length !== 1) {
3159
+ const error2 = new JWKSMultipleMatchingKeys();
3160
+ const _cached = this.#cached;
3161
+ error2[Symbol.asyncIterator] = async function* () {
3162
+ for (const jwk2 of candidates) {
3163
+ try {
3164
+ yield await importWithAlgCache(_cached, jwk2, alg);
3165
+ } catch {
3166
+ }
3167
+ }
3168
+ };
3169
+ throw error2;
3170
+ }
3171
+ return importWithAlgCache(this.#cached, jwk, alg);
3172
+ }
3173
+ };
3174
+ async function importWithAlgCache(cache2, jwk, alg) {
3175
+ const cached = cache2.get(jwk) || cache2.set(jwk, {}).get(jwk);
3176
+ if (cached[alg] === void 0) {
3177
+ const key = await importJWK({ ...jwk, ext: true }, alg);
3178
+ if (key instanceof Uint8Array || key.type !== "public") {
3179
+ throw new JWKSInvalid("JSON Web Key Set members must be public keys");
3180
+ }
3181
+ cached[alg] = key;
3182
+ }
3183
+ return cached[alg];
3184
+ }
3185
+ function createLocalJWKSet(jwks) {
3186
+ const set = new LocalJWKSet(jwks);
3187
+ const localJWKSet = async (protectedHeader, token) => set.getKey(protectedHeader, token);
3188
+ Object.defineProperties(localJWKSet, {
3189
+ jwks: {
3190
+ value: () => structuredClone(set.jwks()),
3191
+ enumerable: false,
3192
+ configurable: false,
3193
+ writable: false
3194
+ }
3195
+ });
3196
+ return localJWKSet;
3197
+ }
3198
+
3199
+ // src/oidc.jwt.mjs
3200
+ var jwksCache = /* @__PURE__ */ new WeakMap();
3201
+ function keySetFor(jwks) {
3202
+ if (!jwks || !Array.isArray(jwks.keys)) {
3203
+ throw metroError("metro.oidc: Error: jwks must be an object with a keys array");
3204
+ }
3205
+ if (!jwksCache.has(jwks)) {
3206
+ jwksCache.set(jwks, createLocalJWKSet(jwks));
3207
+ }
3208
+ return jwksCache.get(jwks);
3209
+ }
3210
+ function supportedAlgorithms(openidConfiguration = {}) {
3211
+ const algorithms = openidConfiguration.id_token_signing_alg_values_supported;
3212
+ if (Array.isArray(algorithms) && algorithms.length) {
3213
+ return algorithms.filter((algorithm) => algorithm !== "none");
3214
+ }
3215
+ return ["RS256"];
3216
+ }
3217
+ async function validateIdToken(idToken2, options = {}) {
3218
+ if (!idToken2) {
3219
+ throw metroError("metro.oidc: Error: token response did not include an id_token");
3220
+ }
3221
+ if (!options.jwks) {
3222
+ throw metroError("metro.oidc: Error: cannot validate id_token without jwks");
3223
+ }
3224
+ if (!options.issuer) {
3225
+ throw metroError("metro.oidc: Error: cannot validate id_token without issuer");
3226
+ }
3227
+ if (!options.client_id) {
3228
+ throw metroError("metro.oidc: Error: cannot validate id_token without client_id");
3229
+ }
3230
+ const { payload, protectedHeader } = await jwtVerify(
3231
+ idToken2,
3232
+ keySetFor(options.jwks),
3233
+ {
3234
+ issuer: options.issuer,
3235
+ audience: options.client_id,
3236
+ algorithms: options.algorithms || supportedAlgorithms(options.openid_configuration),
3237
+ clockTolerance: options.clockTolerance ?? 60,
3238
+ requiredClaims: ["iss", "sub", "aud", "exp", "iat"]
3239
+ }
3240
+ );
3241
+ if (options.nonce !== void 0 && payload.nonce !== options.nonce) {
3242
+ throw metroError("metro.oidc: Error: id_token nonce mismatch");
3243
+ }
3244
+ return {
3245
+ header: protectedHeader,
3246
+ claims: payload
3247
+ };
3248
+ }
3249
+
2143
3250
  // src/oidcmw.mjs
2144
3251
  function oidcmw(options = {}) {
2145
3252
  const defaultOptions = {
@@ -2177,7 +3284,8 @@
2177
3284
  try {
2178
3285
  res = await next(req);
2179
3286
  } catch (err) {
2180
- if (res.status != 401 && res.status != 403) {
3287
+ res = err?.cause;
3288
+ if (!res || res.status != 401 && res.status != 403) {
2181
3289
  throw err;
2182
3290
  }
2183
3291
  }
@@ -2187,7 +3295,8 @@
2187
3295
  }
2188
3296
  if (!options.openid_configuration) {
2189
3297
  options.openid_configuration = await oidcDiscovery({
2190
- issuer: options.issuer
3298
+ issuer: options.issuer,
3299
+ client: options.client.with(options.issuer)
2191
3300
  });
2192
3301
  options.store.set("openid_configuration", options.openid_configuration);
2193
3302
  }
@@ -2197,11 +3306,14 @@
2197
3306
  }
2198
3307
  options.client_info = await register({
2199
3308
  registration_endpoint: options.openid_configuration.registration_endpoint,
3309
+ client: options.client,
2200
3310
  client_info: options.client_info
2201
3311
  });
2202
3312
  options.store.set("client_info", options.client_info);
2203
3313
  }
2204
3314
  const scope = options.scope || "openid";
3315
+ const nonce = options.nonce || generateCodeVerifier(32);
3316
+ options.store.set("pending_nonce", nonce);
2205
3317
  const oauth2Options = Object.assign(
2206
3318
  {
2207
3319
  site: options.issuer,
@@ -2218,32 +3330,49 @@
2218
3330
  token_endpoint: options.openid_configuration.token_endpoint,
2219
3331
  scope,
2220
3332
  //FIXME: should only use scopes supported by server
2221
- redirect_uri: options.client_info.redirect_uris[0]
3333
+ redirect_uri: options.client_info.redirect_uris[0],
3334
+ nonce
2222
3335
  }
2223
3336
  }
2224
3337
  //...
2225
3338
  );
2226
3339
  const storeIdToken = async (req2, next2) => {
2227
3340
  const res2 = await next2(req2);
3341
+ const tokenEndpoint = url(options.openid_configuration.token_endpoint, { hash: "" }).href;
3342
+ const requestUrl = url(req2.url, { hash: "" }).href;
3343
+ if (requestUrl !== tokenEndpoint) {
3344
+ return res2;
3345
+ }
2228
3346
  const contentType = res2.headers.get("content-type");
2229
- if (contentType?.startsWith("application/json")) {
2230
- let id_token = res2.data?.id_token;
2231
- if (!id_token) {
2232
- const res22 = res2.clone();
2233
- try {
2234
- let data = await res22.json();
2235
- if (data && data.id_token) {
2236
- id_token = data.id_token;
2237
- }
2238
- } catch (e) {
2239
- }
2240
- }
2241
- if (id_token) {
2242
- options.store.set("id_token", id_token);
2243
- }
3347
+ if (!contentType?.startsWith("application/json")) {
3348
+ return res2;
3349
+ }
3350
+ let data = res2.data && typeof res2.data === "object" ? res2.data : null;
3351
+ if (!data) {
3352
+ const res22 = res2.clone();
3353
+ data = await res22.json();
2244
3354
  }
3355
+ const id_token = data?.id_token;
3356
+ const jwks = await getJwks();
3357
+ const validation = await validateIdToken(id_token, {
3358
+ issuer: options.openid_configuration.issuer,
3359
+ client_id: options.client_info.client_id,
3360
+ jwks,
3361
+ openid_configuration: options.openid_configuration,
3362
+ nonce: options.store.get("pending_nonce")
3363
+ });
3364
+ options.store.set("id_token", id_token);
3365
+ options.store.set("id_token_claims", validation.claims);
2245
3366
  return res2;
2246
3367
  };
3368
+ const getJwks = async () => {
3369
+ if (!options.jwks) {
3370
+ const jwksClient = options.client.with(throwermw()).with(jsonmw());
3371
+ const response2 = await jwksClient.get(options.openid_configuration.jwks_uri);
3372
+ options.jwks = response2.data;
3373
+ }
3374
+ return options.jwks;
3375
+ };
2247
3376
  let oauth2client = options.client.with(options.issuer).with(storeIdToken);
2248
3377
  if (options.use_dpop) {
2249
3378
  const dpopOptions = {
@@ -2253,8 +3382,8 @@
2253
3382
  dpop_signing_alg_values_supported: options.openid_configuration.dpop_signing_alg_values_supported
2254
3383
  };
2255
3384
  oauth2client = oauth2client.with(dpopmw(dpopOptions));
2256
- oauth2Options.client = oauth2client;
2257
3385
  }
3386
+ oauth2Options.client = oauth2client;
2258
3387
  oauth2client = oauth2client.with(oauth2mw(oauth2Options));
2259
3388
  res = await oauth2client.fetch(req);
2260
3389
  return res;
@@ -2272,18 +3401,33 @@
2272
3401
  }
2273
3402
  return options.store.get("id_token");
2274
3403
  }
3404
+ function idTokenClaims(options) {
3405
+ if (!options.store) {
3406
+ if (!options.issuer) {
3407
+ throw metroError("Must supply options.issuer or options.store to get the id_token claims");
3408
+ }
3409
+ options.store = oidcStore(options.issuer);
3410
+ }
3411
+ return options.store.get("id_token_claims");
3412
+ }
2275
3413
 
2276
- // src/browser.mjs
3414
+ // src/index.mjs
2277
3415
  var oidc = {
2278
3416
  oidcmw,
2279
3417
  discover: oidcDiscovery,
2280
3418
  register,
2281
3419
  isRedirected: isRedirected2,
2282
- idToken
3420
+ idToken,
3421
+ idTokenClaims
2283
3422
  };
2284
- if (!globalThis.metro.oidc) {
2285
- globalThis.metro.oidc = oidc;
3423
+ var index_default = oidc;
3424
+
3425
+ // src/browser.mjs
3426
+ var metro = Object.assign({}, src_exports, globalThis.metro || {});
3427
+ if (!metro.oidc) {
3428
+ metro.oidc = index_default;
2286
3429
  }
2287
- var browser_default2 = oidc;
3430
+ globalThis.metro = metro;
3431
+ var browser_default = index_default;
2288
3432
  })();
2289
3433
  //# sourceMappingURL=browser.js.map