@deslop/auth 0.1.1250 → 0.1.1256
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/client/assets/{(home)-CsFFJloK.js → (home)-BGL2qG8s.js} +2 -2
- package/dist/client/assets/{Check.es-Bp5djBLz.js → Check.es-scKUVKGC.js} +1 -1
- package/dist/client/assets/components-zIDgshMa.js +1 -0
- package/dist/client/assets/dialog-DiwMVfBX.js +1 -0
- package/dist/client/assets/{index-IIm2ZEY_.js → index-BZmbUyIH.js} +2 -2
- package/dist/client/assets/index-CYzFAzTI.css +2 -0
- package/dist/client/assets/people-BOPejtAC.js +1 -0
- package/dist/client/assets/route-BG0dbB9K.js +41 -0
- package/dist/client/assets/utils-Aj5S_5S2.js +2 -0
- package/dist/client/index.html +6 -5
- package/dist/server.js +929 -338
- package/package.json +2 -2
- package/dist/client/assets/components-DxFAwEtI.js +0 -1
- package/dist/client/assets/dialog-DKm49liV.js +0 -1
- package/dist/client/assets/index-e2xUPxy0.css +0 -2
- package/dist/client/assets/people-BvjrADRC.js +0 -1
- package/dist/client/assets/route-NUCS2u02.js +0 -41
- package/dist/client/assets/utils-CQ8HfW2q.js +0 -2
package/dist/server.js
CHANGED
|
@@ -6919,7 +6919,7 @@ const keys$1 = (self) => Object.keys(self);
|
|
|
6919
6919
|
* @category mutations
|
|
6920
6920
|
* @since 2.0.0
|
|
6921
6921
|
*/
|
|
6922
|
-
const set$
|
|
6922
|
+
const set$7 = /*#__PURE__*/ dual(3, (self, key, value) => {
|
|
6923
6923
|
return {
|
|
6924
6924
|
...self,
|
|
6925
6925
|
[key]: value
|
|
@@ -16429,7 +16429,7 @@ const make$79 = (...entries) => fromIterable$2(entries);
|
|
|
16429
16429
|
*/
|
|
16430
16430
|
const fromIterable$2 = (entries) => {
|
|
16431
16431
|
const self = empty$10();
|
|
16432
|
-
for (const [key, value] of entries) set$
|
|
16432
|
+
for (const [key, value] of entries) set$6(self, key, value);
|
|
16433
16433
|
return self;
|
|
16434
16434
|
};
|
|
16435
16435
|
/**
|
|
@@ -16521,7 +16521,7 @@ const getFromBucket = (self, bucket, key) => {
|
|
|
16521
16521
|
* @category mutations
|
|
16522
16522
|
* @since 2.0.0
|
|
16523
16523
|
*/
|
|
16524
|
-
const set$
|
|
16524
|
+
const set$6 = /*#__PURE__*/ dual(3, (self, key, value) => {
|
|
16525
16525
|
if (self.backing.has(key) || isSimpleKey(key)) {
|
|
16526
16526
|
self.backing.set(key, value);
|
|
16527
16527
|
return self;
|
|
@@ -23909,7 +23909,7 @@ const make$75 = (value) => {
|
|
|
23909
23909
|
* @category mutations
|
|
23910
23910
|
* @since 2.0.0
|
|
23911
23911
|
*/
|
|
23912
|
-
const set$
|
|
23912
|
+
const set$5 = /*#__PURE__*/ dual(2, (self, value) => {
|
|
23913
23913
|
self.current = value;
|
|
23914
23914
|
return self;
|
|
23915
23915
|
});
|
|
@@ -24481,7 +24481,7 @@ const makeAtomicUnbounded = (options) => {
|
|
|
24481
24481
|
* @since 2.0.0
|
|
24482
24482
|
*/
|
|
24483
24483
|
const shutdown$1 = (self) => uninterruptible(withFiber((fiber) => {
|
|
24484
|
-
set$
|
|
24484
|
+
set$5(self.shutdownFlag, true);
|
|
24485
24485
|
return close(self.scope, interrupt$2(fiber.id)).pipe(andThen(self.strategy.shutdown), when$2(self.shutdownHook.open), asVoid);
|
|
24486
24486
|
}));
|
|
24487
24487
|
/**
|
|
@@ -24637,7 +24637,7 @@ const subscribe = (self) => uninterruptible(contextWith((services) => {
|
|
|
24637
24637
|
return addFinalizer$1(scope, unsubscribe(subscription)).pipe(andThen(addFinalizerExit(localScope, (exit) => close(scope, exit))), as(subscription));
|
|
24638
24638
|
}));
|
|
24639
24639
|
const unsubscribe = (self) => uninterruptible(withFiber((state) => {
|
|
24640
|
-
set$
|
|
24640
|
+
set$5(self.shutdownFlag, true);
|
|
24641
24641
|
return forEach$1(takeAll$2(self.pollers), (d) => interruptWith(d, state.id), {
|
|
24642
24642
|
discard: true,
|
|
24643
24643
|
concurrency: "unbounded"
|
|
@@ -28735,7 +28735,7 @@ const get$10 = /*#__PURE__*/ dual(2, (self, key) => uninterruptibleMask((restore
|
|
|
28735
28735
|
refCount: 1
|
|
28736
28736
|
};
|
|
28737
28737
|
entry.finalizer = release$1(self, key, entry);
|
|
28738
|
-
set$
|
|
28738
|
+
set$6(state.map, key, entry);
|
|
28739
28739
|
const context = new Map(self.context.mapUnsafe);
|
|
28740
28740
|
parent.context.mapUnsafe.forEach((value, key) => {
|
|
28741
28741
|
context.set(key, value);
|
|
@@ -37729,6 +37729,42 @@ const make$58 = (value) => sync(() => makeUnsafe$2(value));
|
|
|
37729
37729
|
*/
|
|
37730
37730
|
const get$7 = (self) => sync(() => self.ref.current);
|
|
37731
37731
|
/**
|
|
37732
|
+
* Sets the value of the Ref to the specified value.
|
|
37733
|
+
*
|
|
37734
|
+
* **When to use**
|
|
37735
|
+
*
|
|
37736
|
+
* Use to replace the current `Ref` value with a known value.
|
|
37737
|
+
*
|
|
37738
|
+
* **Example** (Setting a value)
|
|
37739
|
+
*
|
|
37740
|
+
* ```ts import.meta.vitest
|
|
37741
|
+
* import { Effect, Ref } from "effect"
|
|
37742
|
+
*
|
|
37743
|
+
* const program = Effect.gen(function*() {
|
|
37744
|
+
* const ref = yield* Ref.make(0)
|
|
37745
|
+
* yield* Ref.set(ref, 42)
|
|
37746
|
+
* return yield* Ref.get(ref)
|
|
37747
|
+
* })
|
|
37748
|
+
*
|
|
37749
|
+
* const program2 = Effect.gen(function*() {
|
|
37750
|
+
* const ref = yield* Ref.make(0)
|
|
37751
|
+
* yield* Ref.set(ref, 100)
|
|
37752
|
+
* return yield* Ref.get(ref)
|
|
37753
|
+
* })
|
|
37754
|
+
*
|
|
37755
|
+
* await Effect.runPromise(program) // => 42
|
|
37756
|
+
* await Effect.runPromise(program2) // => 100
|
|
37757
|
+
* ```
|
|
37758
|
+
*
|
|
37759
|
+
* @see {@link getAndSet} for setting while returning the previous value
|
|
37760
|
+
* @see {@link setAndGet} for setting while returning the new value
|
|
37761
|
+
*
|
|
37762
|
+
* @stability stable
|
|
37763
|
+
* @category mutations
|
|
37764
|
+
* @since 2.0.0
|
|
37765
|
+
*/
|
|
37766
|
+
const set$4 = /*#__PURE__*/ dual(2, (self, value) => sync(() => set$5(self.ref, value)));
|
|
37767
|
+
/**
|
|
37732
37768
|
* Modifies the value of the Ref atomically using the given function.
|
|
37733
37769
|
*
|
|
37734
37770
|
* **When to use**
|
|
@@ -38143,7 +38179,7 @@ const makeCookieUnsafe = (name, value, options) => getOrThrow(makeCookie(name, v
|
|
|
38143
38179
|
* @category combinators
|
|
38144
38180
|
* @since 4.0.0
|
|
38145
38181
|
*/
|
|
38146
|
-
const setUnsafe$1 = /*#__PURE__*/ dual((args) => isCookies(args[0]), (self, name, value, options) => fromReadonlyRecord(set$
|
|
38182
|
+
const setUnsafe$1 = /*#__PURE__*/ dual((args) => isCookies(args[0]), (self, name, value, options) => fromReadonlyRecord(set$7(self.cookies, name, makeCookieUnsafe(name, value, options))));
|
|
38147
38183
|
/**
|
|
38148
38184
|
* Adds an expired cookie to a Cookies object, throwing an error if invalid
|
|
38149
38185
|
*
|
|
@@ -47658,6 +47694,25 @@ function Redacted$1(value, options) {
|
|
|
47658
47694
|
});
|
|
47659
47695
|
return make$51(schema.ast, { value });
|
|
47660
47696
|
}
|
|
47697
|
+
/**
|
|
47698
|
+
* Decodes a value and wraps it in `Redacted<A>`. Unlike {@link Redacted} which
|
|
47699
|
+
* expects the input to already be a `Redacted` instance, this schema decodes
|
|
47700
|
+
* the raw value and wraps it.
|
|
47701
|
+
*
|
|
47702
|
+
* @see {@link Redacted} for schemas whose input is already a `Redacted` value.
|
|
47703
|
+
* @stability stable
|
|
47704
|
+
* @category schemas
|
|
47705
|
+
* @since 4.0.0
|
|
47706
|
+
*/
|
|
47707
|
+
function RedactedFromValue(value, options) {
|
|
47708
|
+
return decodeTo(Redacted$1(toType(value), {
|
|
47709
|
+
label: options?.label,
|
|
47710
|
+
disallowJsonEncode: options?.disallowEncode
|
|
47711
|
+
}), {
|
|
47712
|
+
decode: transform$3((t) => make$61(t, { label: options?.label })),
|
|
47713
|
+
encode: options?.disallowEncode ? forbidden((oe) => "Cannot encode Redacted" + (isSome(oe) && typeof oe.value.label === "string" ? ` with label: "${oe.value.label}"` : "")) : transform$3(value$2)
|
|
47714
|
+
})(value);
|
|
47715
|
+
}
|
|
47661
47716
|
const immerable = /*#__PURE__*/ globalThis.Symbol.for("immer-draftable");
|
|
47662
47717
|
const payloadToken = {};
|
|
47663
47718
|
function makeClass(Inherited, identifier, struct$1, annotations, proto) {
|
|
@@ -49007,6 +49062,14 @@ const compressBody = /*#__PURE__*/ dual((args) => isHttpClientRequest(args[0]),
|
|
|
49007
49062
|
return map$5(compressBody$1(self.body, algorithm, options), (body) => body === self.body ? self : makeWith$2(self.method, self.url, self.urlParams, self.hash, set$3(updateContentLength(self.headers, body), "content-encoding", algorithm), body));
|
|
49008
49063
|
});
|
|
49009
49064
|
/**
|
|
49065
|
+
* Encodes a value as a JSON request body and sets it on the request, failing with `HttpBodyError` if encoding fails.
|
|
49066
|
+
*
|
|
49067
|
+
* @stability unstable
|
|
49068
|
+
* @category combinators
|
|
49069
|
+
* @since 4.0.0
|
|
49070
|
+
*/
|
|
49071
|
+
const bodyJson = /*#__PURE__*/ dual(2, (self, body) => map$5(json$1(body), (body) => setBody$1(self, body)));
|
|
49072
|
+
/**
|
|
49010
49073
|
* Sets a JSON request body using unsafe JSON encoding.
|
|
49011
49074
|
*
|
|
49012
49075
|
* **When to use**
|
|
@@ -49580,6 +49643,14 @@ const endSpanWithStatusError = (fiber, span, request, response) => {
|
|
|
49580
49643
|
span.end(fiber.getRef(TracerTimingEnabled) ? fiber.getRef(Clock).currentTimeNanosUnsafe() : BigInt(0), exit);
|
|
49581
49644
|
};
|
|
49582
49645
|
/**
|
|
49646
|
+
* Appends an effectful transformation of the request object before sending it.
|
|
49647
|
+
*
|
|
49648
|
+
* @stability unstable
|
|
49649
|
+
* @category mapping
|
|
49650
|
+
* @since 4.0.0
|
|
49651
|
+
*/
|
|
49652
|
+
const mapRequestEffect = /*#__PURE__*/ dual(2, (self, f) => makeWith$1(self.postprocess, (request) => flatMap$2(self.preprocess(request), f)));
|
|
49653
|
+
/**
|
|
49583
49654
|
* Retries common transient errors, such as rate limiting, timeouts or network issues.
|
|
49584
49655
|
*
|
|
49585
49656
|
* **When to use**
|
|
@@ -68684,7 +68755,7 @@ const get$2 = /*#__PURE__*/ dual(2, (self, key) => withFiber$1((fiber) => {
|
|
|
68684
68755
|
if (isSome(oentry)) {
|
|
68685
68756
|
remove$5(self.map, key);
|
|
68686
68757
|
if (!hasExpired(oentry.value, fiber)) {
|
|
68687
|
-
set$
|
|
68758
|
+
set$6(self.map, key, oentry.value);
|
|
68688
68759
|
return oentry.value.await(fiber);
|
|
68689
68760
|
}
|
|
68690
68761
|
}
|
|
@@ -68704,7 +68775,7 @@ const get$2 = /*#__PURE__*/ dual(2, (self, key) => withFiber$1((fiber) => {
|
|
|
68704
68775
|
} else if (isFinite$1(ttl)) entry.expiresAt = fiber.getRef(ClockRef).currentTimeMillisUnsafe() + toMillis(ttl);
|
|
68705
68776
|
});
|
|
68706
68777
|
const exit = entry.fiber.pollUnsafe();
|
|
68707
|
-
if (!skipCache && (exit === void 0 || !exitHasInterrupts(exit))) set$
|
|
68778
|
+
if (!skipCache && (exit === void 0 || !exitHasInterrupts(exit))) set$6(self.map, key, entry);
|
|
68708
68779
|
if (Number.isFinite(self.capacity)) checkCapacity(self);
|
|
68709
68780
|
return entry.await(fiber);
|
|
68710
68781
|
}));
|
|
@@ -68869,7 +68940,7 @@ const set = /*#__PURE__*/ dual(3, (self, key, value) => withFiber$1((fiber) => {
|
|
|
68869
68940
|
return void_$3;
|
|
68870
68941
|
}
|
|
68871
68942
|
entry.expiresAt = isFinite$1(ttl) ? fiber.getRef(ClockRef).currentTimeMillisUnsafe() + toMillis(ttl) : void 0;
|
|
68872
|
-
set$
|
|
68943
|
+
set$6(self.map, key, entry);
|
|
68873
68944
|
checkCapacity(self);
|
|
68874
68945
|
return void_$3;
|
|
68875
68946
|
}));
|
|
@@ -89440,6 +89511,71 @@ function failureOptions(error, status) {
|
|
|
89440
89511
|
}
|
|
89441
89512
|
var CurrentUser = class extends Service$1()("@deslop/runtime/auth/lib/utils/CurrentUser") {};
|
|
89442
89513
|
var RpcAuth = class extends Service()("@deslop/runtime/auth/lib/utils/RpcAuth", { error: AuthError }) {};
|
|
89514
|
+
Literals([
|
|
89515
|
+
"anthropic",
|
|
89516
|
+
"openrouter",
|
|
89517
|
+
"opencode-zen",
|
|
89518
|
+
"opencode-go"
|
|
89519
|
+
]);
|
|
89520
|
+
// ../../packages/runtime/src/ai/service.ts
|
|
89521
|
+
var AiUnavailable = class extends TaggedError()("AiUnavailable", { message: String$6 }) {};
|
|
89522
|
+
fromJsonString(Struct({ error: Struct({ message: String$6 }) }));
|
|
89523
|
+
var AiGateway = class AiGateway extends Service$1()("@deslop/runtime/ai/service/AiGateway") {
|
|
89524
|
+
static layer = effect(this, gen(function* () {
|
|
89525
|
+
const gateway = yield* option(String$5("GATEWAY_URL"));
|
|
89526
|
+
const local = yield* localAuth;
|
|
89527
|
+
const app = yield* String$5("APP_URL");
|
|
89528
|
+
const client = yield* HttpClient;
|
|
89529
|
+
const store = toSchemaStore(yield* KeyValueStore, Record$1(String$6, RedactedFromValue(String$6)));
|
|
89530
|
+
const grants = yield* make$58(getOrElse(yield* store.get("ai-gateway-grants"), () => ({})));
|
|
89531
|
+
const lock = yield* make$71(1);
|
|
89532
|
+
return AiGateway.of({
|
|
89533
|
+
apiUrl: (provider) => match$8(gateway, {
|
|
89534
|
+
onNone: () => fail$7(AiUnavailable.make({ message: "Start the app with --gateway" })),
|
|
89535
|
+
onSome: (url) => succeed$5(`${url}/ai/${provider}${match$1(provider === "openrouter", {
|
|
89536
|
+
onFalse: () => "",
|
|
89537
|
+
onTrue: () => "/v1"
|
|
89538
|
+
})}`)
|
|
89539
|
+
}),
|
|
89540
|
+
authorize: (userId) => (http) => pipe(mapRequestEffect(http, (request) => gen(function* () {
|
|
89541
|
+
if (local) return request;
|
|
89542
|
+
const token = (yield* get$7(grants))[userId];
|
|
89543
|
+
if (token === void 0) return yield* new HttpClientError({ reason: new TransportError({
|
|
89544
|
+
description: "AI access is unavailable; sign in again to enroll with Gateway",
|
|
89545
|
+
request
|
|
89546
|
+
}) });
|
|
89547
|
+
return setHeader$1(request, "authorization", `Bearer ${value$2(token)}`);
|
|
89548
|
+
})), tap((response) => pipe(gen(function* () {
|
|
89549
|
+
if (local || response.headers["x-gateway-grant-refused"] === void 0 || !exists(gateway, (url) => startsWith(`${url}/ai/`)(response.request.url))) return;
|
|
89550
|
+
const current = yield* get$7(grants);
|
|
89551
|
+
const token = current[userId];
|
|
89552
|
+
if (token === void 0 || response.request.headers["authorization"] !== `Bearer ${value$2(token)}`) return;
|
|
89553
|
+
const next = remove$6(current, userId);
|
|
89554
|
+
yield* pipe(store.set("ai-gateway-grants", next), ignore$1({
|
|
89555
|
+
log: "Warn",
|
|
89556
|
+
message: "The rejected AI grant could not be removed from storage"
|
|
89557
|
+
}));
|
|
89558
|
+
yield* set$4(grants, next);
|
|
89559
|
+
}), withPermit(lock)))),
|
|
89560
|
+
enroll: fnUntraced(function* (userId, headers) {
|
|
89561
|
+
return yield* pipe(gen(function* () {
|
|
89562
|
+
if (local || isNone(gateway) || (yield* get$7(grants))[userId] !== void 0) return;
|
|
89563
|
+
const response = yield* client.execute(yield* bodyJson(post(`${getOrElse(gateway, () => "")}/ai/grants`, { headers: match$1(headers["authorization"] !== void 0, {
|
|
89564
|
+
onFalse: () => ({ cookie: headers["cookie"] ?? "" }),
|
|
89565
|
+
onTrue: () => ({ authorization: headers["authorization"] })
|
|
89566
|
+
}) }), { app }));
|
|
89567
|
+
const result = yield* schemaBodyJson$1(Struct({ token: String$6 }))(response);
|
|
89568
|
+
const next = {
|
|
89569
|
+
...yield* get$7(grants),
|
|
89570
|
+
[userId]: make$61(result.token)
|
|
89571
|
+
};
|
|
89572
|
+
yield* store.set("ai-gateway-grants", next);
|
|
89573
|
+
yield* set$4(grants, next);
|
|
89574
|
+
}), withPermit(lock), timeout$1("10 seconds"), catch_$2(() => logWarning("AI Gateway enrollment failed")));
|
|
89575
|
+
})
|
|
89576
|
+
});
|
|
89577
|
+
}));
|
|
89578
|
+
};
|
|
89443
89579
|
// ../../packages/runtime/src/auth/service.ts
|
|
89444
89580
|
function rejected(message) {
|
|
89445
89581
|
return mapError$2((cause) => {
|
|
@@ -89458,12 +89594,18 @@ function rejected(message) {
|
|
|
89458
89594
|
function developer() {
|
|
89459
89595
|
return succeed$5(DEVELOPER);
|
|
89460
89596
|
}
|
|
89597
|
+
function enrolled(user, headers) {
|
|
89598
|
+
return gen(function* () {
|
|
89599
|
+
const gateway = getOrUndefined(yield* context(), AiGateway);
|
|
89600
|
+
if (gateway !== void 0) yield* gateway.enroll(user.id, headers);
|
|
89601
|
+
});
|
|
89602
|
+
}
|
|
89461
89603
|
const unavailable = text("The authorization service is temporarily unavailable; retry later", {
|
|
89462
89604
|
headers: { "retry-after": "5" },
|
|
89463
89605
|
status: 503
|
|
89464
89606
|
});
|
|
89465
89607
|
var Auth = class Auth extends Service$1()("@deslop/runtime/auth/service/Auth") {
|
|
89466
|
-
static makeContext = (auth) => pipe(make$85(Auth, auth), add$1(RpcAuth, RpcAuth.of((effect, request) => pipe(auth.user(request.headers), tap$1(() => {
|
|
89608
|
+
static makeContext = (auth) => pipe(make$85(Auth, auth), add$1(RpcAuth, RpcAuth.of((effect, request) => pipe(auth.user(request.headers), tap$1((user) => enrolled(user, request.headers)), tap$1(() => {
|
|
89467
89609
|
if (isStreamSchema(request.rpc.successSchema)) return annotateCurrentSpan("rpc.stream", true);
|
|
89468
89610
|
return void_$1;
|
|
89469
89611
|
}), flatMap$2((user) => raceFirst(provideService(effect, CurrentUser, user), pipe(delay(auth.user(request.headers), "5 minutes"), retry({ while: (error) => error.error === "temporarily_unavailable" }), forever)))))));
|
|
@@ -89498,6 +89640,7 @@ middleware$1()(gen(function* () {
|
|
|
89498
89640
|
if (user.failure.error === "temporarily_unavailable") return unavailable;
|
|
89499
89641
|
return text("Sign in first", { status: 401 });
|
|
89500
89642
|
}
|
|
89643
|
+
yield* enrolled(user.success, (yield* HttpServerRequest).headers);
|
|
89501
89644
|
return yield* provideService(app, CurrentUser, user.success);
|
|
89502
89645
|
});
|
|
89503
89646
|
}));
|
|
@@ -89520,6 +89663,7 @@ function layerMcpAuth(resource) {
|
|
|
89520
89663
|
status: 401
|
|
89521
89664
|
});
|
|
89522
89665
|
}
|
|
89666
|
+
yield* enrolled(user.success, headers);
|
|
89523
89667
|
return yield* provideService(app, CurrentUser, user.success);
|
|
89524
89668
|
});
|
|
89525
89669
|
})).layer;
|
|
@@ -89910,6 +90054,11 @@ const SETTINGS = {
|
|
|
89910
90054
|
flag: "auth",
|
|
89911
90055
|
schema: SecureOrigin
|
|
89912
90056
|
},
|
|
90057
|
+
GATEWAY_URL: {
|
|
90058
|
+
description: "Deslop Gateway origin for AI calls",
|
|
90059
|
+
flag: "gateway",
|
|
90060
|
+
schema: Origin$1
|
|
90061
|
+
},
|
|
89913
90062
|
HOST: {
|
|
89914
90063
|
description: `Listen address; defaults to ${DEFAULT_HOST}`,
|
|
89915
90064
|
flag: "host",
|
|
@@ -89945,7 +90094,7 @@ function server(app) {
|
|
|
89945
90094
|
return pipe(serve(pipe(mergeAll$1(app.routes, layerRoutes, layerIcon(app.icon), layerWeb, layerAnnounce), provide$2(match$8(fromUndefinedOr(app.middleware), {
|
|
89946
90095
|
onNone: () => empty$11,
|
|
89947
90096
|
onSome: (middleware) => middleware$1()(middleware).layer
|
|
89948
|
-
})), provide$2(Auth.layer)), {
|
|
90097
|
+
})), provide$2(Auth.layer), provideMerge(pipe(AiGateway.layer, provide$2(layerDataStore)))), {
|
|
89949
90098
|
disableLogger: true,
|
|
89950
90099
|
middleware: guard
|
|
89951
90100
|
}), provide$2(mergeAll$1(layerProtocol, match$1(app.telemetry === false, {
|
|
@@ -90536,7 +90685,7 @@ base64.validate = (encoded, urlMode) => {
|
|
|
90536
90685
|
}
|
|
90537
90686
|
};
|
|
90538
90687
|
base64.base64 = base64;
|
|
90539
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
90688
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoBase64URL.js
|
|
90540
90689
|
/**
|
|
90541
90690
|
* A runtime-agnostic collection of methods for working with Base64URL encoding
|
|
90542
90691
|
* @module
|
|
@@ -90946,7 +91095,7 @@ function encodeCBOR(data) {
|
|
|
90946
91095
|
}
|
|
90947
91096
|
return output;
|
|
90948
91097
|
}
|
|
90949
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
91098
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCBOR.js
|
|
90950
91099
|
/**
|
|
90951
91100
|
* A runtime-agnostic collection of methods for working with CBOR encoding
|
|
90952
91101
|
* @module
|
|
@@ -90978,7 +91127,7 @@ function decodeFirst(input) {
|
|
|
90978
91127
|
function encode(input) {
|
|
90979
91128
|
return encodeCBOR(input);
|
|
90980
91129
|
}
|
|
90981
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
91130
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/cose.js
|
|
90982
91131
|
/**
|
|
90983
91132
|
* A type guard for determining if a COSE public key is an OKP key pair
|
|
90984
91133
|
*/
|
|
@@ -91088,7 +91237,7 @@ function isPQCCOSEAlg(alg) {
|
|
|
91088
91237
|
COSEALG.ML_DSA_87
|
|
91089
91238
|
].indexOf(alg) >= 0;
|
|
91090
91239
|
}
|
|
91091
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
91240
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoHashAlgName.js
|
|
91092
91241
|
/**
|
|
91093
91242
|
* Convert a COSE alg ID into a corresponding hash algorithm string value that WebCrypto APIs expect
|
|
91094
91243
|
*
|
|
@@ -91115,7 +91264,7 @@ function mapCoseAlgToWebCryptoHashAlgName(alg) {
|
|
|
91115
91264
|
].indexOf(alg) >= 0) return "SHA-512";
|
|
91116
91265
|
throw new Error(`Could not map COSE alg value of ${alg} to a WebCrypto hash alg name`);
|
|
91117
91266
|
}
|
|
91118
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
91267
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/getWebCrypto.js
|
|
91119
91268
|
let webCrypto = void 0;
|
|
91120
91269
|
/**
|
|
91121
91270
|
* Try to get an instance of the Crypto API from the current runtime. Should support Node,
|
|
@@ -91160,7 +91309,7 @@ const _getWebCryptoInternals = {
|
|
|
91160
91309
|
webCrypto = newCrypto;
|
|
91161
91310
|
}
|
|
91162
91311
|
};
|
|
91163
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
91312
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/digest.js
|
|
91164
91313
|
/**
|
|
91165
91314
|
* Generate a digest of the provided data.
|
|
91166
91315
|
*
|
|
@@ -91173,7 +91322,7 @@ async function digest(data, algorithm) {
|
|
|
91173
91322
|
const hashed = await WebCrypto.subtle.digest(subtleAlgorithm, data);
|
|
91174
91323
|
return new Uint8Array(hashed);
|
|
91175
91324
|
}
|
|
91176
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
91325
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/getRandomValues.js
|
|
91177
91326
|
/**
|
|
91178
91327
|
* Fill up the provided bytes array with random bytes equal to its length.
|
|
91179
91328
|
*
|
|
@@ -91183,7 +91332,7 @@ async function getRandomValues(array) {
|
|
|
91183
91332
|
(await getWebCrypto()).getRandomValues(array);
|
|
91184
91333
|
return array;
|
|
91185
91334
|
}
|
|
91186
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
91335
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/convertAAGUIDToString.js
|
|
91187
91336
|
/**
|
|
91188
91337
|
* Convert the aaguid buffer in authData into a UUID string
|
|
91189
91338
|
*/
|
|
@@ -91197,7 +91346,7 @@ function convertAAGUIDToString(aaguid) {
|
|
|
91197
91346
|
hex.slice(20, 32)
|
|
91198
91347
|
].join("-");
|
|
91199
91348
|
}
|
|
91200
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
91349
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/convertCOSEtoPKCS.js
|
|
91201
91350
|
/**
|
|
91202
91351
|
* Takes COSE-encoded public key and converts it to PKCS key
|
|
91203
91352
|
*/
|
|
@@ -91214,7 +91363,7 @@ function convertCOSEtoPKCS(cosePublicKey) {
|
|
|
91214
91363
|
]);
|
|
91215
91364
|
return concat([tag, x]);
|
|
91216
91365
|
}
|
|
91217
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
91366
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/decodeAttestationObject.js
|
|
91218
91367
|
/**
|
|
91219
91368
|
* Convert an AttestationObject buffer to a proper object
|
|
91220
91369
|
*
|
|
@@ -91228,7 +91377,7 @@ function decodeAttestationObject(attestationObject) {
|
|
|
91228
91377
|
* @ignore Don't include this in docs output
|
|
91229
91378
|
*/
|
|
91230
91379
|
const _decodeAttestationObjectInternals = { stubThis: (value) => value };
|
|
91231
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
91380
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/decodeClientDataJSON.js
|
|
91232
91381
|
/**
|
|
91233
91382
|
* Decode an authenticator's base64url-encoded clientDataJSON to JSON
|
|
91234
91383
|
*/
|
|
@@ -91242,7 +91391,7 @@ function decodeClientDataJSON(data) {
|
|
|
91242
91391
|
* @ignore Don't include this in docs output
|
|
91243
91392
|
*/
|
|
91244
91393
|
const _decodeClientDataJSONInternals = { stubThis: (value) => value };
|
|
91245
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
91394
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/decodeCredentialPublicKey.js
|
|
91246
91395
|
function decodeCredentialPublicKey(publicKey) {
|
|
91247
91396
|
return _decodeCredentialPublicKeyInternals.stubThis(decodeFirst(publicKey));
|
|
91248
91397
|
}
|
|
@@ -91251,7 +91400,7 @@ function decodeCredentialPublicKey(publicKey) {
|
|
|
91251
91400
|
* @ignore Don't include this in docs output
|
|
91252
91401
|
*/
|
|
91253
91402
|
const _decodeCredentialPublicKeyInternals = { stubThis: (value) => value };
|
|
91254
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
91403
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/generateChallenge.js
|
|
91255
91404
|
/**
|
|
91256
91405
|
* Generate a suitably random value to be used as an attestation or assertion challenge
|
|
91257
91406
|
*/
|
|
@@ -91273,7 +91422,7 @@ async function generateChallenge() {
|
|
|
91273
91422
|
* @ignore Don't include this in docs output
|
|
91274
91423
|
*/
|
|
91275
91424
|
const _generateChallengeInternals = { stubThis: (value) => value };
|
|
91276
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
91425
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/generateUserID.js
|
|
91277
91426
|
/**
|
|
91278
91427
|
* Generate a suitably random value to be used as user ID
|
|
91279
91428
|
*/
|
|
@@ -99678,7 +99827,7 @@ var require_cjs$12 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
99678
99827
|
tslib_1.__exportStar(require_types$3(), exports);
|
|
99679
99828
|
tslib_1.__exportStar(require_validity(), exports);
|
|
99680
99829
|
}));
|
|
99681
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
99830
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/getCertificateInfo.js
|
|
99682
99831
|
var import_cjs$4 = require_cjs$13();
|
|
99683
99832
|
var import_cjs$5 = require_cjs$12();
|
|
99684
99833
|
const issuerSubjectIDKey = {
|
|
@@ -107916,15 +108065,15 @@ var import_x509_cjs = require_x509_cjs();
|
|
|
107916
108065
|
* A simple method for requesting data via standard `fetch`. Should work
|
|
107917
108066
|
* across multiple runtimes.
|
|
107918
108067
|
*/
|
|
107919
|
-
function fetch(
|
|
107920
|
-
return _fetchInternals.stubThis(
|
|
108068
|
+
function fetch(...args) {
|
|
108069
|
+
return _fetchInternals.stubThis(...args);
|
|
107921
108070
|
}
|
|
107922
108071
|
/**
|
|
107923
108072
|
* Make it possible to stub the return value during testing
|
|
107924
108073
|
* @ignore Don't include this in docs output
|
|
107925
108074
|
*/
|
|
107926
|
-
const _fetchInternals = { stubThis: (
|
|
107927
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
108075
|
+
const _fetchInternals = { stubThis: (...args) => globalThis.fetch(...args) };
|
|
108076
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/isCertRevoked.js
|
|
107928
108077
|
const cacheRevokedCerts = {};
|
|
107929
108078
|
/**
|
|
107930
108079
|
* A method to pull a CRL from a certificate and compare its serial number to the list of revoked
|
|
@@ -107992,7 +108141,7 @@ async function getIssuerKeyIdentifier(issuer) {
|
|
|
107992
108141
|
fromExtension: false
|
|
107993
108142
|
};
|
|
107994
108143
|
}
|
|
107995
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
108144
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/decodeAuthenticatorExtensions.js
|
|
107996
108145
|
/**
|
|
107997
108146
|
* Convert authenticator extension data buffer to a proper object
|
|
107998
108147
|
*
|
|
@@ -108018,7 +108167,7 @@ function convertMapToObjectDeep(input) {
|
|
|
108018
108167
|
else mapped[key] = value;
|
|
108019
108168
|
return mapped;
|
|
108020
108169
|
}
|
|
108021
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
108170
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/parseAuthenticatorData.js
|
|
108022
108171
|
/**
|
|
108023
108172
|
* Make sense of the authData buffer contained in an Attestation
|
|
108024
108173
|
*/
|
|
@@ -108108,16 +108257,16 @@ function parseAuthenticatorData(authData) {
|
|
|
108108
108257
|
* @ignore Don't include this in docs output
|
|
108109
108258
|
*/
|
|
108110
108259
|
const _parseAuthenticatorDataInternals = { stubThis: (value) => value };
|
|
108111
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
108260
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/toHash.js
|
|
108112
108261
|
/**
|
|
108113
|
-
* Returns hash
|
|
108114
|
-
* SHA-256.
|
|
108262
|
+
* Returns the hash of the given data, using the given algorithm when provided. If `data` is
|
|
108263
|
+
* a string, then it's treated like a UTF-8 string. Defaults to hashing using SHA-256.
|
|
108115
108264
|
*/
|
|
108116
108265
|
function toHash(data, algorithm = -7) {
|
|
108117
108266
|
if (typeof data === "string") data = fromUTF8String(data);
|
|
108118
108267
|
return digest(data, algorithm);
|
|
108119
108268
|
}
|
|
108120
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
108269
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoKeyAlgName.js
|
|
108121
108270
|
/**
|
|
108122
108271
|
* Convert a COSE alg ID into a corresponding key algorithm string value that WebCrypto APIs expect
|
|
108123
108272
|
*
|
|
@@ -108148,7 +108297,7 @@ function mapCoseAlgToWebCryptoKeyAlgName(alg) {
|
|
|
108148
108297
|
else if ([COSEALG.ML_DSA_87].indexOf(alg) >= 0) return "ML-DSA-87";
|
|
108149
108298
|
throw new Error(`Could not map COSE alg value of ${alg} to a WebCrypto key alg name`);
|
|
108150
108299
|
}
|
|
108151
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
108300
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/errors/index.js
|
|
108152
108301
|
/**
|
|
108153
108302
|
* Base error class that helps disambiguate SimpleWebAuthn library errors from other library errors
|
|
108154
108303
|
*/
|
|
@@ -108174,7 +108323,7 @@ var PQCNotSupportedError = class extends SimpleWebAuthnError {
|
|
|
108174
108323
|
});
|
|
108175
108324
|
}
|
|
108176
108325
|
};
|
|
108177
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
108326
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/validateCertificatePath.js
|
|
108178
108327
|
/**
|
|
108179
108328
|
* Traverse an array of PEM certificates and ensure they form a proper chain
|
|
108180
108329
|
* @param x5cCertsPEM Typically the result of `x5c.map(convertASN1toPEM)`
|
|
@@ -108294,7 +108443,7 @@ function assertCertIsWithinValidTimeWindow(certificate) {
|
|
|
108294
108443
|
const now = new Date(Date.now());
|
|
108295
108444
|
if (certNotBefore > now || certNotAfter < now) throw new Error("Certificate is not yet valid or expired");
|
|
108296
108445
|
}
|
|
108297
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
108446
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/mapX509SignatureAlgToCOSEAlg.js
|
|
108298
108447
|
var import_cjs$1 = require_cjs$9();
|
|
108299
108448
|
var import_cjs$2 = require_cjs$8();
|
|
108300
108449
|
var import_cjs$3 = require_cjs$2();
|
|
@@ -108316,7 +108465,7 @@ function mapX509SignatureAlgToCOSEAlg(signatureAlgorithm) {
|
|
|
108316
108465
|
else throw new Error(`Unable to map X.509 signature algorithm ${signatureAlgorithm} to a COSE algorithm`);
|
|
108317
108466
|
return alg;
|
|
108318
108467
|
}
|
|
108319
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
108468
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/convertX509PublicKeyToCOSE.js
|
|
108320
108469
|
function convertX509PublicKeyToCOSE(x509Certificate) {
|
|
108321
108470
|
let cosePublicKey = /* @__PURE__ */ new Map();
|
|
108322
108471
|
const { tbsCertificate } = import_cjs$4.AsnParser.parse(x509Certificate, import_cjs$5.Certificate);
|
|
@@ -108384,7 +108533,7 @@ function convertX509PublicKeyToCOSE(x509Certificate) {
|
|
|
108384
108533
|
} else throw new Error(`Certificate public key contained unexpected algorithm ID ${publicKeyAlgorithmID}`);
|
|
108385
108534
|
return cosePublicKey;
|
|
108386
108535
|
}
|
|
108387
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
108536
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/verifySignature.js
|
|
108388
108537
|
/**
|
|
108389
108538
|
* Verify an authenticator's signature
|
|
108390
108539
|
*/
|
|
@@ -108407,7 +108556,7 @@ function verifySignature(opts) {
|
|
|
108407
108556
|
* @ignore Don't include this in docs output
|
|
108408
108557
|
*/
|
|
108409
108558
|
const _verifySignatureInternals = { stubThis: (value) => value };
|
|
108410
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
108559
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/metadata/parseJWT.js
|
|
108411
108560
|
/**
|
|
108412
108561
|
* Process a JWT into Javascript-friendly data structures
|
|
108413
108562
|
*/
|
|
@@ -108419,7 +108568,7 @@ function parseJWT(jwt) {
|
|
|
108419
108568
|
parts[2]
|
|
108420
108569
|
];
|
|
108421
108570
|
}
|
|
108422
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
108571
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/mapJWSAlgToCOSEAlg.js
|
|
108423
108572
|
/**
|
|
108424
108573
|
* Map JWS algorithms to COSE algorithm IDs
|
|
108425
108574
|
*
|
|
@@ -108436,7 +108585,7 @@ function mapJWSAlgToCOSEAlg(alg) {
|
|
|
108436
108585
|
else throw new Error(`Unable to map JWS algorithm "${alg}" to a COSE algorithm`);
|
|
108437
108586
|
return algCOSE;
|
|
108438
108587
|
}
|
|
108439
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
108588
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/importJWKKey.js
|
|
108440
108589
|
/**
|
|
108441
108590
|
* Convert a JWK-formatted public key into a WebCrypto CryptoKey that can be used for
|
|
108442
108591
|
* signature verification
|
|
@@ -108446,7 +108595,7 @@ async function importJWKKey(opts) {
|
|
|
108446
108595
|
const { keyData, algorithm } = opts;
|
|
108447
108596
|
return WebCrypto.subtle.importKey("jwk", keyData, algorithm, false, ["verify"]);
|
|
108448
108597
|
}
|
|
108449
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
108598
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/verifyEC2.js
|
|
108450
108599
|
/**
|
|
108451
108600
|
* Verify a signature using an EC2 public key
|
|
108452
108601
|
*/
|
|
@@ -108493,7 +108642,7 @@ async function verifyEC2(opts) {
|
|
|
108493
108642
|
};
|
|
108494
108643
|
return WebCrypto.subtle.verify(verifyAlgorithm, key, signature, data);
|
|
108495
108644
|
}
|
|
108496
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
108645
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/verifyRSA.js
|
|
108497
108646
|
/**
|
|
108498
108647
|
* Verify a signature using an RSA public key
|
|
108499
108648
|
*/
|
|
@@ -108553,7 +108702,7 @@ async function verifyRSA(opts) {
|
|
|
108553
108702
|
});
|
|
108554
108703
|
return WebCrypto.subtle.verify(verifyAlgorithm, key, signature, data);
|
|
108555
108704
|
}
|
|
108556
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
108705
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/metadata/verifyJWT.js
|
|
108557
108706
|
/**
|
|
108558
108707
|
* Lightweight verification for FIDO MDS JWTs. Supports use of EC2 and RSA.
|
|
108559
108708
|
*
|
|
@@ -108584,14 +108733,14 @@ function verifyJWT(jwt, leafCert) {
|
|
|
108584
108733
|
const kty = certCOSE.get(COSEKEYS.kty);
|
|
108585
108734
|
throw new Error(`JWT verification with public key of kty ${kty} is not supported by this method`);
|
|
108586
108735
|
}
|
|
108587
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
108736
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/convertPEMToBytes.js
|
|
108588
108737
|
/**
|
|
108589
108738
|
* Take a certificate in PEM format and convert it to bytes
|
|
108590
108739
|
*/
|
|
108591
108740
|
function convertPEMToBytes(pem) {
|
|
108592
108741
|
return toBuffer(pem.replace("-----BEGIN CERTIFICATE-----", "").replace("-----END CERTIFICATE-----", "").replace(/[\n ]/g, ""), "base64");
|
|
108593
108742
|
}
|
|
108594
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
108743
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/metadata/verifyMDSBlob.js
|
|
108595
108744
|
/**
|
|
108596
108745
|
* Perform authenticity and integrity verification of a
|
|
108597
108746
|
* [FIDO Metadata Service (MDS)](https://fidoalliance.org/metadata/)-compatible blob, and then
|
|
@@ -108621,7 +108770,7 @@ async function verifyMDSBlob(blob) {
|
|
|
108621
108770
|
payload
|
|
108622
108771
|
};
|
|
108623
108772
|
}
|
|
108624
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
108773
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/verifyAKP.js
|
|
108625
108774
|
/** AKP, a.k.a ML-DSA */
|
|
108626
108775
|
async function verifyAKP(opts) {
|
|
108627
108776
|
const { cosePublicKey, signature, data } = opts;
|
|
@@ -108654,7 +108803,7 @@ async function verifyAKP(opts) {
|
|
|
108654
108803
|
}
|
|
108655
108804
|
return WebCrypto.subtle.verify(webCryptoAlg, key, signature, data);
|
|
108656
108805
|
}
|
|
108657
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
108806
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/verifyOKP.js
|
|
108658
108807
|
async function verifyOKP(opts) {
|
|
108659
108808
|
const { cosePublicKey, signature, data } = opts;
|
|
108660
108809
|
const WebCrypto = await getWebCrypto();
|
|
@@ -108684,7 +108833,7 @@ async function verifyOKP(opts) {
|
|
|
108684
108833
|
const verifyAlgorithm = { name: _crv };
|
|
108685
108834
|
return WebCrypto.subtle.verify(verifyAlgorithm, key, signature, data);
|
|
108686
108835
|
}
|
|
108687
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
108836
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/unwrapEC2Signature.js
|
|
108688
108837
|
/**
|
|
108689
108838
|
* In WebAuthn, EC2 signatures are wrapped in ASN.1 structure so we need to peel r and s apart.
|
|
108690
108839
|
*
|
|
@@ -108734,7 +108883,7 @@ function toNormalizedBytes(bytes, componentLength) {
|
|
|
108734
108883
|
else throw new Error(`Invalid signature component length ${bytes.length}, expected ${componentLength}`);
|
|
108735
108884
|
return normalizedBytes;
|
|
108736
108885
|
}
|
|
108737
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
108886
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/verify.js
|
|
108738
108887
|
/**
|
|
108739
108888
|
* Verify signatures with their public key. Supports EC2 and RSA public keys.
|
|
108740
108889
|
*/
|
|
@@ -108768,7 +108917,7 @@ function verify(opts) {
|
|
|
108768
108917
|
const kty = cosePublicKey.get(COSEKEYS.kty);
|
|
108769
108918
|
throw new Error(`Signature verification with public key of kty ${kty} is not supported by this method`);
|
|
108770
108919
|
}
|
|
108771
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
108920
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoUint8Array.js
|
|
108772
108921
|
/**
|
|
108773
108922
|
* A runtime-agnostic collection of methods for working with Uint8Arrays
|
|
108774
108923
|
* @module
|
|
@@ -108836,7 +108985,7 @@ function fromASCIIString(value) {
|
|
|
108836
108985
|
function toDataView(array) {
|
|
108837
108986
|
return new DataView(array.buffer, array.byteOffset, array.length);
|
|
108838
108987
|
}
|
|
108839
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
108988
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/convertCertBufferToPEM.js
|
|
108840
108989
|
/**
|
|
108841
108990
|
* Convert buffer to an OpenSSL-compatible PEM text format.
|
|
108842
108991
|
*/
|
|
@@ -108858,7 +109007,7 @@ function convertCertBufferToPEM(certBuffer) {
|
|
|
108858
109007
|
PEMKey = `-----BEGIN CERTIFICATE-----\n${PEMKey}-----END CERTIFICATE-----\n`;
|
|
108859
109008
|
return PEMKey;
|
|
108860
109009
|
}
|
|
108861
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
109010
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/runtimeSupportsWebCryptoKeyAlg.js
|
|
108862
109011
|
/**
|
|
108863
109012
|
* Use SubtleCrypto.supports() to understand if the runtime supports using the given key algorithm
|
|
108864
109013
|
* for signature verification.
|
|
@@ -108872,7 +109021,7 @@ function runtimeSupportsWebCryptoKeyAlg(alg) {
|
|
|
108872
109021
|
return false;
|
|
108873
109022
|
}
|
|
108874
109023
|
}
|
|
108875
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
109024
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/services/defaultRootCerts/android-safetynet.js
|
|
108876
109025
|
/**
|
|
108877
109026
|
* GlobalSign Root CA
|
|
108878
109027
|
*
|
|
@@ -108905,50 +109054,7 @@ DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
|
|
|
108905
109054
|
HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
|
|
108906
109055
|
-----END CERTIFICATE-----
|
|
108907
109056
|
`;
|
|
108908
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
108909
|
-
/**
|
|
108910
|
-
* Google Hardware Attestation Root 1
|
|
108911
|
-
*
|
|
108912
|
-
* Downloaded from https://developer.android.com/training/articles/security-key-attestation#root_certificate
|
|
108913
|
-
* (first entry)
|
|
108914
|
-
*
|
|
108915
|
-
* Valid until 2026-05-24 @ 09:28 PST
|
|
108916
|
-
*
|
|
108917
|
-
* SHA256 Fingerprint
|
|
108918
|
-
* C1:98:4A:3E:F4:5C:1E:2A:91:85:51:DE:10:60:3C:86:F7:05:1B:22:49:C4:89:1C:AE:32:30:EA:BD:0C:97:D5
|
|
108919
|
-
*/
|
|
108920
|
-
const Google_Hardware_Attestation_Root_1 = `-----BEGIN CERTIFICATE-----
|
|
108921
|
-
MIIFYDCCA0igAwIBAgIJAOj6GWMU0voYMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV
|
|
108922
|
-
BAUTEGY5MjAwOWU4NTNiNmIwNDUwHhcNMTYwNTI2MTYyODUyWhcNMjYwNTI0MTYy
|
|
108923
|
-
ODUyWjAbMRkwFwYDVQQFExBmOTIwMDllODUzYjZiMDQ1MIICIjANBgkqhkiG9w0B
|
|
108924
|
-
AQEFAAOCAg8AMIICCgKCAgEAr7bHgiuxpwHsK7Qui8xUFmOr75gvMsd/dTEDDJdS
|
|
108925
|
-
Sxtf6An7xyqpRR90PL2abxM1dEqlXnf2tqw1Ne4Xwl5jlRfdnJLmN0pTy/4lj4/7
|
|
108926
|
-
tv0Sk3iiKkypnEUtR6WfMgH0QZfKHM1+di+y9TFRtv6y//0rb+T+W8a9nsNL/ggj
|
|
108927
|
-
nar86461qO0rOs2cXjp3kOG1FEJ5MVmFmBGtnrKpa73XpXyTqRxB/M0n1n/W9nGq
|
|
108928
|
-
C4FSYa04T6N5RIZGBN2z2MT5IKGbFlbC8UrW0DxW7AYImQQcHtGl/m00QLVWutHQ
|
|
108929
|
-
oVJYnFPlXTcHYvASLu+RhhsbDmxMgJJ0mcDpvsC4PjvB+TxywElgS70vE0XmLD+O
|
|
108930
|
-
JtvsBslHZvPBKCOdT0MS+tgSOIfga+z1Z1g7+DVagf7quvmag8jfPioyKvxnK/Eg
|
|
108931
|
-
sTUVi2ghzq8wm27ud/mIM7AY2qEORR8Go3TVB4HzWQgpZrt3i5MIlCaY504LzSRi
|
|
108932
|
-
igHCzAPlHws+W0rB5N+er5/2pJKnfBSDiCiFAVtCLOZ7gLiMm0jhO2B6tUXHI/+M
|
|
108933
|
-
RPjy02i59lINMRRev56GKtcd9qO/0kUJWdZTdA2XoS82ixPvZtXQpUpuL12ab+9E
|
|
108934
|
-
aDK8Z4RHJYYfCT3Q5vNAXaiWQ+8PTWm2QgBR/bkwSWc+NpUFgNPN9PvQi8WEg5Um
|
|
108935
|
-
AGMCAwEAAaOBpjCBozAdBgNVHQ4EFgQUNmHhAHyIBQlRi0RsR/8aTMnqTxIwHwYD
|
|
108936
|
-
VR0jBBgwFoAUNmHhAHyIBQlRi0RsR/8aTMnqTxIwDwYDVR0TAQH/BAUwAwEB/zAO
|
|
108937
|
-
BgNVHQ8BAf8EBAMCAYYwQAYDVR0fBDkwNzA1oDOgMYYvaHR0cHM6Ly9hbmRyb2lk
|
|
108938
|
-
Lmdvb2dsZWFwaXMuY29tL2F0dGVzdGF0aW9uL2NybC8wDQYJKoZIhvcNAQELBQAD
|
|
108939
|
-
ggIBACDIw41L3KlXG0aMiS//cqrG+EShHUGo8HNsw30W1kJtjn6UBwRM6jnmiwfB
|
|
108940
|
-
Pb8VA91chb2vssAtX2zbTvqBJ9+LBPGCdw/E53Rbf86qhxKaiAHOjpvAy5Y3m00m
|
|
108941
|
-
qC0w/Zwvju1twb4vhLaJ5NkUJYsUS7rmJKHHBnETLi8GFqiEsqTWpG/6ibYCv7rY
|
|
108942
|
-
DBJDcR9W62BW9jfIoBQcxUCUJouMPH25lLNcDc1ssqvC2v7iUgI9LeoM1sNovqPm
|
|
108943
|
-
QUiG9rHli1vXxzCyaMTjwftkJLkf6724DFhuKug2jITV0QkXvaJWF4nUaHOTNA4u
|
|
108944
|
-
JU9WDvZLI1j83A+/xnAJUucIv/zGJ1AMH2boHqF8CY16LpsYgBt6tKxxWH00XcyD
|
|
108945
|
-
CdW2KlBCeqbQPcsFmWyWugxdcekhYsAWyoSf818NUsZdBWBaR/OukXrNLfkQ79Iy
|
|
108946
|
-
ZohZbvabO/X+MVT3rriAoKc8oE2Uws6DF+60PV7/WIPjNvXySdqspImSN78mflxD
|
|
108947
|
-
qwLqRBYkA3I75qppLGG9rp7UCdRjxMl8ZDBld+7yvHVgt1cVzJx9xnyGCC23Uaic
|
|
108948
|
-
MDSXYrB4I4WHXPGjxhZuCuPBLTdOLU8YRvMYdEvYebWHMpvwGCF6bAx3JBpIeOQ1
|
|
108949
|
-
wDB5y0USicV3YgYGmi+NZfhA4URSh77Yd6uuJOJENRaNVTzk
|
|
108950
|
-
-----END CERTIFICATE-----
|
|
108951
|
-
`;
|
|
109057
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/services/defaultRootCerts/android-key.js
|
|
108952
109058
|
/**
|
|
108953
109059
|
* Google Hardware Attestation Root 2
|
|
108954
109060
|
*
|
|
@@ -109037,7 +109143,7 @@ mD/vFDkzF+wm7cyWpQpCVQ==
|
|
|
109037
109143
|
/**
|
|
109038
109144
|
* Google Hardware Attestation Root 4
|
|
109039
109145
|
*
|
|
109040
|
-
* Downloaded from https://developer.android.com/
|
|
109146
|
+
* Downloaded from https://developer.android.com/privacy-and-security/security-key-attestation#root_certificate
|
|
109041
109147
|
* (fourth entry)
|
|
109042
109148
|
*
|
|
109043
109149
|
* Valid until 2042-03-15 @ 11:07 PDT
|
|
@@ -109077,7 +109183,33 @@ vaI47gC+TNpkgYGkkBT6B/m/U01BuOBBTzhIlMEZq9qkDWuM2cA5kW5V3FJUcfHn
|
|
|
109077
109183
|
w1IdYIg2Wxg7yHcQZemFQg==
|
|
109078
109184
|
-----END CERTIFICATE-----
|
|
109079
109185
|
`;
|
|
109080
|
-
|
|
109186
|
+
/**
|
|
109187
|
+
* Google Android Key Attestation CA1
|
|
109188
|
+
*
|
|
109189
|
+
* Downloaded from https://developer.android.com/privacy-and-security/security-key-attestation#root_certificate
|
|
109190
|
+
*
|
|
109191
|
+
* Valid until 2035-07-15 @ 15:32 PDT
|
|
109192
|
+
*
|
|
109193
|
+
* SHA256 Fingerprint
|
|
109194
|
+
* 6D:9D:B4:CE:6C:5C:0B:29:31:66:D0:89:86:E0:57:74:A8:77:6C:EB:52:5D:9E:43:29:52:0D:E1:2B:A4:BC:C0
|
|
109195
|
+
*/
|
|
109196
|
+
const Google_Android_Key_Attestation_CA1 = `
|
|
109197
|
+
-----BEGIN CERTIFICATE-----
|
|
109198
|
+
MIICIjCCAaigAwIBAgIRAISp0Cl7DrWK5/8OgN52BgUwCgYIKoZIzj0EAwMwUjEc
|
|
109199
|
+
MBoGA1UEAwwTS2V5IEF0dGVzdGF0aW9uIENBMTEQMA4GA1UECwwHQW5kcm9pZDET
|
|
109200
|
+
MBEGA1UECgwKR29vZ2xlIExMQzELMAkGA1UEBhMCVVMwHhcNMjUwNzE3MjIzMjE4
|
|
109201
|
+
WhcNMzUwNzE1MjIzMjE4WjBSMRwwGgYDVQQDDBNLZXkgQXR0ZXN0YXRpb24gQ0Ex
|
|
109202
|
+
MRAwDgYDVQQLDAdBbmRyb2lkMRMwEQYDVQQKDApHb29nbGUgTExDMQswCQYDVQQG
|
|
109203
|
+
EwJVUzB2MBAGByqGSM49AgEGBSuBBAAiA2IABCPaI3FO3z5bBQo8cuiEas4HjqCt
|
|
109204
|
+
G/mLFfRT0MsIssPBEEU5Cfbt6sH5yOAxqEi5QagpU1yX4HwnGb7OtBYpDTB57uH5
|
|
109205
|
+
Eczm34A5FNijV3s0/f0UPl7zbJcTx6xwqMIRq6NCMEAwDwYDVR0TAQH/BAUwAwEB
|
|
109206
|
+
/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFFIyuyz7RkOb3NaBqQ5lZuA0QepA
|
|
109207
|
+
MAoGCCqGSM49BAMDA2gAMGUCMETfjPO/HwqReR2CS7p0ZWoD/LHs6hDi422opifH
|
|
109208
|
+
EUaYLxwGlT9SLdjkVpz0UUOR5wIxAIoGyxGKRHVTpqpGRFiJtQEOOTp/+s1GcxeY
|
|
109209
|
+
uR2zh/80lQyu9vAFCj6E4AXc+osmRg==
|
|
109210
|
+
-----END CERTIFICATE-----
|
|
109211
|
+
`;
|
|
109212
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/services/defaultRootCerts/apple.js
|
|
109081
109213
|
/**
|
|
109082
109214
|
* Apple WebAuthn Root CA
|
|
109083
109215
|
*
|
|
@@ -109103,7 +109235,7 @@ jAGGiQIwHFj+dJZYUJR786osByBelJYsVZd2GbHQu209b5RCmGQ21gpSAk9QZW4B
|
|
|
109103
109235
|
1bWeT0vT
|
|
109104
109236
|
-----END CERTIFICATE-----
|
|
109105
109237
|
`;
|
|
109106
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
109238
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/services/defaultRootCerts/mds.js
|
|
109107
109239
|
/**
|
|
109108
109240
|
* GlobalSign Root CA - R3
|
|
109109
109241
|
*
|
|
@@ -109178,7 +109310,7 @@ N3ec592kD3ZDZopD8p/7DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3
|
|
|
109178
109310
|
vouXsXgxT7PntgMTzlSdriVZzH81Xwj3QEUxeCp6
|
|
109179
109311
|
-----END CERTIFICATE-----
|
|
109180
109312
|
`;
|
|
109181
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
109313
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/services/settingsService.js
|
|
109182
109314
|
var BaseSettingsService = class {
|
|
109183
109315
|
constructor() {
|
|
109184
109316
|
Object.defineProperty(this, "pemCertificates", {
|
|
@@ -109229,10 +109361,10 @@ const SettingsService = new BaseSettingsService();
|
|
|
109229
109361
|
SettingsService.setRootCertificates({
|
|
109230
109362
|
identifier: "android-key",
|
|
109231
109363
|
certificates: [
|
|
109232
|
-
Google_Hardware_Attestation_Root_1,
|
|
109233
109364
|
Google_Hardware_Attestation_Root_2,
|
|
109234
109365
|
Google_Hardware_Attestation_Root_3,
|
|
109235
|
-
Google_Hardware_Attestation_Root_4
|
|
109366
|
+
Google_Hardware_Attestation_Root_4,
|
|
109367
|
+
Google_Android_Key_Attestation_CA1
|
|
109236
109368
|
]
|
|
109237
109369
|
});
|
|
109238
109370
|
SettingsService.setRootCertificates({
|
|
@@ -109247,7 +109379,7 @@ SettingsService.setRootCertificates({
|
|
|
109247
109379
|
identifier: "mds",
|
|
109248
109380
|
certificates: [GlobalSign_Root_CA_R3, GlobalSign_Root_R46]
|
|
109249
109381
|
});
|
|
109250
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
109382
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/registration/generateRegistrationOptions.js
|
|
109251
109383
|
/**
|
|
109252
109384
|
* Set up some default authenticator selection options as per the latest spec:
|
|
109253
109385
|
* https://www.w3.org/TR/webauthn-2/#dictdef-authenticatorselectioncriteria
|
|
@@ -109389,7 +109521,7 @@ async function generateRegistrationOptions(options) {
|
|
|
109389
109521
|
hints
|
|
109390
109522
|
};
|
|
109391
109523
|
}
|
|
109392
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
109524
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/parseBackupFlags.js
|
|
109393
109525
|
/**
|
|
109394
109526
|
* Make sense of Bits 3 and 4 in authenticator indicating:
|
|
109395
109527
|
*
|
|
@@ -109414,7 +109546,21 @@ var InvalidBackupFlags = class extends Error {
|
|
|
109414
109546
|
this.name = "InvalidBackupFlags";
|
|
109415
109547
|
}
|
|
109416
109548
|
};
|
|
109417
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
109549
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/assertValidExpectedRPID.js
|
|
109550
|
+
/**
|
|
109551
|
+
* Check the RP ID to make sure it's valid to compare against what's reported in a WebAuthn
|
|
109552
|
+
* response.
|
|
109553
|
+
*
|
|
109554
|
+
* Invalid RP IDs will raise a `SimpleWebAuthnError` with `code: 'BAD_ARGUMENT'`
|
|
109555
|
+
*/
|
|
109556
|
+
function assertValidExpectedRPID(rpID) {
|
|
109557
|
+
const asciiRPID = new URL(`https://${rpID}`).hostname;
|
|
109558
|
+
if (asciiRPID !== rpID) throw new SimpleWebAuthnError({
|
|
109559
|
+
message: `"${rpID}" is not a valid expected RP ID. Replace it with its ASCII punycode representation "${asciiRPID}" and try again`,
|
|
109560
|
+
code: "BAD_ARGUMENT"
|
|
109561
|
+
});
|
|
109562
|
+
}
|
|
109563
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/matchExpectedRPID.js
|
|
109418
109564
|
/**
|
|
109419
109565
|
* Go through each expected RP ID and try to find one that matches. Returns the unhashed RP ID
|
|
109420
109566
|
* that matched the hash in the response.
|
|
@@ -109422,6 +109568,7 @@ var InvalidBackupFlags = class extends Error {
|
|
|
109422
109568
|
* Raises an `UnexpectedRPIDHash` error if no match is found
|
|
109423
109569
|
*/
|
|
109424
109570
|
async function matchExpectedRPID(rpIDHash, expectedRPIDs) {
|
|
109571
|
+
for (const rpID of expectedRPIDs) assertValidExpectedRPID(rpID);
|
|
109425
109572
|
try {
|
|
109426
109573
|
return await Promise.any(expectedRPIDs.map((expected) => {
|
|
109427
109574
|
return new Promise((resolve, reject) => {
|
|
@@ -109432,72 +109579,188 @@ async function matchExpectedRPID(rpIDHash, expectedRPIDs) {
|
|
|
109432
109579
|
});
|
|
109433
109580
|
}));
|
|
109434
109581
|
} catch (err) {
|
|
109435
|
-
if (err.name === "AggregateError") throw new
|
|
109582
|
+
if (err.name === "AggregateError") throw new SimpleWebAuthnError({
|
|
109583
|
+
message: "Unexpected RP ID hash",
|
|
109584
|
+
code: "UNEXPECTED_RP_ID"
|
|
109585
|
+
});
|
|
109436
109586
|
throw err;
|
|
109437
109587
|
}
|
|
109438
109588
|
}
|
|
109439
|
-
|
|
109440
|
-
|
|
109441
|
-
|
|
109442
|
-
|
|
109589
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/services/helpers/serviceStateTracker.js
|
|
109590
|
+
var SERVICE_STATE;
|
|
109591
|
+
(function(SERVICE_STATE) {
|
|
109592
|
+
SERVICE_STATE["DISABLED"] = "DISABLED";
|
|
109593
|
+
SERVICE_STATE["REFRESHING"] = "REFRESHING";
|
|
109594
|
+
SERVICE_STATE["READY"] = "READY";
|
|
109595
|
+
})(SERVICE_STATE || (SERVICE_STATE = {}));
|
|
109596
|
+
var ServiceStateTracker = class {
|
|
109597
|
+
constructor(name, logger) {
|
|
109598
|
+
Object.defineProperty(this, "name", {
|
|
109599
|
+
enumerable: true,
|
|
109600
|
+
configurable: true,
|
|
109601
|
+
writable: true,
|
|
109602
|
+
value: name
|
|
109603
|
+
});
|
|
109604
|
+
Object.defineProperty(this, "logger", {
|
|
109605
|
+
enumerable: true,
|
|
109606
|
+
configurable: true,
|
|
109607
|
+
writable: true,
|
|
109608
|
+
value: logger
|
|
109609
|
+
});
|
|
109610
|
+
Object.defineProperty(this, "state", {
|
|
109611
|
+
enumerable: true,
|
|
109612
|
+
configurable: true,
|
|
109613
|
+
writable: true,
|
|
109614
|
+
value: SERVICE_STATE.DISABLED
|
|
109615
|
+
});
|
|
109616
|
+
}
|
|
109617
|
+
/**
|
|
109618
|
+
* Get the current state
|
|
109619
|
+
*/
|
|
109620
|
+
get current() {
|
|
109621
|
+
return this.state;
|
|
109622
|
+
}
|
|
109623
|
+
/**
|
|
109624
|
+
* Set a new state and report it
|
|
109625
|
+
*/
|
|
109626
|
+
set(next) {
|
|
109627
|
+
if (this.state === next) return;
|
|
109628
|
+
this.state = next;
|
|
109629
|
+
this.logger.debug(`${this.name} is ${SERVICE_STATE[this.state]}`);
|
|
109630
|
+
}
|
|
109631
|
+
/**
|
|
109632
|
+
* A helper method to pause execution until the service is ready
|
|
109633
|
+
*/
|
|
109634
|
+
pauseUntilReady() {
|
|
109635
|
+
if (this.state === SERVICE_STATE.READY) return Promise.resolve();
|
|
109636
|
+
return new Promise((resolve, reject) => {
|
|
109637
|
+
const totalTimeoutMS = 7e4;
|
|
109638
|
+
const intervalMS = 100;
|
|
109639
|
+
let iterations = totalTimeoutMS / intervalMS;
|
|
109640
|
+
const intervalID = globalThis.setInterval(() => {
|
|
109641
|
+
if (iterations < 1) {
|
|
109642
|
+
clearInterval(intervalID);
|
|
109643
|
+
reject(`State did not become ready in ${totalTimeoutMS / 1e3} seconds`);
|
|
109644
|
+
} else if (this.state === SERVICE_STATE.READY) {
|
|
109645
|
+
clearInterval(intervalID);
|
|
109646
|
+
resolve();
|
|
109647
|
+
}
|
|
109648
|
+
iterations -= 1;
|
|
109649
|
+
}, intervalMS);
|
|
109650
|
+
});
|
|
109443
109651
|
}
|
|
109444
109652
|
};
|
|
109445
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/registration/verifications/verifyAttestationFIDOU2F.js
|
|
109446
109653
|
/**
|
|
109447
|
-
*
|
|
109654
|
+
* An MDS-aware metadata cache that tracks MDS servers and the data downloaded from them. This
|
|
109655
|
+
* includes tracking when an MDS server needs to be refreshed, but does not actually perform the
|
|
109656
|
+
* refresh.
|
|
109448
109657
|
*/
|
|
109449
|
-
|
|
109450
|
-
|
|
109451
|
-
|
|
109452
|
-
|
|
109453
|
-
|
|
109454
|
-
|
|
109455
|
-
|
|
109456
|
-
|
|
109457
|
-
|
|
109458
|
-
|
|
109459
|
-
|
|
109460
|
-
|
|
109461
|
-
|
|
109462
|
-
|
|
109463
|
-
if (aaguidToHex !== 0) throw new Error(`AAGUID "${aaguidToHex}" was not expected value`);
|
|
109464
|
-
try {
|
|
109465
|
-
await validateCertificatePath(x5c.map(convertCertBufferToPEM), rootCertificates);
|
|
109466
|
-
} catch (err) {
|
|
109467
|
-
throw new Error(`${err.message} (FIDOU2F)`);
|
|
109658
|
+
var MDSCache = class {
|
|
109659
|
+
constructor() {
|
|
109660
|
+
Object.defineProperty(this, "serverCache", {
|
|
109661
|
+
enumerable: true,
|
|
109662
|
+
configurable: true,
|
|
109663
|
+
writable: true,
|
|
109664
|
+
value: /* @__PURE__ */ new Map()
|
|
109665
|
+
});
|
|
109666
|
+
Object.defineProperty(this, "metadataCache", {
|
|
109667
|
+
enumerable: true,
|
|
109668
|
+
configurable: true,
|
|
109669
|
+
writable: true,
|
|
109670
|
+
value: /* @__PURE__ */ new Map()
|
|
109671
|
+
});
|
|
109468
109672
|
}
|
|
109469
|
-
|
|
109470
|
-
|
|
109471
|
-
|
|
109472
|
-
|
|
109473
|
-
|
|
109474
|
-
|
|
109475
|
-
|
|
109476
|
-
|
|
109477
|
-
|
|
109478
|
-
* Attestation Certificate Extension OID: `id-fido-gen-ce-aaguid`
|
|
109479
|
-
*
|
|
109480
|
-
* Sourced from https://fidoalliance.org/specs/fido-v2.0-ps-20150904/fido-key-attestation-v2.0-ps-20150904.html#verifying-an-attestation-statement
|
|
109481
|
-
*/
|
|
109482
|
-
const id_fido_gen_ce_aaguid = "1.3.6.1.4.1.45724.1.1.4";
|
|
109483
|
-
/**
|
|
109484
|
-
* Look for the id-fido-gen-ce-aaguid certificate extension. If it's present then check it against
|
|
109485
|
-
* the attestation statement AAGUID.
|
|
109486
|
-
*/
|
|
109487
|
-
function validateExtFIDOGenCEAAGUID(certExtensions, aaguid) {
|
|
109488
|
-
if (!certExtensions) return true;
|
|
109489
|
-
const extFIDOGenCEAAGUID = certExtensions.find((ext) => ext.extnID === id_fido_gen_ce_aaguid);
|
|
109490
|
-
if (!extFIDOGenCEAAGUID) return true;
|
|
109491
|
-
const parsedExtFIDOGenCEAAGUID = import_cjs$4.AsnParser.parse(extFIDOGenCEAAGUID.extnValue, import_cjs$4.OctetString);
|
|
109492
|
-
const extValue = new Uint8Array(parsedExtFIDOGenCEAAGUID.buffer);
|
|
109493
|
-
if (!areEqual(aaguid, extValue)) {
|
|
109494
|
-
const _debugExtHex = toHex(extValue);
|
|
109495
|
-
const _debugAAGUIDHex = toHex(aaguid);
|
|
109496
|
-
throw new Error(`Certificate extension id-fido-gen-ce-aaguid (${id_fido_gen_ce_aaguid}) value of "${_debugExtHex}" was present but not equal to attestation statement AAGUID value of "${_debugAAGUIDHex}"`);
|
|
109673
|
+
/**
|
|
109674
|
+
* Set up a Metadata Service API for periodic refreshes
|
|
109675
|
+
*/
|
|
109676
|
+
registerMDSServer(url, no, nextUpdate) {
|
|
109677
|
+
this.serverCache.set(url, {
|
|
109678
|
+
url,
|
|
109679
|
+
no,
|
|
109680
|
+
nextUpdate
|
|
109681
|
+
});
|
|
109497
109682
|
}
|
|
109498
|
-
|
|
109499
|
-
|
|
109500
|
-
|
|
109683
|
+
/**
|
|
109684
|
+
* Add the provided metadata to the cache, keyed by its corresponding AAGUID
|
|
109685
|
+
*/
|
|
109686
|
+
cacheMetadata(aaguid, metadata, url) {
|
|
109687
|
+
this.metadataCache.set(this.normalizeAAGUID(aaguid), {
|
|
109688
|
+
data: metadata,
|
|
109689
|
+
url
|
|
109690
|
+
});
|
|
109691
|
+
}
|
|
109692
|
+
/**
|
|
109693
|
+
* Retrieve cached metadata by AAGUID
|
|
109694
|
+
*/
|
|
109695
|
+
getMetadata(aaguid) {
|
|
109696
|
+
if (!aaguid) return;
|
|
109697
|
+
if (aaguid instanceof Uint8Array) aaguid = convertAAGUIDToString(aaguid);
|
|
109698
|
+
return this.metadataCache.get(this.normalizeAAGUID(aaguid))?.data;
|
|
109699
|
+
}
|
|
109700
|
+
/**
|
|
109701
|
+
* Return how many metadata entries have been cached
|
|
109702
|
+
*/
|
|
109703
|
+
get count() {
|
|
109704
|
+
return this.metadataCache.size;
|
|
109705
|
+
}
|
|
109706
|
+
/**
|
|
109707
|
+
* Clear out caches
|
|
109708
|
+
*/
|
|
109709
|
+
reset() {
|
|
109710
|
+
this.serverCache = /* @__PURE__ */ new Map();
|
|
109711
|
+
this.metadataCache = /* @__PURE__ */ new Map();
|
|
109712
|
+
}
|
|
109713
|
+
/**
|
|
109714
|
+
* Remove cached Metadata Service data for a specific API server. If the URL indicates data that
|
|
109715
|
+
* should not be refreshed, then simply exit.
|
|
109716
|
+
*/
|
|
109717
|
+
clearMetadataByURL(url) {
|
|
109718
|
+
if (url === "") return;
|
|
109719
|
+
for (const [aaguid, cached] of this.metadataCache.entries()) if (cached.url === url) this.metadataCache.delete(this.normalizeAAGUID(aaguid));
|
|
109720
|
+
}
|
|
109721
|
+
/**
|
|
109722
|
+
* Whether an MDS server has been registered for periodic refreshes
|
|
109723
|
+
*/
|
|
109724
|
+
mdsServerIsRegistered(url) {
|
|
109725
|
+
return this.serverCache.has(url);
|
|
109726
|
+
}
|
|
109727
|
+
/**
|
|
109728
|
+
* Set the MDS server's nextUpdate
|
|
109729
|
+
*/
|
|
109730
|
+
setMDSServerNextUpdate(url, newNextUpdate) {
|
|
109731
|
+
const server = this.serverCache.get(url);
|
|
109732
|
+
if (!server) throw new SimpleWebAuthnError({
|
|
109733
|
+
message: `No MDS server has been registered for "${url}". Register it with registerMDSServer() first`,
|
|
109734
|
+
code: "BAD_ARGUMENT"
|
|
109735
|
+
});
|
|
109736
|
+
server.nextUpdate = newNextUpdate;
|
|
109737
|
+
this.serverCache.set(url, server);
|
|
109738
|
+
}
|
|
109739
|
+
/**
|
|
109740
|
+
* Retrieve the version number of the MDS server's latest known data
|
|
109741
|
+
*/
|
|
109742
|
+
getMDSServerDataVersion(url) {
|
|
109743
|
+
const server = this.serverCache.get(url);
|
|
109744
|
+
if (!server) throw new SimpleWebAuthnError({
|
|
109745
|
+
message: `No MDS server has been registered for "${url}". Register it with registerMDSServer() first`,
|
|
109746
|
+
code: "BAD_ARGUMENT"
|
|
109747
|
+
});
|
|
109748
|
+
return server.no;
|
|
109749
|
+
}
|
|
109750
|
+
/**
|
|
109751
|
+
* Return a list of MDS server URLs with nextUpdates earlier than the provided date
|
|
109752
|
+
*/
|
|
109753
|
+
getStaleMDSServerURLs(date) {
|
|
109754
|
+
return this.serverCache.values().filter((mds) => mds.url !== "" && date > mds.nextUpdate).map((mds) => mds.url).toArray();
|
|
109755
|
+
}
|
|
109756
|
+
/**
|
|
109757
|
+
* Ensure that AAGUIDs are all lowercase before using them as cache keys
|
|
109758
|
+
*/
|
|
109759
|
+
normalizeAAGUID(aaguid) {
|
|
109760
|
+
return aaguid.toLowerCase();
|
|
109761
|
+
}
|
|
109762
|
+
};
|
|
109763
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/logging.js
|
|
109501
109764
|
/**
|
|
109502
109765
|
* A logger instance that doesn't do anything. Useful as a default argument when no custom instance
|
|
109503
109766
|
* of the `SimpleWebAuthnLogger` interface is specified.
|
|
@@ -109520,66 +109783,231 @@ function buildLoggerAllMethods(logger) {
|
|
|
109520
109783
|
if (logger.error) toReturn.error = logger.error;
|
|
109521
109784
|
return toReturn;
|
|
109522
109785
|
}
|
|
109523
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
109524
|
-
/**
|
|
109525
|
-
* An instance of `CachedMDS` that will not trigger attempts to refresh the associated entry's blob
|
|
109526
|
-
*/
|
|
109527
|
-
const NonRefreshingMDS = {
|
|
109528
|
-
url: "",
|
|
109529
|
-
no: 0,
|
|
109530
|
-
nextUpdate: /* @__PURE__ */ new Date(0)
|
|
109531
|
-
};
|
|
109532
|
-
const defaultURLMDS = "https://mds.fidoalliance.org/";
|
|
109533
|
-
var SERVICE_STATE;
|
|
109534
|
-
(function(SERVICE_STATE) {
|
|
109535
|
-
SERVICE_STATE[SERVICE_STATE["DISABLED"] = 0] = "DISABLED";
|
|
109536
|
-
SERVICE_STATE[SERVICE_STATE["REFRESHING"] = 1] = "REFRESHING";
|
|
109537
|
-
SERVICE_STATE[SERVICE_STATE["READY"] = 2] = "READY";
|
|
109538
|
-
})(SERVICE_STATE || (SERVICE_STATE = {}));
|
|
109786
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/services/helpers/getInitCacheMessage.js
|
|
109539
109787
|
/**
|
|
109540
|
-
*
|
|
109541
|
-
* requesting and caching of individual metadata statements.
|
|
109788
|
+
* Generate a message detailing how many metadata entries were cached, and from which sources
|
|
109542
109789
|
*
|
|
109543
|
-
*
|
|
109790
|
+
* Examples:
|
|
109791
|
+
*
|
|
109792
|
+
* - "ConvenienceMetadataService cached 322 unique metadata entries from 1 local payload(s) and 1 convenience metadata server(s)"
|
|
109793
|
+
* - "ConvenienceMetadataService cached 322 unique metadata entries from 1 local payload(s)"
|
|
109794
|
+
* - "MetadataService cached 285 unique metadata entries from 1 convenience metadata server(s)"
|
|
109795
|
+
* - "MetadataService cached 0 unique metadata entries"
|
|
109796
|
+
*/
|
|
109797
|
+
function getInitCacheMessage(serviceName, cacheCount, numLocalFiles, numServers) {
|
|
109798
|
+
let message = `${serviceName} cached ${cacheCount} unique entries`;
|
|
109799
|
+
if (cacheCount) {
|
|
109800
|
+
const formatter = new Intl.ListFormat("en", {
|
|
109801
|
+
style: "long",
|
|
109802
|
+
type: "conjunction"
|
|
109803
|
+
});
|
|
109804
|
+
const sources = [];
|
|
109805
|
+
if (numLocalFiles) sources.push(`${numLocalFiles} local file(s)`);
|
|
109806
|
+
if (numServers) sources.push(`${numServers} metadata server(s)`);
|
|
109807
|
+
message = `${message} from ${formatter.format(sources)}`;
|
|
109808
|
+
}
|
|
109809
|
+
return message;
|
|
109810
|
+
}
|
|
109811
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/services/helpers/baseMDSService.js
|
|
109812
|
+
/**
|
|
109813
|
+
* Functionality shared by services that download, cache, and refresh metadata from FIDO
|
|
109814
|
+
* Alliance-style metadata servers (MDS and Convenience MDS.) Subclasses are responsible for
|
|
109815
|
+
* parsing and caching what a server returns.
|
|
109544
109816
|
*/
|
|
109545
|
-
var
|
|
109546
|
-
|
|
109547
|
-
|
|
109817
|
+
var BaseMDSService = class {
|
|
109818
|
+
/**
|
|
109819
|
+
* @param serviceName Used in logs, e.g. `"MetadataService"`
|
|
109820
|
+
*/
|
|
109821
|
+
constructor(serviceName) {
|
|
109822
|
+
Object.defineProperty(this, "serviceName", {
|
|
109548
109823
|
enumerable: true,
|
|
109549
109824
|
configurable: true,
|
|
109550
109825
|
writable: true,
|
|
109551
|
-
value:
|
|
109826
|
+
value: serviceName
|
|
109552
109827
|
});
|
|
109553
|
-
Object.defineProperty(this, "
|
|
109828
|
+
Object.defineProperty(this, "metadataCache", {
|
|
109554
109829
|
enumerable: true,
|
|
109555
109830
|
configurable: true,
|
|
109556
109831
|
writable: true,
|
|
109557
|
-
value:
|
|
109832
|
+
value: new MDSCache()
|
|
109558
109833
|
});
|
|
109559
109834
|
Object.defineProperty(this, "state", {
|
|
109560
109835
|
enumerable: true,
|
|
109561
109836
|
configurable: true,
|
|
109562
109837
|
writable: true,
|
|
109563
|
-
value:
|
|
109838
|
+
value: void 0
|
|
109564
109839
|
});
|
|
109565
|
-
Object.defineProperty(this, "
|
|
109840
|
+
Object.defineProperty(this, "logger", {
|
|
109566
109841
|
enumerable: true,
|
|
109567
109842
|
configurable: true,
|
|
109568
109843
|
writable: true,
|
|
109569
|
-
value:
|
|
109844
|
+
value: DefaultNoopLogger
|
|
109570
109845
|
});
|
|
109571
|
-
|
|
109846
|
+
/** How many hours to wait to check a server again when it has nothing new to download */
|
|
109847
|
+
Object.defineProperty(this, "defaultRefreshDelayHours", {
|
|
109572
109848
|
enumerable: true,
|
|
109573
109849
|
configurable: true,
|
|
109574
109850
|
writable: true,
|
|
109575
|
-
value:
|
|
109851
|
+
value: 24
|
|
109852
|
+
});
|
|
109853
|
+
/** How many hours to wait to retry a _failed_ attempt to refresh a server */
|
|
109854
|
+
Object.defineProperty(this, "defaultRetryDelayHours", {
|
|
109855
|
+
enumerable: true,
|
|
109856
|
+
configurable: true,
|
|
109857
|
+
writable: true,
|
|
109858
|
+
value: 3
|
|
109859
|
+
});
|
|
109860
|
+
/** Abort downloads that take longer than this many milliseconds. No limit if left `undefined` */
|
|
109861
|
+
Object.defineProperty(this, "downloadTimeoutMS", {
|
|
109862
|
+
enumerable: true,
|
|
109863
|
+
configurable: true,
|
|
109864
|
+
writable: true,
|
|
109865
|
+
value: 1e4
|
|
109866
|
+
});
|
|
109867
|
+
/**
|
|
109868
|
+
* Refresh a single server, subscribing to the refresh already in flight if there is one.
|
|
109869
|
+
* Failures are passed to `handleRefreshFailure()`.
|
|
109870
|
+
*/
|
|
109871
|
+
Object.defineProperty(this, "serverRefreshes", {
|
|
109872
|
+
enumerable: true,
|
|
109873
|
+
configurable: true,
|
|
109874
|
+
writable: true,
|
|
109875
|
+
value: {}
|
|
109576
109876
|
});
|
|
109877
|
+
this.state = new ServiceStateTracker(serviceName, this.logger);
|
|
109577
109878
|
}
|
|
109578
|
-
|
|
109579
|
-
|
|
109580
|
-
|
|
109879
|
+
/**
|
|
109880
|
+
* Reset the service and move it to the `REFRESHING` state. Call this at the start of
|
|
109881
|
+
* `initialize()`.
|
|
109882
|
+
*/
|
|
109883
|
+
beginInitialize(logger = DefaultNoopLogger) {
|
|
109884
|
+
this.metadataCache.reset();
|
|
109885
|
+
this.serverRefreshes = {};
|
|
109581
109886
|
this.logger = buildLoggerAllMethods(logger);
|
|
109582
|
-
this.
|
|
109887
|
+
this.state = new ServiceStateTracker(this.serviceName, this.logger);
|
|
109888
|
+
this.state.set(SERVICE_STATE.REFRESHING);
|
|
109889
|
+
}
|
|
109890
|
+
/**
|
|
109891
|
+
* Download and cache from each server. A server is only registered for refreshes once data from
|
|
109892
|
+
* it has been cached. One that can't be reached, or that doesn't respond with data, is skipped
|
|
109893
|
+
* so it can't cause lookups of other metadata to fail.
|
|
109894
|
+
*
|
|
109895
|
+
* Returns the number of servers entries were cached from.
|
|
109896
|
+
*/
|
|
109897
|
+
async initializeServers(mdsServers) {
|
|
109898
|
+
let numServers = 0;
|
|
109899
|
+
for (const url of mdsServers ?? []) try {
|
|
109900
|
+
const entriesAdded = await this.downloadAndCache(url, 0);
|
|
109901
|
+
if (entriesAdded !== void 0) {
|
|
109902
|
+
numServers += 1;
|
|
109903
|
+
this.logger.debug(`Cached ${entriesAdded} metadata entries from "${url}"`);
|
|
109904
|
+
}
|
|
109905
|
+
} catch (err) {
|
|
109906
|
+
this.logger.error(`Could not download data from "${url}":`, err);
|
|
109907
|
+
}
|
|
109908
|
+
return numServers;
|
|
109909
|
+
}
|
|
109910
|
+
/**
|
|
109911
|
+
* Log how much was cached and report the service as ready. Call this at the end of
|
|
109912
|
+
* `initialize()`.
|
|
109913
|
+
*/
|
|
109914
|
+
finishInitialize(numLocalFiles, numServers) {
|
|
109915
|
+
const cacheMessage = getInitCacheMessage(this.serviceName, this.metadataCache.count, numLocalFiles, numServers);
|
|
109916
|
+
this.logger.info(cacheMessage);
|
|
109917
|
+
this.state.set(SERVICE_STATE.READY);
|
|
109918
|
+
}
|
|
109919
|
+
/**
|
|
109920
|
+
* Request data from a server, with a query param that can short-circuit the download if the
|
|
109921
|
+
* latest version is already cached. `no` is the serial number of the last data cached from this
|
|
109922
|
+
* server.
|
|
109923
|
+
*
|
|
109924
|
+
* Returns `undefined` if the server responded with anything other than data, in which case the
|
|
109925
|
+
* next refresh will have been delayed.
|
|
109926
|
+
*
|
|
109927
|
+
* See https://fidoalliance.org/specs/mds/fido-metadata-service-v3.1-ps-20250521.html#sctn-mds-blob-proc-rules
|
|
109928
|
+
*/
|
|
109929
|
+
async fetchFromServer(url, no) {
|
|
109930
|
+
const _url = new URL(url);
|
|
109931
|
+
_url.searchParams.set("localCopySerial", String(no));
|
|
109932
|
+
const resp = await fetch(_url.toString(), { signal: AbortSignal.timeout(this.downloadTimeoutMS) });
|
|
109933
|
+
if (resp.status === 304) {
|
|
109934
|
+
await resp.body?.cancel();
|
|
109935
|
+
this.logger.info(`The MDS server at "${_url.toString()}" reported nothing new to download (HTTP 304)`);
|
|
109936
|
+
this.delayNextRefresh(url, this.defaultRefreshDelayHours);
|
|
109937
|
+
return;
|
|
109938
|
+
}
|
|
109939
|
+
if (resp.status === 429) {
|
|
109940
|
+
await resp.body?.cancel();
|
|
109941
|
+
this.logger.warn(`The MDS server at "${_url.toString()}" rate-limited this request (HTTP 429)`);
|
|
109942
|
+
this.delayNextRefresh(url, this.defaultRetryDelayHours);
|
|
109943
|
+
return;
|
|
109944
|
+
}
|
|
109945
|
+
if (!resp.ok) {
|
|
109946
|
+
await resp.body?.cancel();
|
|
109947
|
+
this.logger.warn(`The MDS server at "${_url.toString()}" reported an unsuccessful request (HTTP ${resp.status})`);
|
|
109948
|
+
this.delayNextRefresh(url, this.defaultRetryDelayHours);
|
|
109949
|
+
return;
|
|
109950
|
+
}
|
|
109951
|
+
return resp;
|
|
109952
|
+
}
|
|
109953
|
+
/**
|
|
109954
|
+
* Refresh every server whose `nextUpdate` has passed
|
|
109955
|
+
*/
|
|
109956
|
+
async refreshStaleServers() {
|
|
109957
|
+
const now = /* @__PURE__ */ new Date();
|
|
109958
|
+
const staleURLs = this.metadataCache.getStaleMDSServerURLs(now);
|
|
109959
|
+
await Promise.all(staleURLs.map((url) => this.refreshServer(url)));
|
|
109960
|
+
}
|
|
109961
|
+
refreshServer(url) {
|
|
109962
|
+
const inFlight = this.serverRefreshes[url];
|
|
109963
|
+
if (inFlight) return inFlight;
|
|
109964
|
+
this.state.set(SERVICE_STATE.REFRESHING);
|
|
109965
|
+
const refresh = (async () => {
|
|
109966
|
+
try {
|
|
109967
|
+
const mdsNo = this.metadataCache.getMDSServerDataVersion(url);
|
|
109968
|
+
await this.downloadAndCache(url, mdsNo);
|
|
109969
|
+
} catch (err) {
|
|
109970
|
+
this.logger.error(`Could not download data from "${url}":`, err);
|
|
109971
|
+
this.handleRefreshFailure(url, err);
|
|
109972
|
+
} finally {
|
|
109973
|
+
delete this.serverRefreshes[url];
|
|
109974
|
+
if (Object.keys(this.serverRefreshes).length === 0) this.state.set(SERVICE_STATE.READY);
|
|
109975
|
+
}
|
|
109976
|
+
})();
|
|
109977
|
+
this.serverRefreshes[url] = refresh;
|
|
109978
|
+
return refresh;
|
|
109979
|
+
}
|
|
109980
|
+
/**
|
|
109981
|
+
* Delay the next refresh attempt of this server by the specified number of hours
|
|
109982
|
+
*/
|
|
109983
|
+
delayNextRefresh(url, numHours) {
|
|
109984
|
+
if (!this.metadataCache.mdsServerIsRegistered(url)) return;
|
|
109985
|
+
this.logger.debug(`Delaying next refresh of "${url}" by ${numHours} hours`);
|
|
109986
|
+
const numHoursMS = 36e5 * numHours;
|
|
109987
|
+
this.metadataCache.setMDSServerNextUpdate(url, new Date(Date.now() + numHoursMS));
|
|
109988
|
+
}
|
|
109989
|
+
};
|
|
109990
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/services/metadataService.js
|
|
109991
|
+
const defaultURLMDS = "https://mds.fidoalliance.org/";
|
|
109992
|
+
/**
|
|
109993
|
+
* An implementation of `MetadataService` that can download and parse BLOBs, and support on-demand
|
|
109994
|
+
* requesting and caching of individual metadata statements.
|
|
109995
|
+
*
|
|
109996
|
+
* https://fidoalliance.org/metadata/
|
|
109997
|
+
*/
|
|
109998
|
+
var BaseMetadataService = class extends BaseMDSService {
|
|
109999
|
+
constructor() {
|
|
110000
|
+
super("MetadataService");
|
|
110001
|
+
Object.defineProperty(this, "verificationMode", {
|
|
110002
|
+
enumerable: true,
|
|
110003
|
+
configurable: true,
|
|
110004
|
+
writable: true,
|
|
110005
|
+
value: "strict"
|
|
110006
|
+
});
|
|
110007
|
+
}
|
|
110008
|
+
async initialize(opts = {}) {
|
|
110009
|
+
const { mdsServers = [defaultURLMDS], statements, verificationMode, logger } = opts;
|
|
110010
|
+
this.beginInitialize(logger);
|
|
109583
110011
|
/**
|
|
109584
110012
|
* If metadata statements are provided, load them into the cache first. These statements will
|
|
109585
110013
|
* not be refreshed when a stale one is detected.
|
|
@@ -109587,139 +110015,240 @@ var BaseMetadataService = class {
|
|
|
109587
110015
|
if (statements?.length) {
|
|
109588
110016
|
let statementsAdded = 0;
|
|
109589
110017
|
statements.forEach((statement) => {
|
|
109590
|
-
|
|
109591
|
-
|
|
109592
|
-
|
|
109593
|
-
|
|
109594
|
-
|
|
109595
|
-
|
|
109596
|
-
},
|
|
109597
|
-
url: NonRefreshingMDS.url
|
|
109598
|
-
};
|
|
109599
|
-
statementsAdded += 1;
|
|
109600
|
-
}
|
|
110018
|
+
statementsAdded += this.cacheMetadataBlobEntry("", {
|
|
110019
|
+
aaguid: statement.aaguid,
|
|
110020
|
+
metadataStatement: statement,
|
|
110021
|
+
statusReports: [],
|
|
110022
|
+
timeOfLastStatusChange: "1970-01-01"
|
|
110023
|
+
});
|
|
109601
110024
|
});
|
|
109602
|
-
this.logger.info(`Cached ${statementsAdded} local statements`);
|
|
110025
|
+
this.logger.info(`Cached ${statementsAdded} total local metadata statements`);
|
|
109603
110026
|
}
|
|
109604
110027
|
/**
|
|
109605
110028
|
* If MDS servers are provided, then download blobs from them, verify them, and then add their
|
|
109606
110029
|
* entries to the cache. Blobs loaded in this way will be refreshed when a stale entry within is
|
|
109607
110030
|
* detected.
|
|
109608
110031
|
*/
|
|
109609
|
-
|
|
109610
|
-
|
|
109611
|
-
|
|
109612
|
-
for (const url of mdsServers) try {
|
|
109613
|
-
const cachedMDS = {
|
|
109614
|
-
url,
|
|
109615
|
-
no: 0,
|
|
109616
|
-
nextUpdate: /* @__PURE__ */ new Date(0)
|
|
109617
|
-
};
|
|
109618
|
-
const blob = await this.downloadBlob(cachedMDS);
|
|
109619
|
-
await this.verifyBlob(blob, cachedMDS);
|
|
109620
|
-
} catch (err) {
|
|
109621
|
-
this.logger.error(`Could not download BLOB from ${url}:`, err);
|
|
109622
|
-
numServers -= 1;
|
|
109623
|
-
}
|
|
109624
|
-
const cacheDiff = Object.keys(this.statementCache).length - currentCacheCount;
|
|
109625
|
-
this.logger.info(`Cached ${cacheDiff} statements from ${numServers} metadata server(s)`);
|
|
109626
|
-
}
|
|
109627
|
-
if (verificationMode) this.verificationMode = verificationMode;
|
|
109628
|
-
this.setState(SERVICE_STATE.READY);
|
|
110032
|
+
const numServers = await this.initializeServers(mdsServers);
|
|
110033
|
+
this.verificationMode = verificationMode ?? "strict";
|
|
110034
|
+
this.finishInitialize(statements?.length, numServers);
|
|
109629
110035
|
}
|
|
109630
110036
|
async getStatement(aaguid) {
|
|
109631
|
-
if (this.state === SERVICE_STATE.DISABLED) return;
|
|
110037
|
+
if (this.state.current === SERVICE_STATE.DISABLED) return;
|
|
109632
110038
|
if (!aaguid) return;
|
|
109633
110039
|
if (aaguid instanceof Uint8Array) aaguid = convertAAGUIDToString(aaguid);
|
|
109634
|
-
await this.pauseUntilReady();
|
|
109635
|
-
|
|
109636
|
-
|
|
110040
|
+
await this.state.pauseUntilReady();
|
|
110041
|
+
await this.refreshStaleServers();
|
|
110042
|
+
const entry = this.metadataCache.getMetadata(aaguid);
|
|
110043
|
+
if (!entry) {
|
|
109637
110044
|
if (this.verificationMode === "strict") throw new Error(`No metadata statement found for aaguid "${aaguid}"`);
|
|
109638
110045
|
return;
|
|
109639
110046
|
}
|
|
109640
|
-
if (cachedStatement.url) {
|
|
109641
|
-
const mds = this.mdsCache[cachedStatement.url];
|
|
109642
|
-
if (/* @__PURE__ */ new Date() > mds.nextUpdate) try {
|
|
109643
|
-
this.setState(SERVICE_STATE.REFRESHING);
|
|
109644
|
-
const blob = await this.downloadBlob(mds);
|
|
109645
|
-
await this.verifyBlob(blob, mds);
|
|
109646
|
-
} finally {
|
|
109647
|
-
this.setState(SERVICE_STATE.READY);
|
|
109648
|
-
}
|
|
109649
|
-
}
|
|
109650
|
-
const { entry } = cachedStatement;
|
|
109651
110047
|
for (const report of entry.statusReports) {
|
|
109652
110048
|
const { status } = report;
|
|
109653
110049
|
if (status === "USER_VERIFICATION_BYPASS" || status === "ATTESTATION_KEY_COMPROMISE" || status === "USER_KEY_REMOTE_COMPROMISE" || status === "USER_KEY_PHYSICAL_COMPROMISE") throw new Error(`Detected compromised aaguid "${aaguid}"`);
|
|
109654
110050
|
}
|
|
109655
110051
|
return entry.metadataStatement;
|
|
109656
110052
|
}
|
|
110053
|
+
async getProviderMetadata(aaguid) {
|
|
110054
|
+
/**
|
|
110055
|
+
* This is a load-bearing check: without it the `this.verificationMode === 'strict'` check in
|
|
110056
|
+
* `getStatement()` will raise an error on this method when there's no need to do so because
|
|
110057
|
+
* this method's returning `undefined` does not impact the security posture of the RP.
|
|
110058
|
+
*/
|
|
110059
|
+
if (!aaguid) return;
|
|
110060
|
+
const metadataStatement = await this.getStatement(aaguid);
|
|
110061
|
+
if (!metadataStatement) return;
|
|
110062
|
+
return {
|
|
110063
|
+
friendlyNames: metadataStatement.friendlyNames,
|
|
110064
|
+
icon: metadataStatement.icon,
|
|
110065
|
+
iconDark: metadataStatement.iconDark,
|
|
110066
|
+
providerLogoDark: metadataStatement.providerLogoDark,
|
|
110067
|
+
providerLogoLight: metadataStatement.providerLogoLight
|
|
110068
|
+
};
|
|
110069
|
+
}
|
|
110070
|
+
/**
|
|
110071
|
+
* Download the latest BLOB from MDS, verify it, and cache its entries
|
|
110072
|
+
*/
|
|
110073
|
+
async downloadAndCache(url, no) {
|
|
110074
|
+
const resp = await this.fetchFromServer(url, no);
|
|
110075
|
+
if (!resp) return;
|
|
110076
|
+
const blob = await resp.text();
|
|
110077
|
+
return this.verifyBlob(blob, url, no);
|
|
110078
|
+
}
|
|
109657
110079
|
/**
|
|
109658
|
-
*
|
|
110080
|
+
* Refresh failures are rethrown so that lookups fail closed: until the refresh succeeds the
|
|
110081
|
+
* server stays stale, every lookup tries again, and none of them are answered with statements
|
|
110082
|
+
* from the BLOB that was previously cached.
|
|
109659
110083
|
*/
|
|
109660
|
-
|
|
109661
|
-
|
|
109662
|
-
return await (await fetch(url)).text();
|
|
110084
|
+
handleRefreshFailure(_url, err) {
|
|
110085
|
+
throw err;
|
|
109663
110086
|
}
|
|
109664
110087
|
/**
|
|
109665
|
-
* Verify and process the MDS metadata blob
|
|
110088
|
+
* Verify and process the MDS metadata blob. Caches metadata and sets up refreshing when blobs
|
|
110089
|
+
* grow stale. `no` is the serial number of the last BLOB cached from this server.
|
|
110090
|
+
*
|
|
110091
|
+
* Returns the number of FIDO2 metadata statements that were cached.
|
|
109666
110092
|
*/
|
|
109667
|
-
async verifyBlob(blob,
|
|
109668
|
-
const { url, no } = cachedMDS;
|
|
110093
|
+
async verifyBlob(blob, url, no) {
|
|
109669
110094
|
const { payload, parsedNextUpdate } = await verifyMDSBlob(blob);
|
|
109670
110095
|
if (payload.no <= no) throw new Error(`Latest BLOB no. ${payload.no} is not greater than previous no. ${no}`);
|
|
109671
|
-
|
|
109672
|
-
|
|
109673
|
-
|
|
109674
|
-
|
|
109675
|
-
if (url) this.mdsCache[url] = {
|
|
109676
|
-
...cachedMDS,
|
|
109677
|
-
no: payload.no,
|
|
109678
|
-
nextUpdate: parsedNextUpdate
|
|
109679
|
-
};
|
|
110096
|
+
this.metadataCache.clearMetadataByURL(url);
|
|
110097
|
+
let totalEntries = 0;
|
|
110098
|
+
for (const entry of payload.entries) totalEntries += this.cacheMetadataBlobEntry(url, entry);
|
|
110099
|
+
if (url !== "") this.metadataCache.registerMDSServer(url, payload.no, parsedNextUpdate);
|
|
109680
110100
|
else if (parsedNextUpdate < /* @__PURE__ */ new Date()) this.logger.warn(`⚠️ This MDS blob (serial: ${payload.no}) contains stale data as of ${parsedNextUpdate.toISOString()}. Please consider re-initializing MetadataService with a newer MDS blob.`);
|
|
110101
|
+
return totalEntries;
|
|
109681
110102
|
}
|
|
109682
110103
|
/**
|
|
109683
|
-
* A
|
|
110104
|
+
* A central place to contain logic and side effects of caching a BLOB entry. Only caches FIDO2
|
|
110105
|
+
* statements (i.e. ones with `aaguid` as UAF authenticators won't have one.) Returns `1` if the
|
|
110106
|
+
* statement was cached, or `0` if it wasn't (so you can `count += cacheMetadataBlobEntry(...)`)
|
|
109684
110107
|
*/
|
|
109685
|
-
|
|
109686
|
-
if (
|
|
109687
|
-
|
|
109688
|
-
|
|
109689
|
-
|
|
109690
|
-
|
|
109691
|
-
|
|
109692
|
-
|
|
109693
|
-
|
|
109694
|
-
|
|
109695
|
-
|
|
109696
|
-
|
|
109697
|
-
|
|
109698
|
-
|
|
109699
|
-
|
|
109700
|
-
|
|
109701
|
-
|
|
109702
|
-
|
|
110108
|
+
cacheMetadataBlobEntry(url, entry) {
|
|
110109
|
+
if (!entry.aaguid) return 0;
|
|
110110
|
+
this.metadataCache.cacheMetadata(entry.aaguid, entry, url);
|
|
110111
|
+
return 1;
|
|
110112
|
+
}
|
|
110113
|
+
};
|
|
110114
|
+
/**
|
|
110115
|
+
* A basic service for coordinating interactions with the FIDO Metadata Service. This includes BLOB
|
|
110116
|
+
* download and parsing, and on-demand requesting and caching of individual metadata statements.
|
|
110117
|
+
*
|
|
110118
|
+
* https://fidoalliance.org/metadata/
|
|
110119
|
+
*/
|
|
110120
|
+
const MetadataService = new BaseMetadataService();
|
|
110121
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/services/convenienceMetadataService.js
|
|
110122
|
+
const defaultURLConvenienceMDS = "https://c-mds.fidoalliance.org/";
|
|
110123
|
+
var BaseConvenienceMetadataService = class extends BaseMDSService {
|
|
110124
|
+
constructor() {
|
|
110125
|
+
super("ConvenienceMetadataService");
|
|
110126
|
+
}
|
|
110127
|
+
async initialize(opts = {}) {
|
|
110128
|
+
const { mdsServers = [defaultURLConvenienceMDS], payloads, logger } = opts;
|
|
110129
|
+
this.beginInitialize(logger);
|
|
110130
|
+
/**
|
|
110131
|
+
* If passkey provider metadata is provided, load them into the cache first.
|
|
110132
|
+
*/
|
|
110133
|
+
if (payloads?.length) {
|
|
110134
|
+
let entriesAdded = 0;
|
|
110135
|
+
payloads.forEach((payload) => {
|
|
110136
|
+
entriesAdded += this.cacheConvenienceMDS("", payload);
|
|
110137
|
+
});
|
|
110138
|
+
this.logger.debug(`Cached ${entriesAdded} total local metadata entries`);
|
|
110139
|
+
}
|
|
110140
|
+
/**
|
|
110141
|
+
* If Convenience MDS server URLs are provided, then download and cache the current collection
|
|
110142
|
+
* of metadata from them.
|
|
110143
|
+
*/
|
|
110144
|
+
const numServers = await this.initializeServers(mdsServers);
|
|
110145
|
+
this.finishInitialize(payloads?.length, numServers);
|
|
110146
|
+
}
|
|
110147
|
+
/**
|
|
110148
|
+
* Download the convenience metadata, which is surprisingly just a JSON document, and cache it
|
|
110149
|
+
*/
|
|
110150
|
+
async downloadAndCache(url, no) {
|
|
110151
|
+
const resp = await this.fetchFromServer(url, no);
|
|
110152
|
+
if (!resp) return;
|
|
110153
|
+
const payload = await resp.json();
|
|
110154
|
+
return this.cacheConvenienceMDS(url, payload);
|
|
110155
|
+
}
|
|
110156
|
+
/**
|
|
110157
|
+
* Refresh failures cause that server's refresh to be re-attempted at a later date
|
|
110158
|
+
*/
|
|
110159
|
+
handleRefreshFailure(url) {
|
|
110160
|
+
this.delayNextRefresh(url, this.defaultRetryDelayHours);
|
|
110161
|
+
}
|
|
110162
|
+
/**
|
|
110163
|
+
* Cache the AAGUID-keyed entries in a Convenience MDS payload. Returns the number of entries
|
|
110164
|
+
* cached (so you can `count += cacheConvenienceMDS(...)`)
|
|
110165
|
+
*/
|
|
110166
|
+
cacheConvenienceMDS(url, payload) {
|
|
110167
|
+
let entriesAdded = 0;
|
|
110168
|
+
this.metadataCache.clearMetadataByURL(url);
|
|
110169
|
+
Object.keys(payload).forEach((aaguid) => {
|
|
110170
|
+
if (aaguid === "no") return;
|
|
110171
|
+
this.metadataCache.cacheMetadata(aaguid, payload[aaguid], url);
|
|
110172
|
+
entriesAdded += 1;
|
|
109703
110173
|
});
|
|
110174
|
+
this.metadataCache.registerMDSServer(url, payload.no, new Date(Date.now() + 36e5 * this.defaultRefreshDelayHours));
|
|
110175
|
+
return entriesAdded;
|
|
109704
110176
|
}
|
|
109705
110177
|
/**
|
|
109706
|
-
*
|
|
110178
|
+
* Get a collection of metadata about a credential manager, including localized name(s) and
|
|
110179
|
+
* light and dark iconography when available. Returns `undefined` if no such metadata has been
|
|
110180
|
+
* registered with a Convenience MDS.
|
|
109707
110181
|
*/
|
|
109708
|
-
|
|
109709
|
-
this.state
|
|
109710
|
-
|
|
109711
|
-
|
|
109712
|
-
|
|
110182
|
+
async getProviderMetadata(aaguid) {
|
|
110183
|
+
if (this.state.current === SERVICE_STATE.DISABLED) return;
|
|
110184
|
+
await this.state.pauseUntilReady();
|
|
110185
|
+
await this.refreshStaleServers();
|
|
110186
|
+
return this.metadataCache.getMetadata(aaguid);
|
|
109713
110187
|
}
|
|
109714
110188
|
};
|
|
109715
110189
|
/**
|
|
109716
|
-
* A basic service for coordinating interactions with the FIDO Metadata Service. This
|
|
109717
|
-
* download and parsing, and on-demand requesting and caching of
|
|
110190
|
+
* A basic service for coordinating interactions with the FIDO Convenience Metadata Service. This
|
|
110191
|
+
* includes metadata download and parsing, and on-demand requesting and caching of provider details.
|
|
109718
110192
|
*
|
|
109719
110193
|
* https://fidoalliance.org/metadata/
|
|
109720
110194
|
*/
|
|
109721
|
-
const
|
|
109722
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
110195
|
+
const ConvenienceMetadataService = new BaseConvenienceMetadataService();
|
|
110196
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/registration/verifications/verifyAttestationFIDOU2F.js
|
|
110197
|
+
/**
|
|
110198
|
+
* Verify an attestation response with fmt 'fido-u2f'
|
|
110199
|
+
*/
|
|
110200
|
+
async function verifyAttestationFIDOU2F(options) {
|
|
110201
|
+
const { attStmt, clientDataHash, rpIdHash, credentialID, credentialPublicKey, aaguid, rootCertificates } = options;
|
|
110202
|
+
const signatureBase = concat([
|
|
110203
|
+
Uint8Array.from([0]),
|
|
110204
|
+
rpIdHash,
|
|
110205
|
+
clientDataHash,
|
|
110206
|
+
credentialID,
|
|
110207
|
+
convertCOSEtoPKCS(credentialPublicKey)
|
|
110208
|
+
]);
|
|
110209
|
+
const sig = attStmt.get("sig");
|
|
110210
|
+
const x5c = attStmt.get("x5c");
|
|
110211
|
+
if (!x5c) throw new Error("No attestation certificate provided in attestation statement (FIDOU2F)");
|
|
110212
|
+
if (!sig) throw new Error("No attestation signature provided in attestation statement (FIDOU2F)");
|
|
110213
|
+
const aaguidToHex = Number.parseInt(toHex(aaguid), 16);
|
|
110214
|
+
if (aaguidToHex !== 0) throw new Error(`AAGUID "${aaguidToHex}" was not expected value`);
|
|
110215
|
+
try {
|
|
110216
|
+
await validateCertificatePath(x5c.map(convertCertBufferToPEM), rootCertificates);
|
|
110217
|
+
} catch (err) {
|
|
110218
|
+
throw new Error(`${err.message} (FIDOU2F)`);
|
|
110219
|
+
}
|
|
110220
|
+
return verifySignature({
|
|
110221
|
+
signature: sig,
|
|
110222
|
+
data: signatureBase,
|
|
110223
|
+
x509Certificate: x5c[0],
|
|
110224
|
+
hashAlgorithm: COSEALG.ES256
|
|
110225
|
+
});
|
|
110226
|
+
}
|
|
110227
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/validateExtFIDOGenCEAAGUID.js
|
|
110228
|
+
/**
|
|
110229
|
+
* Attestation Certificate Extension OID: `id-fido-gen-ce-aaguid`
|
|
110230
|
+
*
|
|
110231
|
+
* Sourced from https://fidoalliance.org/specs/fido-v2.0-ps-20150904/fido-key-attestation-v2.0-ps-20150904.html#verifying-an-attestation-statement
|
|
110232
|
+
*/
|
|
110233
|
+
const id_fido_gen_ce_aaguid = "1.3.6.1.4.1.45724.1.1.4";
|
|
110234
|
+
/**
|
|
110235
|
+
* Look for the id-fido-gen-ce-aaguid certificate extension. If it's present then check it against
|
|
110236
|
+
* the attestation statement AAGUID.
|
|
110237
|
+
*/
|
|
110238
|
+
function validateExtFIDOGenCEAAGUID(certExtensions, aaguid) {
|
|
110239
|
+
if (!certExtensions) return true;
|
|
110240
|
+
const extFIDOGenCEAAGUID = certExtensions.find((ext) => ext.extnID === id_fido_gen_ce_aaguid);
|
|
110241
|
+
if (!extFIDOGenCEAAGUID) return true;
|
|
110242
|
+
const parsedExtFIDOGenCEAAGUID = import_cjs$4.AsnParser.parse(extFIDOGenCEAAGUID.extnValue, import_cjs$4.OctetString);
|
|
110243
|
+
const extValue = new Uint8Array(parsedExtFIDOGenCEAAGUID.buffer);
|
|
110244
|
+
if (!areEqual(aaguid, extValue)) {
|
|
110245
|
+
const _debugExtHex = toHex(extValue);
|
|
110246
|
+
const _debugAAGUIDHex = toHex(aaguid);
|
|
110247
|
+
throw new Error(`Certificate extension id-fido-gen-ce-aaguid (${id_fido_gen_ce_aaguid}) value of "${_debugExtHex}" was present but not equal to attestation statement AAGUID value of "${_debugAAGUIDHex}"`);
|
|
110248
|
+
}
|
|
110249
|
+
return true;
|
|
110250
|
+
}
|
|
110251
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/metadata/verifyAttestationWithMetadata.js
|
|
109723
110252
|
/**
|
|
109724
110253
|
* Match properties of the authenticator's attestation statement against expected values as
|
|
109725
110254
|
* registered with the FIDO Alliance Metadata Service
|
|
@@ -109880,7 +110409,7 @@ function stringifyCOSEInfo(info) {
|
|
|
109880
110409
|
else toReturn = `{ kty: ${kty}, alg: ${alg} }`;
|
|
109881
110410
|
return toReturn;
|
|
109882
110411
|
}
|
|
109883
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
110412
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/registration/verifications/verifyAttestationPacked.js
|
|
109884
110413
|
/**
|
|
109885
110414
|
* Verify an attestation response with fmt 'packed'
|
|
109886
110415
|
*/
|
|
@@ -109945,7 +110474,7 @@ async function verifyAttestationPacked(options) {
|
|
|
109945
110474
|
});
|
|
109946
110475
|
return verified;
|
|
109947
110476
|
}
|
|
109948
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
110477
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/registration/verifications/verifyAttestationAndroidSafetyNet.js
|
|
109949
110478
|
/**
|
|
109950
110479
|
* Verify an attestation response with fmt 'android-safetynet'
|
|
109951
110480
|
*/
|
|
@@ -110014,7 +110543,7 @@ async function verifyAttestationAndroidSafetyNet(options) {
|
|
|
110014
110543
|
hashAlgorithm: alg
|
|
110015
110544
|
});
|
|
110016
110545
|
}
|
|
110017
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
110546
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/registration/verifications/tpm/constants.js
|
|
110018
110547
|
/**
|
|
110019
110548
|
* A whole lotta domain knowledge is captured here, with hazy connections to source
|
|
110020
110549
|
* documents. Good places to start searching for more info on these values are the
|
|
@@ -110233,13 +110762,13 @@ const TPM_MANUFACTURERS = {
|
|
|
110233
110762
|
* Match TPM public area curve ID's to `crv` numbers used in COSE public keys
|
|
110234
110763
|
*/
|
|
110235
110764
|
const TPM_ECC_CURVE_COSE_CRV_MAP = {
|
|
110236
|
-
TPM_ECC_NIST_P256:
|
|
110237
|
-
TPM_ECC_NIST_P384:
|
|
110238
|
-
TPM_ECC_NIST_P521:
|
|
110239
|
-
TPM_ECC_BN_P256:
|
|
110240
|
-
TPM_ECC_SM2_P256:
|
|
110765
|
+
TPM_ECC_NIST_P256: COSECRV.P256,
|
|
110766
|
+
TPM_ECC_NIST_P384: COSECRV.P384,
|
|
110767
|
+
TPM_ECC_NIST_P521: COSECRV.P521,
|
|
110768
|
+
TPM_ECC_BN_P256: COSECRV.P256,
|
|
110769
|
+
TPM_ECC_SM2_P256: COSECRV.P256
|
|
110241
110770
|
};
|
|
110242
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
110771
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/registration/verifications/tpm/parseCertInfo.js
|
|
110243
110772
|
/**
|
|
110244
110773
|
* Cut up a TPM attestation's certInfo into intelligible chunks
|
|
110245
110774
|
*/
|
|
@@ -110291,7 +110820,7 @@ function parseCertInfo(certInfo) {
|
|
|
110291
110820
|
}
|
|
110292
110821
|
};
|
|
110293
110822
|
}
|
|
110294
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
110823
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/registration/verifications/tpm/parsePubArea.js
|
|
110295
110824
|
/**
|
|
110296
110825
|
* Break apart a TPM attestation's pubArea buffer
|
|
110297
110826
|
*
|
|
@@ -110352,6 +110881,27 @@ function parsePubArea(pubArea) {
|
|
|
110352
110881
|
pointer += 2;
|
|
110353
110882
|
const scheme = TPM_ALG[dataView.getUint16(pointer)];
|
|
110354
110883
|
pointer += 2;
|
|
110884
|
+
/**
|
|
110885
|
+
* In TPM 2.0, a non-TPM_ALG_NULL scheme is followed by alg-specific "details" bytes.
|
|
110886
|
+
* For TPM_ALG_ECC this is defined as TPMT_ECC_SCHEME, which is the
|
|
110887
|
+
* scheme (TPMI_ALG_ECC_SCHEME) followed by details (TPMU_ECC_SCHEME).
|
|
110888
|
+
*
|
|
110889
|
+
* See 11.2.5.7 TPMT_ECC_SCHEME here:
|
|
110890
|
+
* https://medias.cdn.trustedcomputinggroup.org/production/Trusted_Platform_Module_2_0_Library_Part_2_Structures_Version_185_pub_c0a962a931.pdf >
|
|
110891
|
+
*/
|
|
110892
|
+
const details = {};
|
|
110893
|
+
if (scheme === "TPM_ALG_NULL") {} else if (scheme === "TPM_ALG_ECDSA") {
|
|
110894
|
+
details.hashAlg = TPM_ALG[dataView.getUint16(pointer)];
|
|
110895
|
+
pointer += 2;
|
|
110896
|
+
} else if (scheme === "TPM_ALG_ECSCHNORR") {
|
|
110897
|
+
details.hashAlg = TPM_ALG[dataView.getUint16(pointer)];
|
|
110898
|
+
pointer += 2;
|
|
110899
|
+
} else if (scheme === "TPM_ALG_ECDAA") {
|
|
110900
|
+
details.hashAlg = TPM_ALG[dataView.getUint16(pointer)];
|
|
110901
|
+
pointer += 2;
|
|
110902
|
+
details.count = dataView.getUint16(pointer);
|
|
110903
|
+
pointer += 2;
|
|
110904
|
+
}
|
|
110355
110905
|
const curveID = TPM_ECC_CURVE[dataView.getUint16(pointer)];
|
|
110356
110906
|
pointer += 2;
|
|
110357
110907
|
const kdf = TPM_ALG[dataView.getUint16(pointer)];
|
|
@@ -110359,6 +110909,7 @@ function parsePubArea(pubArea) {
|
|
|
110359
110909
|
parameters.ecc = {
|
|
110360
110910
|
symmetric,
|
|
110361
110911
|
scheme,
|
|
110912
|
+
details,
|
|
110362
110913
|
curveID,
|
|
110363
110914
|
kdf
|
|
110364
110915
|
};
|
|
@@ -110382,12 +110933,12 @@ function parsePubArea(pubArea) {
|
|
|
110382
110933
|
unique
|
|
110383
110934
|
};
|
|
110384
110935
|
}
|
|
110385
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
110936
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/registration/verifications/tpm/isValidTPMManufacturerID.js
|
|
110386
110937
|
function getTPMManufacturerInfo(id) {
|
|
110387
110938
|
const _normalized = `id:${id.substring(3).toUpperCase()}`;
|
|
110388
110939
|
return TPM_MANUFACTURERS[_normalized];
|
|
110389
110940
|
}
|
|
110390
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
110941
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/registration/verifications/tpm/verifyAttestationTPM.js
|
|
110391
110942
|
async function verifyAttestationTPM(options) {
|
|
110392
110943
|
const { aaguid, attStmt, authData, credentialPublicKey, clientDataHash, rootCertificates } = options;
|
|
110393
110944
|
const ver = attStmt.get("ver");
|
|
@@ -110422,17 +110973,19 @@ async function verifyAttestationTPM(options) {
|
|
|
110422
110973
|
if (pubAreaExponent !== eSum) throw new Error(`Unexpected public key exp ${eSum}, expected ${pubAreaExponent} (TPM|RSA)`);
|
|
110423
110974
|
} else if (pubType === "TPM_ALG_ECC") {
|
|
110424
110975
|
if (!isCOSEPublicKeyEC2(cosePublicKey)) throw new Error(`Credential public key with kty ${cosePublicKey.get(COSEKEYS.kty)} did not match ${pubType}`);
|
|
110425
|
-
const
|
|
110426
|
-
const
|
|
110427
|
-
const
|
|
110428
|
-
|
|
110429
|
-
if (!
|
|
110430
|
-
if (!
|
|
110431
|
-
if (!
|
|
110976
|
+
const pubKeyAlg = cosePublicKey.get(COSEKEYS.alg);
|
|
110977
|
+
const pubKeyCrv = cosePublicKey.get(COSEKEYS.crv);
|
|
110978
|
+
const pubKeyX = cosePublicKey.get(COSEKEYS.x);
|
|
110979
|
+
const pubKeyY = cosePublicKey.get(COSEKEYS.y);
|
|
110980
|
+
if (!pubKeyAlg) throw new Error("COSE public key missing crv (TPM|ECC)");
|
|
110981
|
+
if (!pubKeyCrv) throw new Error("COSE public key missing crv (TPM|ECC)");
|
|
110982
|
+
if (!pubKeyX) throw new Error("COSE public key missing x (TPM|ECC)");
|
|
110983
|
+
if (!pubKeyY) throw new Error("COSE public key missing y (TPM|ECC)");
|
|
110984
|
+
if (!areEqual(unique, concat([pubKeyX, pubKeyY]))) throw new Error("PubArea unique is not same as public key x and y (TPM|ECC)");
|
|
110432
110985
|
if (!parameters.ecc) throw new Error(`Parsed pubArea type is ECC, but missing parameters.ecc (TPM|ECC)`);
|
|
110433
110986
|
const pubAreaCurveID = parameters.ecc.curveID;
|
|
110434
110987
|
const pubAreaCurveIDMapToCOSECRV = TPM_ECC_CURVE_COSE_CRV_MAP[pubAreaCurveID];
|
|
110435
|
-
if (pubAreaCurveIDMapToCOSECRV !==
|
|
110988
|
+
if (pubAreaCurveIDMapToCOSECRV !== pubKeyCrv) throw new Error(`Public area key curve ID "${pubAreaCurveID}" mapped to "${pubAreaCurveIDMapToCOSECRV}" which did not match public key crv of "${pubKeyCrv}" (TPM|ECC)`);
|
|
110436
110989
|
} else throw new Error(`Unsupported pubArea.type "${pubType}"`);
|
|
110437
110990
|
const { magic, type: certType, attested, extraData } = parseCertInfo(certInfo);
|
|
110438
110991
|
if (magic !== 4283712327) throw new Error(`Unexpected magic value "${magic}", expected "0xff544347" (TPM)`);
|
|
@@ -111068,7 +111621,7 @@ var require_attestation = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
111068
111621
|
repeated: "set"
|
|
111069
111622
|
})], AttestationApplicationId.prototype, "signatureDigests", void 0);
|
|
111070
111623
|
}));
|
|
111071
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
111624
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/registration/verifications/verifyAttestationAndroidKey.js
|
|
111072
111625
|
var import_cjs = (/* @__PURE__ */ __commonJSMin(((exports) => {
|
|
111073
111626
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
111074
111627
|
const tslib_1 = (init_tslib_es6$1(), __toCommonJS(tslib_es6_exports$1));
|
|
@@ -111110,7 +111663,7 @@ async function verifyAttestationAndroidKey(options) {
|
|
|
111110
111663
|
* (i.e. These shouldn't contain the [600] tag)
|
|
111111
111664
|
*/
|
|
111112
111665
|
if (teeEnforced.allApplications !== void 0) throw new Error("teeEnforced contained \"allApplications [600]\" tag (Android Key)");
|
|
111113
|
-
if (softwareEnforced.allApplications !== void 0) throw new Error("
|
|
111666
|
+
if (softwareEnforced.allApplications !== void 0) throw new Error("softwareEnforced contained \"allApplications [600]\" tag (Android Key)");
|
|
111114
111667
|
const statement = await MetadataService.getStatement(aaguid);
|
|
111115
111668
|
if (statement) try {
|
|
111116
111669
|
await verifyAttestationWithMetadata({
|
|
@@ -111125,22 +111678,30 @@ async function verifyAttestationAndroidKey(options) {
|
|
|
111125
111678
|
}
|
|
111126
111679
|
else {
|
|
111127
111680
|
/**
|
|
111128
|
-
*
|
|
111681
|
+
* Fail closed if for some reason no root certificates were registered with SettingsService
|
|
111682
|
+
* for this attestation format. Android Key attestation statements are a bit unique in that they
|
|
111683
|
+
* contain a full certificate chain, which an attacker could abuse to perform arbitrary network
|
|
111684
|
+
* requests within the RP's boundary if we simply validated x5c like other attestation formats.
|
|
111129
111685
|
*/
|
|
111686
|
+
if (rootCertificates.length === 0) throw new Error("No root certificates were set with SettingsService for \"android-key\" attestation (Android Key)");
|
|
111130
111687
|
const x5cNoRootPEM = x5c.slice(0, -1).map(convertCertBufferToPEM);
|
|
111131
111688
|
const x5cRootPEM = x5c.slice(-1).map(convertCertBufferToPEM);
|
|
111689
|
+
/**
|
|
111690
|
+
* Make sure the final cert in x5c is one of the Google Hardware Attestation Root certificates
|
|
111691
|
+
* before we attempt to validate the certificate chain.
|
|
111692
|
+
*
|
|
111693
|
+
* https://developer.android.com/privacy-and-security/security-key-attestation#root_certificate
|
|
111694
|
+
*/
|
|
111695
|
+
if (rootCertificates.indexOf(x5cRootPEM[0]) < 0) throw new Error("x5c root certificate was not a known root certificate (Android Key)");
|
|
111696
|
+
/**
|
|
111697
|
+
* Verify that x5c contains a full certificate path.
|
|
111698
|
+
*/
|
|
111132
111699
|
try {
|
|
111133
111700
|
await validateCertificatePath(x5cNoRootPEM, x5cRootPEM);
|
|
111134
111701
|
} catch (err) {
|
|
111135
111702
|
const _err = err;
|
|
111136
111703
|
throw new Error(`${_err.message} (Android Key)`, { cause: _err });
|
|
111137
111704
|
}
|
|
111138
|
-
/**
|
|
111139
|
-
* Make sure the root certificate is one of the Google Hardware Attestation Root certificates
|
|
111140
|
-
*
|
|
111141
|
-
* https://developer.android.com/privacy-and-security/security-key-attestation#root_certificate
|
|
111142
|
-
*/
|
|
111143
|
-
if (rootCertificates.length > 0 && rootCertificates.indexOf(x5cRootPEM[0]) < 0) throw new Error("x5c root certificate was not a known root certificate (Android Key)");
|
|
111144
111705
|
}
|
|
111145
111706
|
return verifySignature({
|
|
111146
111707
|
signature: sig,
|
|
@@ -111149,7 +111710,7 @@ async function verifyAttestationAndroidKey(options) {
|
|
|
111149
111710
|
hashAlgorithm: alg
|
|
111150
111711
|
});
|
|
111151
111712
|
}
|
|
111152
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
111713
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/registration/verifications/verifyAttestationApple.js
|
|
111153
111714
|
async function verifyAttestationApple(options) {
|
|
111154
111715
|
const { attStmt, authData, clientDataHash, credentialPublicKey, rootCertificates } = options;
|
|
111155
111716
|
const x5c = attStmt.get("x5c");
|
|
@@ -111170,7 +111731,42 @@ async function verifyAttestationApple(options) {
|
|
|
111170
111731
|
if (!areEqual(convertCOSEtoPKCS(credentialPublicKey), new Uint8Array(subjectPublicKeyInfo.subjectPublicKey))) throw new Error("Credential public key does not equal credCert public key (Apple)");
|
|
111171
111732
|
return true;
|
|
111172
111733
|
}
|
|
111173
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
111734
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/assertValidExpectedOrigin.js
|
|
111735
|
+
/**
|
|
111736
|
+
* Check the origin to make sure it's valid to compare against what's reported in a WebAuthn
|
|
111737
|
+
* response.
|
|
111738
|
+
*
|
|
111739
|
+
* Invalid origins will raise a `SimpleWebAuthnError` with `code: 'BAD_ARGUMENT'`
|
|
111740
|
+
*/
|
|
111741
|
+
function assertValidExpectedOrigin(origin) {
|
|
111742
|
+
if (!origin.startsWith("https://")) return;
|
|
111743
|
+
if (origin.endsWith("/")) throw new SimpleWebAuthnError({
|
|
111744
|
+
message: `"${origin}" is not a valid expected origin. Remove the trailing "/" and try again`,
|
|
111745
|
+
code: "BAD_ARGUMENT"
|
|
111746
|
+
});
|
|
111747
|
+
const asciiOrigin = new URL(origin).origin;
|
|
111748
|
+
if (asciiOrigin !== origin) throw new SimpleWebAuthnError({
|
|
111749
|
+
message: `"${origin}" is not a valid expected origin. Replace it with its ASCII punycode representation "${asciiOrigin}" and try again`,
|
|
111750
|
+
code: "BAD_ARGUMENT"
|
|
111751
|
+
});
|
|
111752
|
+
}
|
|
111753
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/matchExpectedOrigin.js
|
|
111754
|
+
/**
|
|
111755
|
+
* Check that the origin reported in a WebAuthn response is an expected one.
|
|
111756
|
+
*
|
|
111757
|
+
* Raises a `SimpleWebAuthnError` if not match is found.
|
|
111758
|
+
*/
|
|
111759
|
+
function matchExpectedOrigin(origin, expectedOrigin) {
|
|
111760
|
+
let _expectedOrigins = [];
|
|
111761
|
+
if (typeof expectedOrigin === "string") _expectedOrigins = [expectedOrigin];
|
|
111762
|
+
else _expectedOrigins = expectedOrigin;
|
|
111763
|
+
for (const _origin of _expectedOrigins) assertValidExpectedOrigin(_origin);
|
|
111764
|
+
if (!_expectedOrigins.includes(origin)) throw new SimpleWebAuthnError({
|
|
111765
|
+
message: `Unexpected response origin "${origin}", expected one of: ${_expectedOrigins.join(", ")}`,
|
|
111766
|
+
code: "UNEXPECTED_ORIGIN"
|
|
111767
|
+
});
|
|
111768
|
+
}
|
|
111769
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/registration/verifyRegistrationResponse.js
|
|
111174
111770
|
/**
|
|
111175
111771
|
* Verify that the user has legitimately completed the registration process
|
|
111176
111772
|
*
|
|
@@ -111205,9 +111801,7 @@ async function verifyRegistrationResponse(options) {
|
|
|
111205
111801
|
if (typeof expectedChallenge === "function") {
|
|
111206
111802
|
if (!await expectedChallenge(challenge)) throw new Error(`Custom challenge verifier returned false for registration response challenge "${challenge}"`);
|
|
111207
111803
|
} else if (challenge !== expectedChallenge) throw new Error(`Unexpected registration response challenge "${challenge}", expected "${expectedChallenge}"`);
|
|
111208
|
-
|
|
111209
|
-
if (!expectedOrigin.includes(origin)) throw new Error(`Unexpected registration response origin "${origin}", expected one of: ${expectedOrigin.join(", ")}`);
|
|
111210
|
-
} else if (origin !== expectedOrigin) throw new Error(`Unexpected registration response origin "${origin}", expected "${expectedOrigin}"`);
|
|
111804
|
+
matchExpectedOrigin(origin, expectedOrigin);
|
|
111211
111805
|
if (tokenBinding) {
|
|
111212
111806
|
if (typeof tokenBinding !== "object") throw new Error(`Unexpected value for TokenBinding "${tokenBinding}"`);
|
|
111213
111807
|
if ([
|
|
@@ -111277,11 +111871,13 @@ async function verifyRegistrationResponse(options) {
|
|
|
111277
111871
|
} else throw new Error(`Unsupported Attestation Format: ${fmt}`);
|
|
111278
111872
|
if (!verified) return { verified: false };
|
|
111279
111873
|
const { credentialDeviceType, credentialBackedUp } = parseBackupFlags(flags);
|
|
111874
|
+
const formattedAAGUID = convertAAGUIDToString(aaguid);
|
|
111280
111875
|
return {
|
|
111281
111876
|
verified: true,
|
|
111282
111877
|
registrationInfo: {
|
|
111283
111878
|
fmt,
|
|
111284
|
-
aaguid:
|
|
111879
|
+
aaguid: formattedAAGUID,
|
|
111880
|
+
passkeyProviderMetadata: await MetadataService.getProviderMetadata(formattedAAGUID) ?? await ConvenienceMetadataService.getProviderMetadata(formattedAAGUID),
|
|
111285
111881
|
credentialType,
|
|
111286
111882
|
credential: {
|
|
111287
111883
|
id: fromBuffer(credentialID),
|
|
@@ -111299,7 +111895,7 @@ async function verifyRegistrationResponse(options) {
|
|
|
111299
111895
|
}
|
|
111300
111896
|
};
|
|
111301
111897
|
}
|
|
111302
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
111898
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/authentication/generateAuthenticationOptions.js
|
|
111303
111899
|
/**
|
|
111304
111900
|
* Prepare a value to pass into navigator.credentials.get(...) for authenticator authentication
|
|
111305
111901
|
*
|
|
@@ -111335,7 +111931,7 @@ async function generateAuthenticationOptions(options) {
|
|
|
111335
111931
|
extensions
|
|
111336
111932
|
};
|
|
111337
111933
|
}
|
|
111338
|
-
// ../../node_modules/.pnpm/@simplewebauthn+server@14.0
|
|
111934
|
+
// ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/authentication/verifyAuthenticationResponse.js
|
|
111339
111935
|
/**
|
|
111340
111936
|
* Verify that the user has legitimately completed the authentication process
|
|
111341
111937
|
*
|
|
@@ -111399,12 +111995,7 @@ async function verifyAuthenticationResponse(options) {
|
|
|
111399
111995
|
* See https://w3c.github.io/webauthn/#dom-collectedclientdata-toporigin.
|
|
111400
111996
|
*/
|
|
111401
111997
|
throw new Error(`Unexpected top origin of "${topOrigin}" within a non-cross-origin authentication response. This error should be reported to the browser vendor as a WebAuthn specification violation with a link to https://w3c.github.io/webauthn/#dom-collectedclientdata-toporigin`);
|
|
111402
|
-
|
|
111403
|
-
if (!expectedOrigin.includes(origin)) {
|
|
111404
|
-
const joinedExpectedOrigin = expectedOrigin.join(", ");
|
|
111405
|
-
throw new Error(`Unexpected authentication response origin "${origin}", expected one of: ${joinedExpectedOrigin}`);
|
|
111406
|
-
}
|
|
111407
|
-
} else if (origin !== expectedOrigin) throw new Error(`Unexpected authentication response origin "${origin}", expected "${expectedOrigin}"`);
|
|
111998
|
+
matchExpectedOrigin(origin, expectedOrigin);
|
|
111408
111999
|
if (!isBase64URL(assertionResponse.authenticatorData)) throw new Error("Credential response authenticatorData was not a base64url string");
|
|
111409
112000
|
if (!isBase64URL(assertionResponse.signature)) throw new Error("Credential response signature was not a base64url string");
|
|
111410
112001
|
if (assertionResponse.userHandle && typeof assertionResponse.userHandle !== "string") throw new Error("Credential response userHandle was not a string");
|