@finueva/auth 0.16.1 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/server.js CHANGED
@@ -8,16 +8,16 @@ const ENC_CARET_RE = /%5e/gi;
8
8
  const ENC_BACKTICK_RE = /%60/gi;
9
9
  const ENC_PIPE_RE = /%7c/gi;
10
10
  const ENC_SPACE_RE = /%20/gi;
11
- function encode(text) {
11
+ function encode$2(text) {
12
12
  return encodeURI("" + text).replace(ENC_PIPE_RE, "|");
13
13
  }
14
14
  function encodeQueryValue(input) {
15
- return encode(typeof input === "string" ? input : JSON.stringify(input)).replace(PLUS_RE, "%2B").replace(ENC_SPACE_RE, "+").replace(HASH_RE, "%23").replace(AMPERSAND_RE, "%26").replace(ENC_BACKTICK_RE, "`").replace(ENC_CARET_RE, "^").replace(SLASH_RE, "%2F");
15
+ return encode$2(typeof input === "string" ? input : JSON.stringify(input)).replace(PLUS_RE, "%2B").replace(ENC_SPACE_RE, "+").replace(HASH_RE, "%23").replace(AMPERSAND_RE, "%26").replace(ENC_BACKTICK_RE, "`").replace(ENC_CARET_RE, "^").replace(SLASH_RE, "%2F");
16
16
  }
17
17
  function encodeQueryKey(text) {
18
18
  return encodeQueryValue(text).replace(EQUAL_RE, "%3D");
19
19
  }
20
- function decode(text = "") {
20
+ function decode$1(text = "") {
21
21
  try {
22
22
  return decodeURIComponent("" + text);
23
23
  } catch {
@@ -25,10 +25,10 @@ function decode(text = "") {
25
25
  }
26
26
  }
27
27
  function decodeQueryKey(text) {
28
- return decode(text.replace(PLUS_RE, " "));
28
+ return decode$1(text.replace(PLUS_RE, " "));
29
29
  }
30
30
  function decodeQueryValue(text) {
31
- return decode(text.replace(PLUS_RE, " "));
31
+ return decode$1(text.replace(PLUS_RE, " "));
32
32
  }
33
33
  function parseQuery(parametersString = "") {
34
34
  const object = Object.create(null);
@@ -187,6 +187,7 @@ const messages = {
187
187
  recipient_unavailable: "The recipient is unavailable.",
188
188
  invitation_recipient_mismatch: "The invitation cannot be accepted by this account.",
189
189
  invitation_recovery_required: "Invitation administration requires separate recovery.",
190
+ membership_removal_recovery_required: "Membership removal requires separate recovery.",
190
191
  email_verification_required: "Email verification is required.",
191
192
  invalid_workspace_selection: "The workspace selection is invalid.",
192
193
  organization_context_too_large: "The organization context is too large.",
@@ -212,1278 +213,2682 @@ var AuthError = class extends Error {
212
213
  }
213
214
  };
214
215
  //#endregion
215
- //#region src/shared.ts
216
- const DRIVE_CREDENTIAL_LIFETIME_SECONDS = 840;
217
- const id = /^[A-Za-z0-9_-]{1,128}$/;
218
- const email = /^[^\s@]+@[^\s@]+$/;
219
- const MAX_SOCIAL_ID_TOKEN_BYTES = 16 * 1024;
220
- function normalizeEmail(value) {
221
- if (typeof value !== "string") throw new TypeError("email is invalid");
222
- const normalized = value.trim().toLowerCase();
223
- if (normalized.length === 0 || normalized.length > 320 || !email.test(normalized)) throw new TypeError("email is invalid");
224
- return normalized;
216
+ //#region src/user-api/credential.ts
217
+ function userApiApplication(input) {
218
+ if (!input || typeof input.applicationId !== "string" || !/^[A-Za-z0-9_-]{1,128}$(?![\s\S])/.test(input.applicationId) || input.forceRefresh !== void 0 && typeof input.forceRefresh !== "boolean") throw new TypeError("User API credential input is invalid");
219
+ return input.applicationId;
225
220
  }
226
- function normalizeSocialIdTokenInput(value) {
227
- if (!isObject(value)) throw new TypeError("social ID token input is invalid");
228
- const keys = Object.keys(value);
229
- if (keys.length !== 3 && keys.length !== 4 || keys.some((key) => key !== "provider" && key !== "idToken" && key !== "nonce" && key !== "signUp") || value.provider !== "google" && value.provider !== "apple" || typeof value.signUp !== "boolean" || typeof value.idToken !== "string" || value.idToken.length < 1 || new TextEncoder().encode(value.idToken).byteLength > MAX_SOCIAL_ID_TOKEN_BYTES || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(value.idToken) || value.nonce !== void 0 && (typeof value.nonce !== "string" || value.nonce.length < 1 || value.nonce.length > 256 || !/^[\x20-\x7e]+$/.test(value.nonce))) throw new TypeError("social ID token input is invalid");
221
+ function normalizeUserApiCredential(value, startedAt) {
222
+ if (!value || typeof value !== "object" || Array.isArray(value) || !("tokenType" in value) || value.tokenType !== "Bearer" || !("token" in value) || typeof value.token !== "string" || value.token.length + 7 > 16 * 1024 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(value.token) || !("expiresIn" in value) || typeof value.expiresIn !== "number" || !Number.isInteger(value.expiresIn) || value.expiresIn < 1 || value.expiresIn > 840 || Object.keys(value).sort().join(",") !== "expiresIn,token,tokenType") throw new AuthError("identity_authority_unavailable", 503);
230
223
  return {
231
- provider: value.provider,
232
- idToken: value.idToken,
233
- ...value.nonce === void 0 ? {} : { nonce: value.nonce },
234
- signUp: value.signUp
224
+ tokenType: "Bearer",
225
+ token: value.token,
226
+ expiresAt: new Date(startedAt + value.expiresIn * 1e3)
235
227
  };
236
228
  }
237
- function socialIdTokenRequest(value) {
238
- return {
239
- provider: value.provider,
240
- idToken: {
241
- token: value.idToken,
242
- ...value.nonce === void 0 ? {} : { nonce: value.nonce }
243
- },
244
- requestSignUp: value.signUp
245
- };
229
+ //#endregion
230
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/buffer_utils.js
231
+ const encoder$1 = new TextEncoder();
232
+ const decoder = new TextDecoder();
233
+ function concat(...buffers) {
234
+ const size = buffers.reduce((acc, { length }) => acc + length, 0);
235
+ const buf = new Uint8Array(size);
236
+ let i = 0;
237
+ for (const buffer of buffers) {
238
+ buf.set(buffer, i);
239
+ i += buffer.length;
240
+ }
241
+ return buf;
242
+ }
243
+ function encode$1(string) {
244
+ const bytes = new Uint8Array(string.length);
245
+ for (let i = 0; i < string.length; i++) {
246
+ const code = string.charCodeAt(i);
247
+ if (code > 127) throw new TypeError("non-ASCII string encountered in encode()");
248
+ bytes[i] = code;
249
+ }
250
+ return bytes;
246
251
  }
247
- function normalizeOrigin(value, name) {
248
- if (value.length === 0 || value.length > 2048 || /[^\x20-\x7e]/.test(value)) throw new TypeError(`${name} must be an ASCII HTTP origin`);
249
- let url;
252
+ //#endregion
253
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/base64.js
254
+ function encodeBase64(input) {
255
+ if (Uint8Array.prototype.toBase64) return input.toBase64();
256
+ const CHUNK_SIZE = 32768;
257
+ const arr = [];
258
+ for (let i = 0; i < input.length; i += CHUNK_SIZE) arr.push(String.fromCharCode.apply(null, input.subarray(i, i + CHUNK_SIZE)));
259
+ return btoa(arr.join(""));
260
+ }
261
+ function decodeBase64(encoded) {
262
+ if (Uint8Array.fromBase64) return Uint8Array.fromBase64(encoded);
263
+ const binary = atob(encoded);
264
+ const bytes = new Uint8Array(binary.length);
265
+ for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
266
+ return bytes;
267
+ }
268
+ //#endregion
269
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/util/base64url.js
270
+ function decode(input) {
271
+ if (Uint8Array.fromBase64) return Uint8Array.fromBase64(typeof input === "string" ? input : decoder.decode(input), { alphabet: "base64url" });
272
+ let encoded = input;
273
+ if (encoded instanceof Uint8Array) encoded = decoder.decode(encoded);
274
+ encoded = encoded.replace(/-/g, "+").replace(/_/g, "/");
250
275
  try {
251
- url = new URL(value);
276
+ return decodeBase64(encoded);
252
277
  } catch {
253
- throw new TypeError(`${name} must be an ASCII HTTP origin`);
278
+ throw new TypeError("The input to be decoded is not correctly encoded.");
254
279
  }
255
- const local = url.hostname === "localhost" || url.hostname.endsWith(".localhost") || url.hostname === "127.0.0.1";
256
- if (url.protocol !== "https:" && !(local && url.protocol === "http:") || url.username || url.password || url.pathname !== "/" || url.search || url.hash || url.origin !== value) throw new TypeError(`${name} must be an ASCII HTTP origin`);
257
- return url.origin;
258
280
  }
259
- function normalizeTimeout(value) {
260
- const timeout = value ?? 1e4;
261
- if (!Number.isSafeInteger(timeout) || timeout < 1 || timeout > 6e4) throw new TypeError("timeoutMs must be an integer from 1 to 60000");
262
- return timeout;
281
+ function encode(input) {
282
+ let unencoded = input;
283
+ if (typeof unencoded === "string") unencoded = encoder$1.encode(unencoded);
284
+ if (Uint8Array.prototype.toBase64) return unencoded.toBase64({
285
+ alphabet: "base64url",
286
+ omitPadding: true
287
+ });
288
+ return encodeBase64(unencoded).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
263
289
  }
264
- function normalizeSession(value) {
265
- if (value === null) return null;
266
- if (!isObject(value) || !isObject(value.session) || !isObject(value.user)) throw authorityUnavailable();
267
- const expiresAt = toDate(value.session.expiresAt);
268
- const image = value.user.image;
269
- if (!isId(value.session.id) || !expiresAt || !isId(value.user.id) || typeof value.user.name !== "string" || value.user.name.length > 256 || typeof value.user.email !== "string" || value.user.email.length > 320 || !email.test(value.user.email) || typeof value.user.emailVerified !== "boolean" || image !== null && image !== void 0 && (typeof image !== "string" || image.length > 2048)) throw authorityUnavailable();
270
- return {
271
- id: value.session.id,
272
- expiresAt,
273
- user: {
274
- id: value.user.id,
275
- name: value.user.name,
276
- email: value.user.email,
277
- emailVerified: value.user.emailVerified,
278
- image: image ?? null
290
+ //#endregion
291
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/crypto_key.js
292
+ const unusable = (name, prop = "algorithm.name") => new TypeError(`CryptoKey does not support this operation, its ${prop} must be ${name}`);
293
+ const isAlgorithm = (algorithm, name) => algorithm.name === name;
294
+ function getHashLength(hash) {
295
+ return parseInt(hash.name.slice(4), 10);
296
+ }
297
+ function checkHashLength(algorithm, expected) {
298
+ if (getHashLength(algorithm.hash) !== expected) throw unusable(`SHA-${expected}`, "algorithm.hash");
299
+ }
300
+ function getNamedCurve(alg) {
301
+ switch (alg) {
302
+ case "ES256": return "P-256";
303
+ case "ES384": return "P-384";
304
+ case "ES512": return "P-521";
305
+ default: throw new Error("unreachable");
306
+ }
307
+ }
308
+ function checkUsage(key, usage) {
309
+ if (usage && !key.usages.includes(usage)) throw new TypeError(`CryptoKey does not support this operation, its usages must include ${usage}.`);
310
+ }
311
+ function checkSigCryptoKey(key, alg, usage) {
312
+ switch (alg) {
313
+ case "HS256":
314
+ case "HS384":
315
+ case "HS512":
316
+ if (!isAlgorithm(key.algorithm, "HMAC")) throw unusable("HMAC");
317
+ checkHashLength(key.algorithm, parseInt(alg.slice(2), 10));
318
+ break;
319
+ case "RS256":
320
+ case "RS384":
321
+ case "RS512":
322
+ if (!isAlgorithm(key.algorithm, "RSASSA-PKCS1-v1_5")) throw unusable("RSASSA-PKCS1-v1_5");
323
+ checkHashLength(key.algorithm, parseInt(alg.slice(2), 10));
324
+ break;
325
+ case "PS256":
326
+ case "PS384":
327
+ case "PS512":
328
+ if (!isAlgorithm(key.algorithm, "RSA-PSS")) throw unusable("RSA-PSS");
329
+ checkHashLength(key.algorithm, parseInt(alg.slice(2), 10));
330
+ break;
331
+ case "Ed25519":
332
+ case "EdDSA":
333
+ if (!isAlgorithm(key.algorithm, "Ed25519")) throw unusable("Ed25519");
334
+ break;
335
+ case "ML-DSA-44":
336
+ case "ML-DSA-65":
337
+ case "ML-DSA-87":
338
+ if (!isAlgorithm(key.algorithm, alg)) throw unusable(alg);
339
+ break;
340
+ case "ES256":
341
+ case "ES384":
342
+ case "ES512": {
343
+ if (!isAlgorithm(key.algorithm, "ECDSA")) throw unusable("ECDSA");
344
+ const expected = getNamedCurve(alg);
345
+ if (key.algorithm.namedCurve !== expected) throw unusable(expected, "algorithm.namedCurve");
346
+ break;
279
347
  }
280
- };
348
+ default: throw new TypeError("CryptoKey does not support this operation");
349
+ }
350
+ checkUsage(key, usage);
281
351
  }
282
- function normalizeDriveCredential(value, now) {
283
- if (!isObject(value) || value.tokenType !== "Bearer" || value.expiresIn !== DRIVE_CREDENTIAL_LIFETIME_SECONDS || typeof value.token !== "string" || value.token.length === 0 || new TextEncoder().encode(`Bearer ${value.token}`).byteLength > 16 * 1024) throw authorityUnavailable();
284
- return {
285
- tokenType: "Bearer",
286
- token: value.token,
287
- expiresAt: new Date(now + value.expiresIn * 1e3)
288
- };
352
+ //#endregion
353
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/invalid_key_input.js
354
+ function message(msg, actual, ...types) {
355
+ types = types.filter(Boolean);
356
+ if (types.length > 2) {
357
+ const last = types.pop();
358
+ msg += `one of type ${types.join(", ")}, or ${last}.`;
359
+ } else if (types.length === 2) msg += `one of type ${types[0]} or ${types[1]}.`;
360
+ else msg += `of type ${types[0]}.`;
361
+ if (actual == null) msg += ` Received ${actual}`;
362
+ else if (typeof actual === "function" && actual.name) msg += ` Received function ${actual.name}`;
363
+ else if (typeof actual === "object" && actual != null) {
364
+ if (actual.constructor?.name) msg += ` Received an instance of ${actual.constructor.name}`;
365
+ }
366
+ return msg;
289
367
  }
290
- function normalizeOrganizationPageInput(value) {
291
- if (value === void 0) return new URLSearchParams();
292
- if (!isObject(value) || Object.keys(value).some((key) => key !== "limit" && key !== "cursor")) throw new AuthError("invalid_request", 400);
293
- const input = value;
294
- const query = new URLSearchParams();
295
- if (input.limit !== void 0) {
296
- if (!Number.isSafeInteger(input.limit) || input.limit < 1 || input.limit > 100) throw new AuthError("invalid_request", 400);
297
- query.set("limit", String(input.limit));
368
+ const invalidKeyInput = (actual, ...types) => message("Key must be ", actual, ...types);
369
+ const withAlg = (alg, actual, ...types) => message(`Key for the ${alg} algorithm must be `, actual, ...types);
370
+ //#endregion
371
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/util/errors.js
372
+ var JOSEError = class extends Error {
373
+ static code = "ERR_JOSE_GENERIC";
374
+ code = "ERR_JOSE_GENERIC";
375
+ constructor(message, options) {
376
+ super(message, options);
377
+ this.name = this.constructor.name;
378
+ Error.captureStackTrace?.(this, this.constructor);
298
379
  }
299
- if (input.cursor !== void 0) {
300
- if (typeof input.cursor !== "string" || input.cursor.length < 1 || input.cursor.length > 820 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(input.cursor)) throw new AuthError("invalid_request", 400);
301
- query.set("cursor", input.cursor);
380
+ };
381
+ var JWTClaimValidationFailed = class extends JOSEError {
382
+ static code = "ERR_JWT_CLAIM_VALIDATION_FAILED";
383
+ code = "ERR_JWT_CLAIM_VALIDATION_FAILED";
384
+ claim;
385
+ reason;
386
+ payload;
387
+ constructor(message, payload, claim = "unspecified", reason = "unspecified") {
388
+ super(message, { cause: {
389
+ claim,
390
+ reason,
391
+ payload
392
+ } });
393
+ this.claim = claim;
394
+ this.reason = reason;
395
+ this.payload = payload;
302
396
  }
303
- return query;
304
- }
305
- function normalizeIdInput(value) {
306
- if (!isId(value)) throw new AuthError("invalid_request", 400);
307
- return value;
308
- }
309
- function normalizeOrganization(value) {
310
- exact$2(value, [
311
- "capabilities",
312
- "id",
313
- "lifecycle",
314
- "logo",
315
- "name",
316
- "role",
317
- "slug"
318
- ]);
319
- if (!isId(value.id) || !boundedString(value.name, 255) || !boundedString(value.slug, 255) || value.lifecycle !== "ordinary" && value.lifecycle !== "managed" || !role(value.role) || !isObject(value.capabilities)) throw authorityUnavailable();
320
- exact$2(value.capabilities, [
321
- "readInvitations",
322
- "readMembers",
323
- "readTeams"
324
- ]);
325
- if (value.capabilities.readMembers !== true || value.capabilities.readTeams !== true || typeof value.capabilities.readInvitations !== "boolean") throw authorityUnavailable();
326
- return {
327
- id: value.id,
328
- name: value.name,
329
- slug: value.slug,
330
- logo: nullableHttpsUrl(value.logo),
331
- lifecycle: value.lifecycle,
332
- role: value.role,
333
- capabilities: {
334
- readMembers: true,
335
- readTeams: true,
336
- readInvitations: value.capabilities.readInvitations
337
- }
338
- };
339
- }
340
- function normalizeOrganizationDisplayInput(value) {
341
- if (!isObject(value) || Object.keys(value).sort().join(",") !== "logo,name,slug") throw new AuthError("invalid_request", 400);
342
- if (!boundedString(value.name, 255) || !boundedString(value.slug, 255)) throw new AuthError("invalid_request", 400);
343
- let logo;
397
+ };
398
+ var JWTExpired = class extends JOSEError {
399
+ static code = "ERR_JWT_EXPIRED";
400
+ code = "ERR_JWT_EXPIRED";
401
+ claim;
402
+ reason;
403
+ payload;
404
+ constructor(message, payload, claim = "unspecified", reason = "unspecified") {
405
+ super(message, { cause: {
406
+ claim,
407
+ reason,
408
+ payload
409
+ } });
410
+ this.claim = claim;
411
+ this.reason = reason;
412
+ this.payload = payload;
413
+ }
414
+ };
415
+ var JOSEAlgNotAllowed = class extends JOSEError {
416
+ static code = "ERR_JOSE_ALG_NOT_ALLOWED";
417
+ code = "ERR_JOSE_ALG_NOT_ALLOWED";
418
+ };
419
+ var JOSENotSupported = class extends JOSEError {
420
+ static code = "ERR_JOSE_NOT_SUPPORTED";
421
+ code = "ERR_JOSE_NOT_SUPPORTED";
422
+ };
423
+ var JWSInvalid = class extends JOSEError {
424
+ static code = "ERR_JWS_INVALID";
425
+ code = "ERR_JWS_INVALID";
426
+ };
427
+ var JWTInvalid = class extends JOSEError {
428
+ static code = "ERR_JWT_INVALID";
429
+ code = "ERR_JWT_INVALID";
430
+ };
431
+ var JWKInvalid = class extends JOSEError {
432
+ static code = "ERR_JWK_INVALID";
433
+ code = "ERR_JWK_INVALID";
434
+ };
435
+ var JWSSignatureVerificationFailed = class extends JOSEError {
436
+ static code = "ERR_JWS_SIGNATURE_VERIFICATION_FAILED";
437
+ code = "ERR_JWS_SIGNATURE_VERIFICATION_FAILED";
438
+ constructor(message = "signature verification failed", options) {
439
+ super(message, options);
440
+ }
441
+ };
442
+ //#endregion
443
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/is_key_like.js
444
+ const isCryptoKey = (key) => {
445
+ if (key?.[Symbol.toStringTag] === "CryptoKey") return true;
344
446
  try {
345
- logo = nullableHttpsUrl(value.logo);
447
+ return key instanceof CryptoKey;
346
448
  } catch {
347
- throw new AuthError("invalid_request", 400);
449
+ return false;
348
450
  }
349
- return {
350
- name: value.name,
351
- slug: value.slug,
352
- logo
353
- };
354
- }
355
- function normalizeOrganizationDisplay(value) {
451
+ };
452
+ const isKeyObject = (key) => key?.[Symbol.toStringTag] === "KeyObject";
453
+ const isKeyLike = (key) => isCryptoKey(key) || isKeyObject(key);
454
+ //#endregion
455
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/helpers.js
456
+ function decodeBase64url(value, label, ErrorClass) {
356
457
  try {
357
- return normalizeOrganizationDisplayInput(value);
458
+ return decode(value);
358
459
  } catch {
359
- throw authorityUnavailable();
460
+ throw new ErrorClass(`Failed to base64url decode the ${label}`);
360
461
  }
361
462
  }
362
- function normalizeOrganizationTeamDisplayInput(value) {
363
- if (!isObject(value) || Object.keys(value).join(",") !== "name" || !boundedString(value.name, 255)) throw new AuthError("invalid_request", 400);
364
- return { name: value.name };
463
+ async function digest(algorithm, data) {
464
+ const subtleDigest = `SHA-${algorithm.slice(-3)}`;
465
+ return new Uint8Array(await crypto.subtle.digest(subtleDigest, data));
365
466
  }
366
- function normalizeOrganizationTeamDisplay(value) {
367
- try {
368
- return normalizeOrganizationTeamDisplayInput(value);
369
- } catch {
370
- throw authorityUnavailable();
467
+ //#endregion
468
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/type_checks.js
469
+ const isObjectLike = (value) => typeof value === "object" && value !== null;
470
+ function isObject$1(input) {
471
+ if (!isObjectLike(input) || Object.prototype.toString.call(input) !== "[object Object]") return false;
472
+ if (Object.getPrototypeOf(input) === null) return true;
473
+ let proto = input;
474
+ while (Object.getPrototypeOf(proto) !== null) proto = Object.getPrototypeOf(proto);
475
+ return Object.getPrototypeOf(input) === proto;
476
+ }
477
+ function isDisjoint(...headers) {
478
+ const sources = headers.filter(Boolean);
479
+ if (sources.length === 0 || sources.length === 1) return true;
480
+ let acc;
481
+ for (const header of sources) {
482
+ const parameters = Object.keys(header);
483
+ if (!acc || acc.size === 0) {
484
+ acc = new Set(parameters);
485
+ continue;
486
+ }
487
+ for (const parameter of parameters) {
488
+ if (acc.has(parameter)) return false;
489
+ acc.add(parameter);
490
+ }
371
491
  }
492
+ return true;
372
493
  }
373
- function normalizeOrganizationTeamCreationInput(name, idempotencyKey) {
374
- if (!boundedString(name, 255) || !boundedString(idempotencyKey, 255)) throw new AuthError("invalid_request", 400);
375
- return {
376
- name,
377
- idempotencyKey
378
- };
494
+ const isJWK = (key) => isObject$1(key) && typeof key.kty === "string";
495
+ const isPrivateJWK = (key) => key.kty !== "oct" && (key.kty === "AKP" && typeof key.priv === "string" || typeof key.d === "string");
496
+ const isPublicJWK = (key) => key.kty !== "oct" && key.d === void 0 && key.priv === void 0;
497
+ const isSecretJWK = (key) => key.kty === "oct" && typeof key.k === "string";
498
+ //#endregion
499
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/signing.js
500
+ function checkKeyLength(alg, key) {
501
+ if (alg.startsWith("RS") || alg.startsWith("PS")) {
502
+ const { modulusLength } = key.algorithm;
503
+ if (typeof modulusLength !== "number" || modulusLength < 2048) throw new TypeError(`${alg} requires key modulusLength to be 2048 bits or larger`);
504
+ }
379
505
  }
380
- function normalizeCreatedOrganizationTeam(value) {
381
- exact$2(value, ["id", "name"]);
382
- if (!isId(value.id) || !boundedString(value.name, 255)) throw authorityUnavailable();
383
- return {
384
- id: value.id,
385
- name: value.name
386
- };
506
+ function subtleAlgorithm(alg, algorithm) {
507
+ const hash = `SHA-${alg.slice(-3)}`;
508
+ switch (alg) {
509
+ case "HS256":
510
+ case "HS384":
511
+ case "HS512": return {
512
+ hash,
513
+ name: "HMAC"
514
+ };
515
+ case "PS256":
516
+ case "PS384":
517
+ case "PS512": return {
518
+ hash,
519
+ name: "RSA-PSS",
520
+ saltLength: parseInt(alg.slice(-3), 10) >> 3
521
+ };
522
+ case "RS256":
523
+ case "RS384":
524
+ case "RS512": return {
525
+ hash,
526
+ name: "RSASSA-PKCS1-v1_5"
527
+ };
528
+ case "ES256":
529
+ case "ES384":
530
+ case "ES512": return {
531
+ hash,
532
+ name: "ECDSA",
533
+ namedCurve: algorithm.namedCurve
534
+ };
535
+ case "Ed25519":
536
+ case "EdDSA": return { name: "Ed25519" };
537
+ case "ML-DSA-44":
538
+ case "ML-DSA-65":
539
+ case "ML-DSA-87": return { name: alg };
540
+ default: throw new JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`);
541
+ }
387
542
  }
388
- function normalizeOrganizationMemberInvitationCreationInput(value) {
389
- if (!isObject(value)) throw new AuthError("invalid_request", 400);
390
- const keys = Object.keys(value).sort().join(",");
391
- if (keys !== "email,idempotencyKey" && keys !== "email,idempotencyKey,teamIds") throw new AuthError("invalid_request", 400);
392
- let normalizedEmail;
543
+ async function getSigKey(alg, key, usage) {
544
+ if (key instanceof Uint8Array) {
545
+ if (!alg.startsWith("HS")) throw new TypeError(invalidKeyInput(key, "CryptoKey", "KeyObject", "JSON Web Key"));
546
+ return crypto.subtle.importKey("raw", key, {
547
+ hash: `SHA-${alg.slice(-3)}`,
548
+ name: "HMAC"
549
+ }, false, [usage]);
550
+ }
551
+ checkSigCryptoKey(key, alg, usage);
552
+ return key;
553
+ }
554
+ async function verify(alg, key, signature, data) {
555
+ const cryptoKey = await getSigKey(alg, key, "verify");
556
+ checkKeyLength(alg, cryptoKey);
557
+ const algorithm = subtleAlgorithm(alg, cryptoKey.algorithm);
393
558
  try {
394
- normalizedEmail = normalizeEmail(value.email);
559
+ return await crypto.subtle.verify(algorithm, cryptoKey, signature, data);
395
560
  } catch {
396
- throw new AuthError("invalid_request", 400);
561
+ return false;
397
562
  }
398
- if (new TextEncoder().encode(normalizedEmail).byteLength > 320 || !boundedString(value.idempotencyKey, 255) || value.teamIds !== void 0 && (!Array.isArray(value.teamIds) || value.teamIds.length > 100)) throw new AuthError("invalid_request", 400);
399
- const teamIds = value.teamIds?.map((teamId) => normalizeIdInput(teamId));
400
- if (teamIds && new Set(teamIds).size !== teamIds.length) throw new AuthError("invalid_request", 400);
401
- return {
402
- email: normalizedEmail,
403
- ...teamIds === void 0 ? {} : { teamIds },
404
- idempotencyKey: value.idempotencyKey
405
- };
406
563
  }
407
- function normalizeCreatedOrganizationMemberInvitation(value) {
408
- exact$2(value, ["expiresAt", "id"]);
409
- if (!isId(value.id)) throw authorityUnavailable();
564
+ //#endregion
565
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/jwk_to_key.js
566
+ const unsupportedAlg = "Invalid or unsupported JWK \"alg\" (Algorithm) Parameter value";
567
+ function subtleMapping(jwk) {
568
+ let algorithm;
569
+ let keyUsages;
570
+ switch (jwk.kty) {
571
+ case "AKP":
572
+ switch (jwk.alg) {
573
+ case "ML-DSA-44":
574
+ case "ML-DSA-65":
575
+ case "ML-DSA-87":
576
+ algorithm = { name: jwk.alg };
577
+ keyUsages = jwk.priv ? ["sign"] : ["verify"];
578
+ break;
579
+ default: throw new JOSENotSupported(unsupportedAlg);
580
+ }
581
+ break;
582
+ case "RSA":
583
+ switch (jwk.alg) {
584
+ case "PS256":
585
+ case "PS384":
586
+ case "PS512":
587
+ algorithm = {
588
+ name: "RSA-PSS",
589
+ hash: `SHA-${jwk.alg.slice(-3)}`
590
+ };
591
+ keyUsages = jwk.d ? ["sign"] : ["verify"];
592
+ break;
593
+ case "RS256":
594
+ case "RS384":
595
+ case "RS512":
596
+ algorithm = {
597
+ name: "RSASSA-PKCS1-v1_5",
598
+ hash: `SHA-${jwk.alg.slice(-3)}`
599
+ };
600
+ keyUsages = jwk.d ? ["sign"] : ["verify"];
601
+ break;
602
+ case "RSA-OAEP":
603
+ case "RSA-OAEP-256":
604
+ case "RSA-OAEP-384":
605
+ case "RSA-OAEP-512":
606
+ algorithm = {
607
+ name: "RSA-OAEP",
608
+ hash: `SHA-${parseInt(jwk.alg.slice(-3), 10) || 1}`
609
+ };
610
+ keyUsages = jwk.d ? ["decrypt", "unwrapKey"] : ["encrypt", "wrapKey"];
611
+ break;
612
+ default: throw new JOSENotSupported(unsupportedAlg);
613
+ }
614
+ break;
615
+ case "EC":
616
+ switch (jwk.alg) {
617
+ case "ES256":
618
+ case "ES384":
619
+ case "ES512":
620
+ algorithm = {
621
+ name: "ECDSA",
622
+ namedCurve: {
623
+ ES256: "P-256",
624
+ ES384: "P-384",
625
+ ES512: "P-521"
626
+ }[jwk.alg]
627
+ };
628
+ keyUsages = jwk.d ? ["sign"] : ["verify"];
629
+ break;
630
+ case "ECDH-ES":
631
+ case "ECDH-ES+A128KW":
632
+ case "ECDH-ES+A192KW":
633
+ case "ECDH-ES+A256KW":
634
+ algorithm = {
635
+ name: "ECDH",
636
+ namedCurve: jwk.crv
637
+ };
638
+ keyUsages = jwk.d ? ["deriveBits"] : [];
639
+ break;
640
+ default: throw new JOSENotSupported(unsupportedAlg);
641
+ }
642
+ break;
643
+ case "OKP":
644
+ switch (jwk.alg) {
645
+ case "Ed25519":
646
+ case "EdDSA":
647
+ algorithm = { name: "Ed25519" };
648
+ keyUsages = jwk.d ? ["sign"] : ["verify"];
649
+ break;
650
+ case "ECDH-ES":
651
+ case "ECDH-ES+A128KW":
652
+ case "ECDH-ES+A192KW":
653
+ case "ECDH-ES+A256KW":
654
+ algorithm = { name: jwk.crv };
655
+ keyUsages = jwk.d ? ["deriveBits"] : [];
656
+ break;
657
+ default: throw new JOSENotSupported(unsupportedAlg);
658
+ }
659
+ break;
660
+ default: throw new JOSENotSupported("Invalid or unsupported JWK \"kty\" (Key Type) Parameter value");
661
+ }
410
662
  return {
411
- id: value.id,
412
- expiresAt: responseDate(value.expiresAt)
663
+ algorithm,
664
+ keyUsages
413
665
  };
414
666
  }
415
- function normalizeResentOrganizationInvitation(value, invitationId) {
416
- const invitation = normalizeCreatedOrganizationMemberInvitation(value);
417
- if (invitation.id !== invitationId) throw authorityUnavailable();
418
- return invitation;
667
+ async function jwkToKey(jwk) {
668
+ if (!jwk.alg) throw new TypeError("\"alg\" argument is required when \"jwk.alg\" is not present");
669
+ const { algorithm, keyUsages } = subtleMapping(jwk);
670
+ const keyData = { ...jwk };
671
+ if (keyData.kty !== "AKP") delete keyData.alg;
672
+ delete keyData.use;
673
+ return crypto.subtle.importKey("jwk", keyData, algorithm, jwk.ext ?? (jwk.d || jwk.priv ? false : true), jwk.key_ops ?? keyUsages);
419
674
  }
420
- function normalizeOrganizationInvitationAdministrationInput(idempotencyKey) {
421
- if (!boundedString(idempotencyKey, 255)) throw new AuthError("invalid_request", 400);
422
- return { idempotencyKey };
675
+ //#endregion
676
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/normalize_key.js
677
+ const unusableForAlg = "given KeyObject instance cannot be used for this algorithm";
678
+ let cache;
679
+ const handleJWK = async (key, jwk, alg, freeze = false) => {
680
+ cache ||= new WeakMap();
681
+ let cached = cache.get(key);
682
+ if (cached?.[alg]) return cached[alg];
683
+ const cryptoKey = await jwkToKey({
684
+ ...jwk,
685
+ alg
686
+ });
687
+ if (freeze) Object.freeze(key);
688
+ if (!cached) cache.set(key, { [alg]: cryptoKey });
689
+ else cached[alg] = cryptoKey;
690
+ return cryptoKey;
691
+ };
692
+ const handleKeyObject = (keyObject, alg) => {
693
+ cache ||= new WeakMap();
694
+ let cached = cache.get(keyObject);
695
+ if (cached?.[alg]) return cached[alg];
696
+ const isPublic = keyObject.type === "public";
697
+ const extractable = isPublic ? true : false;
698
+ let cryptoKey;
699
+ if (keyObject.asymmetricKeyType === "x25519") {
700
+ switch (alg) {
701
+ case "ECDH-ES":
702
+ case "ECDH-ES+A128KW":
703
+ case "ECDH-ES+A192KW":
704
+ case "ECDH-ES+A256KW": break;
705
+ default: throw new TypeError(unusableForAlg);
706
+ }
707
+ cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, isPublic ? [] : ["deriveBits"]);
708
+ }
709
+ if (keyObject.asymmetricKeyType === "ed25519") {
710
+ if (alg !== "EdDSA" && alg !== "Ed25519") throw new TypeError(unusableForAlg);
711
+ cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, [isPublic ? "verify" : "sign"]);
712
+ }
713
+ switch (keyObject.asymmetricKeyType) {
714
+ case "ml-dsa-44":
715
+ case "ml-dsa-65":
716
+ case "ml-dsa-87":
717
+ if (alg !== keyObject.asymmetricKeyType.toUpperCase()) throw new TypeError(unusableForAlg);
718
+ cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, [isPublic ? "verify" : "sign"]);
719
+ }
720
+ if (keyObject.asymmetricKeyType === "rsa") {
721
+ let hash;
722
+ switch (alg) {
723
+ case "RSA-OAEP":
724
+ hash = "SHA-1";
725
+ break;
726
+ case "RS256":
727
+ case "PS256":
728
+ case "RSA-OAEP-256":
729
+ hash = "SHA-256";
730
+ break;
731
+ case "RS384":
732
+ case "PS384":
733
+ case "RSA-OAEP-384":
734
+ hash = "SHA-384";
735
+ break;
736
+ case "RS512":
737
+ case "PS512":
738
+ case "RSA-OAEP-512":
739
+ hash = "SHA-512";
740
+ break;
741
+ default: throw new TypeError(unusableForAlg);
742
+ }
743
+ if (alg.startsWith("RSA-OAEP")) return keyObject.toCryptoKey({
744
+ name: "RSA-OAEP",
745
+ hash
746
+ }, extractable, isPublic ? ["encrypt"] : ["decrypt"]);
747
+ cryptoKey = keyObject.toCryptoKey({
748
+ name: alg.startsWith("PS") ? "RSA-PSS" : "RSASSA-PKCS1-v1_5",
749
+ hash
750
+ }, extractable, [isPublic ? "verify" : "sign"]);
751
+ }
752
+ if (keyObject.asymmetricKeyType === "ec") {
753
+ const namedCurve = new Map([
754
+ ["prime256v1", "P-256"],
755
+ ["secp384r1", "P-384"],
756
+ ["secp521r1", "P-521"]
757
+ ]).get(keyObject.asymmetricKeyDetails?.namedCurve);
758
+ if (!namedCurve) throw new TypeError(unusableForAlg);
759
+ const expectedCurve = {
760
+ ES256: "P-256",
761
+ ES384: "P-384",
762
+ ES512: "P-521"
763
+ };
764
+ if (expectedCurve[alg] && namedCurve === expectedCurve[alg]) cryptoKey = keyObject.toCryptoKey({
765
+ name: "ECDSA",
766
+ namedCurve
767
+ }, extractable, [isPublic ? "verify" : "sign"]);
768
+ if (alg.startsWith("ECDH-ES")) cryptoKey = keyObject.toCryptoKey({
769
+ name: "ECDH",
770
+ namedCurve
771
+ }, extractable, isPublic ? [] : ["deriveBits"]);
772
+ }
773
+ if (!cryptoKey) throw new TypeError(unusableForAlg);
774
+ if (!cached) cache.set(keyObject, { [alg]: cryptoKey });
775
+ else cached[alg] = cryptoKey;
776
+ return cryptoKey;
777
+ };
778
+ async function normalizeKey(key, alg) {
779
+ if (key instanceof Uint8Array) return key;
780
+ if (isCryptoKey(key)) return key;
781
+ if (isKeyObject(key)) {
782
+ if (key.type === "secret") return key.export();
783
+ if ("toCryptoKey" in key && typeof key.toCryptoKey === "function") try {
784
+ return handleKeyObject(key, alg);
785
+ } catch (err) {
786
+ if (err instanceof TypeError) throw err;
787
+ }
788
+ let jwk = key.export({ format: "jwk" });
789
+ return handleJWK(key, jwk, alg);
790
+ }
791
+ if (isJWK(key)) {
792
+ if (key.k) return decode(key.k);
793
+ return handleJWK(key, key, alg, true);
794
+ }
795
+ throw new Error("unreachable");
423
796
  }
424
- function normalizeCanceledOrganizationInvitation(value) {
425
- exact$2(value, ["status"]);
426
- if (value.status !== "canceled") throw authorityUnavailable();
427
- return { status: "canceled" };
797
+ //#endregion
798
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/key/import.js
799
+ async function importJWK(jwk, alg, options) {
800
+ if (!isObject$1(jwk)) throw new TypeError("JWK must be an object");
801
+ let ext;
802
+ alg ??= jwk.alg;
803
+ ext ??= options?.extractable ?? jwk.ext;
804
+ switch (jwk.kty) {
805
+ case "oct":
806
+ if (typeof jwk.k !== "string" || !jwk.k) throw new TypeError("missing \"k\" (Key Value) Parameter value");
807
+ return decode(jwk.k);
808
+ case "RSA":
809
+ if ("oth" in jwk && jwk.oth !== void 0) throw new JOSENotSupported("RSA JWK \"oth\" (Other Primes Info) Parameter value is not supported");
810
+ return jwkToKey({
811
+ ...jwk,
812
+ alg,
813
+ ext
814
+ });
815
+ case "AKP":
816
+ if (typeof jwk.alg !== "string" || !jwk.alg) throw new TypeError("missing \"alg\" (Algorithm) Parameter value");
817
+ if (alg !== void 0 && alg !== jwk.alg) throw new TypeError("JWK alg and alg option value mismatch");
818
+ return jwkToKey({
819
+ ...jwk,
820
+ ext
821
+ });
822
+ case "EC":
823
+ case "OKP": return jwkToKey({
824
+ ...jwk,
825
+ alg,
826
+ ext
827
+ });
828
+ default: throw new JOSENotSupported("Unsupported \"kty\" (Key Type) Parameter value");
829
+ }
428
830
  }
429
- function normalizeOrganizations(value) {
430
- exact$2(value, ["nextCursor", "organizations"]);
431
- if (!Array.isArray(value.organizations) || value.organizations.length > 100) throw authorityUnavailable();
432
- return {
433
- organizations: unique(value.organizations.map(normalizeOrganization), (item) => item.id),
434
- nextCursor: nullableCursor(value.nextCursor)
831
+ //#endregion
832
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/key_to_jwk.js
833
+ function omitUndefinedProperties(jwk) {
834
+ return Object.fromEntries(Object.entries(jwk).filter(([, value]) => value !== void 0));
835
+ }
836
+ async function keyToJWK(key) {
837
+ if (isKeyObject(key)) if (key.type === "secret") key = key.export();
838
+ else return key.export({ format: "jwk" });
839
+ if (key instanceof Uint8Array) return {
840
+ kty: "oct",
841
+ k: encode(key)
435
842
  };
843
+ if (!isCryptoKey(key)) throw new TypeError(invalidKeyInput(key, "CryptoKey", "KeyObject", "Uint8Array"));
844
+ if (!key.extractable) throw new TypeError("non-extractable CryptoKey cannot be exported as a JWK");
845
+ const { ext, key_ops, alg, use, ...jwk } = omitUndefinedProperties(await crypto.subtle.exportKey("jwk", key));
846
+ if (jwk.kty === "AKP") jwk.alg = alg;
847
+ return jwk;
436
848
  }
437
- function normalizeOrganizationMembers(value) {
438
- exact$2(value, ["members", "nextCursor"]);
439
- if (!Array.isArray(value.members) || value.members.length > 100) throw authorityUnavailable();
440
- return {
441
- members: unique(value.members.map((member) => {
442
- exact$2(member, [
443
- "email",
444
- "id",
445
- "image",
446
- "joinedAt",
447
- "name",
448
- "owner",
449
- "role",
450
- "teamIds",
451
- "userId"
452
- ]);
453
- if (!isId(member.id) || !isId(member.userId) || !boundedString(member.name, 255) || typeof member.email !== "string" || member.email.length > 320 || !email.test(member.email) || !role(member.role) || typeof member.owner !== "boolean" || !Array.isArray(member.teamIds) || member.teamIds.length > 100) throw authorityUnavailable();
454
- const teamIds = unique(member.teamIds.map((teamId) => normalizeResponseId(teamId)), (item) => item);
455
- return {
456
- id: member.id,
457
- userId: member.userId,
458
- name: member.name,
459
- email: member.email,
460
- image: nullableHttpsUrl(member.image),
461
- role: member.role,
462
- owner: member.owner,
463
- joinedAt: responseDate(member.joinedAt),
464
- teamIds
465
- };
466
- }), (item) => item.id),
467
- nextCursor: nullableCursor(value.nextCursor)
468
- };
849
+ //#endregion
850
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/key/export.js
851
+ async function exportJWK(key) {
852
+ return keyToJWK(key);
469
853
  }
470
- function normalizeOrganizationTeams(value) {
471
- exact$2(value, ["nextCursor", "teams"]);
472
- if (!Array.isArray(value.teams) || value.teams.length > 100) throw authorityUnavailable();
473
- return {
474
- teams: unique(value.teams.map((team) => {
475
- exact$2(team, [
476
- "category",
477
- "createdAt",
478
- "id",
479
- "name"
480
- ]);
481
- if (!isId(team.id) || !boundedString(team.name, 255) || team.category !== "manual" && team.category !== "managed") throw authorityUnavailable();
482
- return {
483
- id: team.id,
484
- name: team.name,
485
- category: team.category,
486
- createdAt: responseDate(team.createdAt)
487
- };
488
- }), (item) => item.id),
489
- nextCursor: nullableCursor(value.nextCursor)
490
- };
854
+ //#endregion
855
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/validate_crit.js
856
+ function validateCrit(Err, recognizedDefault, recognizedOption, protectedHeader, joseHeader) {
857
+ if (joseHeader.crit !== void 0 && protectedHeader?.crit === void 0) throw new Err("\"crit\" (Critical) Header Parameter MUST be integrity protected");
858
+ if (!protectedHeader || protectedHeader.crit === void 0) return new Set();
859
+ if (!Array.isArray(protectedHeader.crit) || protectedHeader.crit.length === 0 || protectedHeader.crit.some((input) => typeof input !== "string" || input.length === 0)) throw new Err("\"crit\" (Critical) Header Parameter MUST be an array of non-empty strings when present");
860
+ let recognized;
861
+ if (recognizedOption !== void 0) recognized = new Map([...Object.entries(recognizedOption), ...recognizedDefault.entries()]);
862
+ else recognized = recognizedDefault;
863
+ for (const parameter of protectedHeader.crit) {
864
+ if (!recognized.has(parameter)) throw new JOSENotSupported(`Extension Header Parameter "${parameter}" is not recognized`);
865
+ if (joseHeader[parameter] === void 0) throw new Err(`Extension Header Parameter "${parameter}" is missing`);
866
+ if (recognized.get(parameter) && protectedHeader[parameter] === void 0) throw new Err(`Extension Header Parameter "${parameter}" MUST be integrity protected`);
867
+ }
868
+ return new Set(protectedHeader.crit);
491
869
  }
492
- function normalizeOrganizationTeamMembers(value) {
493
- exact$2(value, ["memberIds", "nextCursor"]);
494
- if (!Array.isArray(value.memberIds) || value.memberIds.length > 100) throw authorityUnavailable();
495
- return {
496
- memberIds: unique(value.memberIds.map((item) => normalizeResponseId(item)), (item) => item),
497
- nextCursor: nullableCursor(value.nextCursor)
498
- };
870
+ //#endregion
871
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/validate_algorithms.js
872
+ function validateAlgorithms(option, algorithms) {
873
+ if (algorithms !== void 0 && (!Array.isArray(algorithms) || algorithms.some((s) => typeof s !== "string"))) throw new TypeError(`"${option}" option must be an array of strings`);
874
+ if (!algorithms) return;
875
+ return new Set(algorithms);
499
876
  }
500
- function normalizeOrganizationInvitation(value) {
501
- exact$2(value, [
502
- "createdAt",
503
- "email",
504
- "expiresAt",
505
- "id",
506
- "inviter",
507
- "role",
508
- "status",
509
- "teamIds"
510
- ]);
511
- if (!isId(value.id) || typeof value.email !== "string" || value.email.length > 320 || !email.test(value.email) || !role(value.role) || value.status !== "pending" || !Array.isArray(value.teamIds) || value.teamIds.length > 100 || !isObject(value.inviter)) throw authorityUnavailable();
512
- exact$2(value.inviter, ["membershipId", "name"]);
513
- if (!isId(value.inviter.membershipId) || !boundedString(value.inviter.name, 255)) throw authorityUnavailable();
514
- return {
515
- id: value.id,
516
- email: value.email,
517
- role: value.role,
518
- teamIds: unique(value.teamIds.map(normalizeResponseId), (item) => item),
519
- inviter: {
520
- membershipId: value.inviter.membershipId,
521
- name: value.inviter.name
522
- },
523
- createdAt: responseDate(value.createdAt),
524
- expiresAt: responseDate(value.expiresAt),
525
- status: "pending"
526
- };
877
+ //#endregion
878
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/check_key_type.js
879
+ const tag = (key) => key?.[Symbol.toStringTag];
880
+ const jwkMatchesOp = (alg, key, usage) => {
881
+ if (key.use !== void 0) {
882
+ let expected;
883
+ switch (usage) {
884
+ case "sign":
885
+ case "verify":
886
+ expected = "sig";
887
+ break;
888
+ case "encrypt":
889
+ case "decrypt":
890
+ expected = "enc";
891
+ break;
892
+ }
893
+ if (key.use !== expected) throw new TypeError(`Invalid key for this operation, its "use" must be "${expected}" when present`);
894
+ }
895
+ if (key.alg !== void 0 && key.alg !== alg) throw new TypeError(`Invalid key for this operation, its "alg" must be "${alg}" when present`);
896
+ if (Array.isArray(key.key_ops)) {
897
+ let expectedKeyOp;
898
+ switch (true) {
899
+ case usage === "sign" || usage === "verify":
900
+ case alg === "dir":
901
+ case alg.includes("CBC-HS"):
902
+ expectedKeyOp = usage;
903
+ break;
904
+ case alg.startsWith("PBES2"):
905
+ expectedKeyOp = "deriveBits";
906
+ break;
907
+ case /^A\d{3}(?:GCM)?(?:KW)?$/.test(alg):
908
+ if (!alg.includes("GCM") && alg.endsWith("KW")) expectedKeyOp = usage === "encrypt" ? "wrapKey" : "unwrapKey";
909
+ else expectedKeyOp = usage;
910
+ break;
911
+ case usage === "encrypt" && alg.startsWith("RSA"):
912
+ expectedKeyOp = "wrapKey";
913
+ break;
914
+ case usage === "decrypt":
915
+ expectedKeyOp = alg.startsWith("RSA") ? "unwrapKey" : "deriveBits";
916
+ break;
917
+ }
918
+ if (expectedKeyOp && key.key_ops?.includes?.(expectedKeyOp) === false) throw new TypeError(`Invalid key for this operation, its "key_ops" must include "${expectedKeyOp}" when present`);
919
+ }
920
+ return true;
921
+ };
922
+ const symmetricTypeCheck = (alg, key, usage) => {
923
+ if (key instanceof Uint8Array) return;
924
+ if (isJWK(key)) {
925
+ if (isSecretJWK(key) && jwkMatchesOp(alg, key, usage)) return;
926
+ throw new TypeError(`JSON Web Key for symmetric algorithms must have JWK "kty" (Key Type) equal to "oct" and the JWK "k" (Key Value) present`);
927
+ }
928
+ if (!isKeyLike(key)) throw new TypeError(withAlg(alg, key, "CryptoKey", "KeyObject", "JSON Web Key", "Uint8Array"));
929
+ if (key.type !== "secret") throw new TypeError(`${tag(key)} instances for symmetric algorithms must be of type "secret"`);
930
+ };
931
+ const asymmetricTypeCheck = (alg, key, usage) => {
932
+ if (isJWK(key)) switch (usage) {
933
+ case "decrypt":
934
+ case "sign":
935
+ if (isPrivateJWK(key) && jwkMatchesOp(alg, key, usage)) return;
936
+ throw new TypeError(`JSON Web Key for this operation must be a private JWK`);
937
+ case "encrypt":
938
+ case "verify":
939
+ if (isPublicJWK(key) && jwkMatchesOp(alg, key, usage)) return;
940
+ throw new TypeError(`JSON Web Key for this operation must be a public JWK`);
941
+ }
942
+ if (!isKeyLike(key)) throw new TypeError(withAlg(alg, key, "CryptoKey", "KeyObject", "JSON Web Key"));
943
+ if (key.type === "secret") throw new TypeError(`${tag(key)} instances for asymmetric algorithms must not be of type "secret"`);
944
+ if (key.type === "public") switch (usage) {
945
+ case "sign": throw new TypeError(`${tag(key)} instances for asymmetric algorithm signing must be of type "private"`);
946
+ case "decrypt": throw new TypeError(`${tag(key)} instances for asymmetric algorithm decryption must be of type "private"`);
947
+ }
948
+ if (key.type === "private") switch (usage) {
949
+ case "verify": throw new TypeError(`${tag(key)} instances for asymmetric algorithm verifying must be of type "public"`);
950
+ case "encrypt": throw new TypeError(`${tag(key)} instances for asymmetric algorithm encryption must be of type "public"`);
951
+ }
952
+ };
953
+ function checkKeyType(alg, key, usage) {
954
+ switch (alg.substring(0, 2)) {
955
+ case "A1":
956
+ case "A2":
957
+ case "di":
958
+ case "HS":
959
+ case "PB":
960
+ symmetricTypeCheck(alg, key, usage);
961
+ break;
962
+ default: asymmetricTypeCheck(alg, key, usage);
963
+ }
527
964
  }
528
- function normalizeOrganizationInvitations(value) {
529
- exact$2(value, ["invitations", "nextCursor"]);
530
- if (!Array.isArray(value.invitations) || value.invitations.length > 100) throw authorityUnavailable();
531
- return {
532
- invitations: unique(value.invitations.map(normalizeOrganizationInvitation), (item) => item.id),
533
- nextCursor: nullableCursor(value.nextCursor)
965
+ //#endregion
966
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/jws/flattened/verify.js
967
+ async function flattenedVerify(jws, key, options) {
968
+ if (!isObject$1(jws)) throw new JWSInvalid("Flattened JWS must be an object");
969
+ if (jws.protected === void 0 && jws.header === void 0) throw new JWSInvalid("Flattened JWS must have either of the \"protected\" or \"header\" members");
970
+ if (jws.protected !== void 0 && typeof jws.protected !== "string") throw new JWSInvalid("JWS Protected Header incorrect type");
971
+ if (jws.payload === void 0) throw new JWSInvalid("JWS Payload missing");
972
+ if (typeof jws.signature !== "string") throw new JWSInvalid("JWS Signature missing or incorrect type");
973
+ if (jws.header !== void 0 && !isObject$1(jws.header)) throw new JWSInvalid("JWS Unprotected Header incorrect type");
974
+ let parsedProt = {};
975
+ if (jws.protected) try {
976
+ const protectedHeader = decode(jws.protected);
977
+ parsedProt = JSON.parse(decoder.decode(protectedHeader));
978
+ } catch {
979
+ throw new JWSInvalid("JWS Protected Header is invalid");
980
+ }
981
+ if (!isDisjoint(parsedProt, jws.header)) throw new JWSInvalid("JWS Protected and JWS Unprotected Header Parameter names must be disjoint");
982
+ const joseHeader = {
983
+ ...parsedProt,
984
+ ...jws.header
534
985
  };
535
- }
536
- function normalizeReceivedInvitation(value) {
537
- exact$2(value, [
538
- "expiresAt",
539
- "id",
540
- "inviterName",
541
- "organization",
542
- "role",
543
- "teams"
544
- ]);
545
- if (!isId(value.id) || !boundedString(value.inviterName, 255) || !role(value.role) || !Array.isArray(value.teams) || value.teams.length > 100 || !isObject(value.organization)) throw authorityUnavailable();
546
- exact$2(value.organization, [
547
- "id",
548
- "logo",
549
- "name",
550
- "slug"
551
- ]);
552
- if (!isId(value.organization.id) || !boundedString(value.organization.name, 255) || !boundedString(value.organization.slug, 255)) throw authorityUnavailable();
553
- return {
554
- id: value.id,
555
- organization: {
556
- id: value.organization.id,
557
- name: value.organization.name,
558
- slug: value.organization.slug,
559
- logo: nullableHttpsUrl(value.organization.logo)
560
- },
561
- role: value.role,
562
- teams: unique(value.teams.map((team) => {
563
- exact$2(team, ["id", "name"]);
564
- if (!isId(team.id) || !boundedString(team.name, 255)) throw authorityUnavailable();
565
- return {
566
- id: team.id,
567
- name: team.name
568
- };
569
- }), (item) => item.id),
570
- inviterName: value.inviterName,
571
- expiresAt: responseDate(value.expiresAt)
986
+ const extensions = validateCrit(JWSInvalid, new Map([["b64", true]]), options?.crit, parsedProt, joseHeader);
987
+ let b64 = true;
988
+ if (extensions.has("b64")) {
989
+ b64 = parsedProt.b64;
990
+ if (typeof b64 !== "boolean") throw new JWSInvalid("The \"b64\" (base64url-encode payload) Header Parameter must be a boolean");
991
+ }
992
+ const { alg } = joseHeader;
993
+ if (typeof alg !== "string" || !alg) throw new JWSInvalid("JWS \"alg\" (Algorithm) Header Parameter missing or invalid");
994
+ const algorithms = options && validateAlgorithms("algorithms", options.algorithms);
995
+ if (algorithms && !algorithms.has(alg)) throw new JOSEAlgNotAllowed("\"alg\" (Algorithm) Header Parameter value not allowed");
996
+ if (b64) {
997
+ if (typeof jws.payload !== "string") throw new JWSInvalid("JWS Payload must be a string");
998
+ } else if (typeof jws.payload !== "string" && !(jws.payload instanceof Uint8Array)) throw new JWSInvalid("JWS Payload must be a string or an Uint8Array instance");
999
+ let resolvedKey = false;
1000
+ if (typeof key === "function") {
1001
+ key = await key(parsedProt, jws);
1002
+ resolvedKey = true;
1003
+ }
1004
+ checkKeyType(alg, key, "verify");
1005
+ const data = concat(jws.protected !== void 0 ? encode$1(jws.protected) : new Uint8Array(), encode$1("."), typeof jws.payload === "string" ? b64 ? encode$1(jws.payload) : encoder$1.encode(jws.payload) : jws.payload);
1006
+ const signature = decodeBase64url(jws.signature, "signature", JWSInvalid);
1007
+ const k = await normalizeKey(key, alg);
1008
+ if (!await verify(alg, k, signature, data)) throw new JWSSignatureVerificationFailed();
1009
+ let payload;
1010
+ if (b64) payload = decodeBase64url(jws.payload, "payload", JWSInvalid);
1011
+ else if (typeof jws.payload === "string") payload = encoder$1.encode(jws.payload);
1012
+ else payload = jws.payload;
1013
+ const result = { payload };
1014
+ if (jws.protected !== void 0) result.protectedHeader = parsedProt;
1015
+ if (jws.header !== void 0) result.unprotectedHeader = jws.header;
1016
+ if (resolvedKey) return {
1017
+ ...result,
1018
+ key: k
572
1019
  };
1020
+ return result;
573
1021
  }
574
- function normalizeReceivedInvitations(value) {
575
- exact$2(value, ["invitations", "nextCursor"]);
576
- if (!Array.isArray(value.invitations) || value.invitations.length > 100) throw authorityUnavailable();
577
- return {
578
- invitations: unique(value.invitations.map(normalizeReceivedInvitation), (item) => item.id),
579
- nextCursor: nullableCursor(value.nextCursor)
1022
+ //#endregion
1023
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/jws/compact/verify.js
1024
+ async function compactVerify(jws, key, options) {
1025
+ if (jws instanceof Uint8Array) jws = decoder.decode(jws);
1026
+ if (typeof jws !== "string") throw new JWSInvalid("Compact JWS must be a string or Uint8Array");
1027
+ const { 0: protectedHeader, 1: payload, 2: signature, length } = jws.split(".");
1028
+ if (length !== 3) throw new JWSInvalid("Invalid Compact JWS");
1029
+ const verified = await flattenedVerify({
1030
+ payload,
1031
+ protected: protectedHeader,
1032
+ signature
1033
+ }, key, options);
1034
+ const result = {
1035
+ payload: verified.payload,
1036
+ protectedHeader: verified.protectedHeader
580
1037
  };
581
- }
582
- function normalizeInvitationInput(value) {
583
- if (!isObject(value) || Object.keys(value).length !== 1 || !isId(value.invitationId)) throw new AuthError("invalid_invitation", 422);
584
- return { invitationId: value.invitationId };
585
- }
586
- function normalizeInvitationAcceptance(value, invitationId) {
587
- if (!isObject(value) || !isObject(value.invitation) || !isObject(value.member) || value.invitation.id !== invitationId || value.invitation.status !== "accepted" || !isId(value.invitation.organizationId) || value.member.organizationId !== value.invitation.organizationId) throw authorityUnavailable();
588
- return { organizationId: value.invitation.organizationId };
589
- }
590
- function normalizeWorkspaceSelection(value) {
591
- if (!isObject(value)) throw new AuthError("invalid_workspace_selection", 422);
592
- const keys = Object.keys(value);
593
- if (value.type === "personal" && keys.length === 1 && keys[0] === "type") return { type: "personal" };
594
- if (value.type === "organization" && keys.length === 2 && keys.includes("type") && keys.includes("organizationId") && typeof value.organizationId === "string" && id.test(value.organizationId)) return {
595
- type: "organization",
596
- organizationId: value.organizationId
1038
+ if (typeof key === "function") return {
1039
+ ...result,
1040
+ key: verified.key
597
1041
  };
598
- throw new AuthError("invalid_workspace_selection", 422);
1042
+ return result;
599
1043
  }
600
- function fromAuthorityError(value, fallbackStatus, retryAfter) {
601
- const mapped = mapError(isObject(value) && typeof value.code === "string" ? value.code : void 0, fallbackStatus);
602
- return new AuthError(mapped.code, mapped.status, parseRetryAfter(retryAfter));
1044
+ //#endregion
1045
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/jwt_claims_set.js
1046
+ const epoch = (date) => Math.floor(date.getTime() / 1e3);
1047
+ const minute = 60;
1048
+ const hour = minute * 60;
1049
+ const day = hour * 24;
1050
+ const week = day * 7;
1051
+ const year = day * 365.25;
1052
+ const REGEX = /^(\+|\-)? ?(\d+|\d+\.\d+) ?(seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)(?: (ago|from now))?$/i;
1053
+ function secs(str) {
1054
+ const matched = REGEX.exec(str);
1055
+ if (!matched || matched[4] && matched[1]) throw new TypeError("Invalid time period format");
1056
+ const value = parseFloat(matched[2]);
1057
+ const unit = matched[3].toLowerCase();
1058
+ let numericDate;
1059
+ switch (unit) {
1060
+ case "sec":
1061
+ case "secs":
1062
+ case "second":
1063
+ case "seconds":
1064
+ case "s":
1065
+ numericDate = Math.round(value);
1066
+ break;
1067
+ case "minute":
1068
+ case "minutes":
1069
+ case "min":
1070
+ case "mins":
1071
+ case "m":
1072
+ numericDate = Math.round(value * minute);
1073
+ break;
1074
+ case "hour":
1075
+ case "hours":
1076
+ case "hr":
1077
+ case "hrs":
1078
+ case "h":
1079
+ numericDate = Math.round(value * hour);
1080
+ break;
1081
+ case "day":
1082
+ case "days":
1083
+ case "d":
1084
+ numericDate = Math.round(value * day);
1085
+ break;
1086
+ case "week":
1087
+ case "weeks":
1088
+ case "w":
1089
+ numericDate = Math.round(value * week);
1090
+ break;
1091
+ default:
1092
+ numericDate = Math.round(value * year);
1093
+ break;
1094
+ }
1095
+ if (matched[1] === "-" || matched[4] === "ago") return -numericDate;
1096
+ return numericDate;
603
1097
  }
604
- function fromAccountAuthorityError(value, status, retryAfter) {
605
- const code = isObject(value) && typeof value.code === "string" ? value.code : void 0;
606
- if (status === 403 && (code === "INVALID_ORIGIN" || code === "MISSING_OR_NULL_ORIGIN")) return new AuthError("request_origin_denied", 403);
607
- if (code === "USER_ALREADY_EXISTS_USE_ANOTHER_EMAIL") return new AuthError("account_conflict", 409);
608
- if (code === "INVALID_TOKEN") return new AuthError("password_reset_invalid", 422);
609
- if (code === "INVALID_PASSWORD" || code === "INVALID_EMAIL_OR_PASSWORD") return new AuthError("invalid_credentials", 401);
610
- if (code === "INVALID_EMAIL" || code === "PASSWORD_TOO_SHORT" || code === "PASSWORD_TOO_LONG" || code === "BODY_MUST_BE_AN_OBJECT" || code === "EMAIL_CAN_NOT_BE_UPDATED") return new AuthError("invalid_auth_input", 422);
611
- if (status === 401) return new AuthError("authentication_required", 401);
612
- if (status === 403) return new AuthError("access_denied", 403);
613
- if (status === 409) return new AuthError("state_conflict", 409);
614
- if (status === 429) return new AuthError("auth_request_rate_limited", 429, parseRetryAfter(retryAfter));
615
- if (status === 400 || status === 422) return new AuthError("invalid_auth_input", 422);
616
- return authorityUnavailable();
1098
+ const normalizeTyp = (value) => {
1099
+ if (value.includes("/")) return value.toLowerCase();
1100
+ return `application/${value.toLowerCase()}`;
1101
+ };
1102
+ const checkAudiencePresence = (audPayload, audOption) => {
1103
+ if (typeof audPayload === "string") return audOption.includes(audPayload);
1104
+ if (Array.isArray(audPayload)) return audOption.some(Set.prototype.has.bind(new Set(audPayload)));
1105
+ return false;
1106
+ };
1107
+ function validateClaimsSet(protectedHeader, encodedPayload, options = {}) {
1108
+ let payload;
1109
+ try {
1110
+ payload = JSON.parse(decoder.decode(encodedPayload));
1111
+ } catch {}
1112
+ if (!isObject$1(payload)) throw new JWTInvalid("JWT Claims Set must be a top-level JSON object");
1113
+ const { typ } = options;
1114
+ if (typ && (typeof protectedHeader.typ !== "string" || normalizeTyp(protectedHeader.typ) !== normalizeTyp(typ))) throw new JWTClaimValidationFailed("unexpected \"typ\" JWT header value", payload, "typ", "check_failed");
1115
+ const { requiredClaims = [], issuer, subject, audience, maxTokenAge } = options;
1116
+ const presenceCheck = [...requiredClaims];
1117
+ if (maxTokenAge !== void 0) presenceCheck.push("iat");
1118
+ if (audience !== void 0) presenceCheck.push("aud");
1119
+ if (subject !== void 0) presenceCheck.push("sub");
1120
+ if (issuer !== void 0) presenceCheck.push("iss");
1121
+ for (const claim of new Set(presenceCheck.reverse())) if (!(claim in payload)) throw new JWTClaimValidationFailed(`missing required "${claim}" claim`, payload, claim, "missing");
1122
+ if (issuer && !(Array.isArray(issuer) ? issuer : [issuer]).includes(payload.iss)) throw new JWTClaimValidationFailed("unexpected \"iss\" claim value", payload, "iss", "check_failed");
1123
+ if (subject && payload.sub !== subject) throw new JWTClaimValidationFailed("unexpected \"sub\" claim value", payload, "sub", "check_failed");
1124
+ if (audience && !checkAudiencePresence(payload.aud, typeof audience === "string" ? [audience] : audience)) throw new JWTClaimValidationFailed("unexpected \"aud\" claim value", payload, "aud", "check_failed");
1125
+ let tolerance;
1126
+ switch (typeof options.clockTolerance) {
1127
+ case "string":
1128
+ tolerance = secs(options.clockTolerance);
1129
+ break;
1130
+ case "number":
1131
+ tolerance = options.clockTolerance;
1132
+ break;
1133
+ case "undefined":
1134
+ tolerance = 0;
1135
+ break;
1136
+ default: throw new TypeError("Invalid clockTolerance option type");
1137
+ }
1138
+ const { currentDate } = options;
1139
+ const now = epoch(currentDate || new Date());
1140
+ if ((payload.iat !== void 0 || maxTokenAge) && typeof payload.iat !== "number") throw new JWTClaimValidationFailed("\"iat\" claim must be a number", payload, "iat", "invalid");
1141
+ if (payload.nbf !== void 0) {
1142
+ if (typeof payload.nbf !== "number") throw new JWTClaimValidationFailed("\"nbf\" claim must be a number", payload, "nbf", "invalid");
1143
+ if (payload.nbf > now + tolerance) throw new JWTClaimValidationFailed("\"nbf\" claim timestamp check failed", payload, "nbf", "check_failed");
1144
+ }
1145
+ if (payload.exp !== void 0) {
1146
+ if (typeof payload.exp !== "number") throw new JWTClaimValidationFailed("\"exp\" claim must be a number", payload, "exp", "invalid");
1147
+ if (payload.exp <= now - tolerance) throw new JWTExpired("\"exp\" claim timestamp check failed", payload, "exp", "check_failed");
1148
+ }
1149
+ if (maxTokenAge) {
1150
+ const age = now - payload.iat;
1151
+ const max = typeof maxTokenAge === "number" ? maxTokenAge : secs(maxTokenAge);
1152
+ if (age - tolerance > max) throw new JWTExpired("\"iat\" claim timestamp check failed (too far in the past)", payload, "iat", "check_failed");
1153
+ if (age < 0 - tolerance) throw new JWTClaimValidationFailed("\"iat\" claim timestamp check failed (it should be in the past)", payload, "iat", "check_failed");
1154
+ }
1155
+ return payload;
617
1156
  }
618
- function fromSocialIdTokenAuthorityError(value, status, retryAfter) {
619
- const code = isObject(value) && typeof value.code === "string" ? value.code : void 0;
620
- if (code === "INVALID_TOKEN" || code === "FAILED_TO_GET_USER_INFO" || code === "USER_EMAIL_NOT_FOUND") return new AuthError("invalid_credentials", 401);
621
- if (code === "OAUTH_LINK_ERROR") return new AuthError("account_conflict", 409);
622
- return fromAccountAuthorityError(value, status, retryAfter);
1157
+ //#endregion
1158
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/jwt/verify.js
1159
+ async function jwtVerify(jwt, key, options) {
1160
+ const verified = await compactVerify(jwt, key, options);
1161
+ if (verified.protectedHeader.crit?.includes("b64") && verified.protectedHeader.b64 === false) throw new JWTInvalid("JWTs MUST NOT use unencoded payload");
1162
+ const result = {
1163
+ payload: validateClaimsSet(verified.protectedHeader, verified.payload, options),
1164
+ protectedHeader: verified.protectedHeader
1165
+ };
1166
+ if (typeof key === "function") return {
1167
+ ...result,
1168
+ key: verified.key
1169
+ };
1170
+ return result;
623
1171
  }
624
- function authorityUnavailable() {
625
- return new AuthError("identity_authority_unavailable", 503);
1172
+ //#endregion
1173
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/jwk/thumbprint.js
1174
+ const check = (value, description) => {
1175
+ if (typeof value !== "string" || !value) throw new JWKInvalid(`${description} missing or invalid`);
1176
+ };
1177
+ async function calculateJwkThumbprint(key, digestAlgorithm) {
1178
+ let jwk;
1179
+ if (isJWK(key)) jwk = key;
1180
+ else if (isKeyLike(key)) jwk = await exportJWK(key);
1181
+ else throw new TypeError(invalidKeyInput(key, "CryptoKey", "KeyObject", "JSON Web Key"));
1182
+ digestAlgorithm ??= "sha256";
1183
+ if (digestAlgorithm !== "sha256" && digestAlgorithm !== "sha384" && digestAlgorithm !== "sha512") throw new TypeError("digestAlgorithm must one of \"sha256\", \"sha384\", or \"sha512\"");
1184
+ let components;
1185
+ switch (jwk.kty) {
1186
+ case "AKP":
1187
+ check(jwk.alg, "\"alg\" (Algorithm) Parameter");
1188
+ check(jwk.pub, "\"pub\" (Public key) Parameter");
1189
+ components = {
1190
+ alg: jwk.alg,
1191
+ kty: jwk.kty,
1192
+ pub: jwk.pub
1193
+ };
1194
+ break;
1195
+ case "EC":
1196
+ check(jwk.crv, "\"crv\" (Curve) Parameter");
1197
+ check(jwk.x, "\"x\" (X Coordinate) Parameter");
1198
+ check(jwk.y, "\"y\" (Y Coordinate) Parameter");
1199
+ components = {
1200
+ crv: jwk.crv,
1201
+ kty: jwk.kty,
1202
+ x: jwk.x,
1203
+ y: jwk.y
1204
+ };
1205
+ break;
1206
+ case "OKP":
1207
+ check(jwk.crv, "\"crv\" (Subtype of Key Pair) Parameter");
1208
+ check(jwk.x, "\"x\" (Public Key) Parameter");
1209
+ components = {
1210
+ crv: jwk.crv,
1211
+ kty: jwk.kty,
1212
+ x: jwk.x
1213
+ };
1214
+ break;
1215
+ case "RSA":
1216
+ check(jwk.e, "\"e\" (Exponent) Parameter");
1217
+ check(jwk.n, "\"n\" (Modulus) Parameter");
1218
+ components = {
1219
+ e: jwk.e,
1220
+ kty: jwk.kty,
1221
+ n: jwk.n
1222
+ };
1223
+ break;
1224
+ case "oct":
1225
+ check(jwk.k, "\"k\" (Key Value) Parameter");
1226
+ components = {
1227
+ k: jwk.k,
1228
+ kty: jwk.kty
1229
+ };
1230
+ break;
1231
+ default: throw new JOSENotSupported("\"kty\" (Key Type) Parameter missing or unsupported");
1232
+ }
1233
+ const data = encode$1(JSON.stringify(components));
1234
+ return encode(await digest(digestAlgorithm, data));
626
1235
  }
627
- function fromOrganizationListError(error) {
628
- if (error instanceof AuthError && error.status === 401) return new AuthError("authentication_required", 401);
629
- if (error instanceof AuthError) return error;
630
- return authorityUnavailable();
1236
+ //#endregion
1237
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/util/decode_protected_header.js
1238
+ function decodeProtectedHeader(token) {
1239
+ let protectedB64u;
1240
+ if (typeof token === "string") {
1241
+ const parts = token.split(".");
1242
+ if (parts.length === 3 || parts.length === 5) [protectedB64u] = parts;
1243
+ } else if (typeof token === "object" && token) if ("protected" in token) protectedB64u = token.protected;
1244
+ else throw new TypeError("Token does not contain a Protected Header");
1245
+ try {
1246
+ if (typeof protectedB64u !== "string" || !protectedB64u) throw new Error();
1247
+ const result = JSON.parse(decoder.decode(decode(protectedB64u)));
1248
+ if (!isObject$1(result)) throw new Error();
1249
+ return result;
1250
+ } catch {
1251
+ throw new TypeError("Invalid Token or Protected Header formatting");
1252
+ }
631
1253
  }
632
- function fromOrganizationReadAuthorityError(value, status) {
633
- if (status === 400) return new AuthError("invalid_request", 400);
634
- if (status === 401) return new AuthError("authentication_required", 401);
635
- if (status === 403) return new AuthError("access_denied", 403);
636
- return authorityUnavailable();
1254
+ //#endregion
1255
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/util/decode_jwt.js
1256
+ function decodeJwt(jwt) {
1257
+ if (typeof jwt !== "string") throw new JWTInvalid("JWTs must use Compact JWS serialization, JWT must be a string");
1258
+ const { 1: payload, length } = jwt.split(".");
1259
+ if (length === 5) throw new JWTInvalid("Only JWTs using Compact JWS serialization can be decoded");
1260
+ if (length !== 3) throw new JWTInvalid("Invalid JWT");
1261
+ if (!payload) throw new JWTInvalid("JWTs must contain a payload");
1262
+ let decoded;
1263
+ try {
1264
+ decoded = decode(payload);
1265
+ } catch {
1266
+ throw new JWTInvalid("Failed to base64url decode the payload");
1267
+ }
1268
+ let result;
1269
+ try {
1270
+ result = JSON.parse(decoder.decode(decoded));
1271
+ } catch {
1272
+ throw new JWTInvalid("Failed to parse the decoded payload as JSON");
1273
+ }
1274
+ if (!isObject$1(result)) throw new JWTInvalid("Invalid JWT Claims Set");
1275
+ return result;
637
1276
  }
638
- function fromOrganizationMutationAuthorityError(value, status, retryAfter) {
639
- if (status === 400 || status === 413 || status === 415) return new AuthError("invalid_request", 400);
640
- if (status === 409) return new AuthError("state_conflict", 409);
641
- if (status === 429) return new AuthError("auth_request_rate_limited", 429, parseRetryAfter(retryAfter));
642
- const code = isObject(value) && typeof value.code === "string" ? value.code : void 0;
643
- if (status === 403 && code === "REQUEST_ORIGIN_DENIED") return new AuthError("request_origin_denied", 403);
644
- return fromOrganizationReadAuthorityError(value, status);
1277
+ //#endregion
1278
+ //#region ../../node_modules/.pnpm/destr@2.0.5/node_modules/destr/dist/index.mjs
1279
+ const suspectProtoRx = /"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/;
1280
+ const suspectConstructorRx = /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;
1281
+ const JsonSigRx = /^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/;
1282
+ function jsonParseTransform(key, value) {
1283
+ if (key === "__proto__" || key === "constructor" && value && typeof value === "object" && "prototype" in value) {
1284
+ warnKeyDropped(key);
1285
+ return;
1286
+ }
1287
+ return value;
645
1288
  }
646
- function fromOrganizationInvitationAdministrationError(value, status, retryAfter) {
647
- if (status === 422 && isObject(value) && value.code === "RECOVERY_REQUIRED") return new AuthError("invitation_recovery_required", 422);
648
- return fromOrganizationMutationAuthorityError(value, status, retryAfter);
1289
+ function warnKeyDropped(key) {
1290
+ console.warn(`[destr] Dropping "${key}" key to prevent prototype pollution.`);
649
1291
  }
650
- function normalizeOrganizationMemberAuthority(value, organizationId, memberId) {
651
- exact$2(value, [
652
- "organizationId",
653
- "actor",
654
- "target"
655
- ]);
656
- if (!isId(value.organizationId) || value.organizationId !== organizationId) throw authorityUnavailable();
657
- const actor = normalizeOrganizationAuthorityMemberOutcome(value.actor);
658
- const target = normalizeOrganizationAuthorityMemberOutcome(value.target);
659
- if (target.memberId !== memberId || actor.manualRole !== "owner" && actor.manualRole !== "admin") throw authorityUnavailable();
660
- for (const member of [actor, target]) if (member.manualRole === "member" ? member.role === "owner" : member.role !== member.manualRole) throw authorityUnavailable();
661
- if (actor.memberId === target.memberId && (actor.manualRole !== target.manualRole || actor.role !== target.role || actor.authorityRevision !== target.authorityRevision)) throw authorityUnavailable();
662
- return {
663
- organizationId: value.organizationId,
664
- actor,
665
- target
666
- };
1292
+ function destr(value, options = {}) {
1293
+ if (typeof value !== "string") return value;
1294
+ if (value[0] === "\"" && value[value.length - 1] === "\"" && value.indexOf("\\") === -1) return value.slice(1, -1);
1295
+ const _value = value.trim();
1296
+ if (_value.length <= 9) switch (_value.toLowerCase()) {
1297
+ case "true": return true;
1298
+ case "false": return false;
1299
+ case "undefined": return;
1300
+ case "null": return null;
1301
+ case "nan": return NaN;
1302
+ case "infinity": return Number.POSITIVE_INFINITY;
1303
+ case "-infinity": return Number.NEGATIVE_INFINITY;
1304
+ }
1305
+ if (!JsonSigRx.test(value)) {
1306
+ if (options.strict) throw new SyntaxError("[destr] Invalid JSON");
1307
+ return value;
1308
+ }
1309
+ try {
1310
+ if (suspectProtoRx.test(value) || suspectConstructorRx.test(value)) {
1311
+ if (options.strict) throw new Error("[destr] Possible prototype pollution");
1312
+ return JSON.parse(value, jsonParseTransform);
1313
+ }
1314
+ return JSON.parse(value);
1315
+ } catch (error) {
1316
+ if (options.strict) throw error;
1317
+ return value;
1318
+ }
667
1319
  }
668
- function normalizeOrganizationAuthorityMemberOutcome(value, includesStatus = false) {
669
- exact$2(value, [
670
- "memberId",
671
- "manualRole",
672
- "role",
673
- "authorityRevision",
674
- ...includesStatus ? ["status"] : []
675
- ]);
676
- if (!isId(value.memberId) || value.manualRole !== "owner" && value.manualRole !== "admin" && value.manualRole !== "member" || value.role !== "owner" && value.role !== "admin" && value.role !== "member") throw authorityUnavailable();
677
- return {
678
- memberId: value.memberId,
679
- manualRole: value.manualRole,
680
- role: value.role,
681
- authorityRevision: normalizeAuthorityResultRevision(value.authorityRevision)
682
- };
1320
+ //#endregion
1321
+ //#region ../../node_modules/.pnpm/ofetch@1.5.1/node_modules/ofetch/dist/shared/ofetch.CWycOUEr.mjs
1322
+ var FetchError = class extends Error {
1323
+ constructor(message, opts) {
1324
+ super(message, opts);
1325
+ this.name = "FetchError";
1326
+ if (opts?.cause && !this.cause) this.cause = opts.cause;
1327
+ }
1328
+ };
1329
+ function createFetchError(ctx) {
1330
+ const errorMessage = ctx.error?.message || ctx.error?.toString() || "";
1331
+ const method = ctx.request?.method || ctx.options?.method || "GET";
1332
+ const url = ctx.request?.url || String(ctx.request) || "/";
1333
+ const fetchError = new FetchError(`${`[${method}] ${JSON.stringify(url)}`}: ${ctx.response ? `${ctx.response.status} ${ctx.response.statusText}` : "<no response>"}${errorMessage ? ` ${errorMessage}` : ""}`, ctx.error ? { cause: ctx.error } : void 0);
1334
+ for (const key of [
1335
+ "request",
1336
+ "options",
1337
+ "response"
1338
+ ]) Object.defineProperty(fetchError, key, { get() {
1339
+ return ctx[key];
1340
+ } });
1341
+ for (const [key, refKey] of [
1342
+ ["data", "_data"],
1343
+ ["status", "status"],
1344
+ ["statusCode", "status"],
1345
+ ["statusText", "statusText"],
1346
+ ["statusMessage", "statusText"]
1347
+ ]) Object.defineProperty(fetchError, key, { get() {
1348
+ return ctx.response && ctx.response[refKey];
1349
+ } });
1350
+ return fetchError;
683
1351
  }
684
- function normalizeAuthorityResultRevision(value) {
685
- if (!Number.isSafeInteger(value) || value < 0 || value >= Number.MAX_SAFE_INTEGER) throw authorityUnavailable();
686
- return value;
1352
+ const payloadMethods = new Set(Object.freeze([
1353
+ "PATCH",
1354
+ "POST",
1355
+ "PUT",
1356
+ "DELETE"
1357
+ ]));
1358
+ function isPayloadMethod(method = "GET") {
1359
+ return payloadMethods.has(method.toUpperCase());
687
1360
  }
688
- function fromInvitationAuthorityError(value, status) {
689
- const code = isObject(value) && typeof value.code === "string" ? value.code : void 0;
690
- if (status === 401 && code === "UNAUTHORIZED") return new AuthError("authentication_required", 401);
691
- if (status === 403 && (code === "INVALID_ORIGIN" || code === "MISSING_OR_NULL_ORIGIN")) return new AuthError("request_origin_denied", 403);
692
- if (status === 403 && code === "YOU_ARE_NOT_THE_RECIPIENT_OF_THE_INVITATION") return new AuthError("invitation_recipient_mismatch", 403);
693
- if (status === 403 && code === "EMAIL_VERIFICATION_REQUIRED_BEFORE_ACCEPTING_OR_REJECTING_INVITATION") return new AuthError("email_verification_required", 403);
694
- if (status === 400 && (code === "INVITATION_NOT_FOUND" || code === "ORGANIZATION_NOT_FOUND" || code === "TEAM_NOT_FOUND")) return new AuthError("invitation_unavailable", 409);
695
- return authorityUnavailable();
1361
+ function isJSONSerializable(value) {
1362
+ if (value === void 0) return false;
1363
+ const t = typeof value;
1364
+ if (t === "string" || t === "number" || t === "boolean" || t === null) return true;
1365
+ if (t !== "object") return false;
1366
+ if (Array.isArray(value)) return true;
1367
+ if (value.buffer) return false;
1368
+ if (value instanceof FormData || value instanceof URLSearchParams) return false;
1369
+ return value.constructor && value.constructor.name === "Object" || typeof value.toJSON === "function";
696
1370
  }
697
- function fromInvitationError(error) {
698
- return error instanceof AuthError ? error : authorityUnavailable();
1371
+ const textTypes = new Set([
1372
+ "image/svg",
1373
+ "application/xml",
1374
+ "application/xhtml",
1375
+ "application/html"
1376
+ ]);
1377
+ const JSON_RE = /^application\/(?:[\w!#$%&*.^`~-]*\+)?json(;.+)?$/i;
1378
+ function detectResponseType(_contentType = "") {
1379
+ if (!_contentType) return "json";
1380
+ const contentType = _contentType.split(";").shift() || "";
1381
+ if (JSON_RE.test(contentType)) return "json";
1382
+ if (contentType === "text/event-stream") return "stream";
1383
+ if (textTypes.has(contentType) || contentType.startsWith("text/")) return "text";
1384
+ return "blob";
699
1385
  }
700
- function mapError(code, status) {
701
- if (code === "authentication_required") return {
702
- code,
703
- status: 401
704
- };
705
- if (code === "request_origin_denied") return {
706
- code,
707
- status: 403
708
- };
709
- if (code === "invalid_workspace_selection") return {
710
- code,
711
- status: 422
712
- };
713
- if (code === "organization_context_too_large") return {
714
- code,
715
- status: 422
716
- };
717
- if (code === "credential_rate_limited") return {
718
- code,
719
- status: 429
720
- };
721
- if (code === "identity_authority_unavailable") return {
722
- code,
723
- status: 503
724
- };
725
- if (status === 401 || status === 400) return {
726
- code: "invalid_credentials",
727
- status: 401
728
- };
729
- if (status === 403) return {
730
- code: "access_denied",
731
- status: 403
732
- };
733
- if (status === 409) return {
734
- code: "state_conflict",
735
- status: 409
736
- };
737
- if (status === 422) return {
738
- code: "invalid_workspace_selection",
739
- status: 422
740
- };
741
- if (status === 429) return {
742
- code: "credential_rate_limited",
743
- status: 429
1386
+ function resolveFetchOptions(request, input, defaults, Headers) {
1387
+ const headers = mergeHeaders(input?.headers ?? request?.headers, defaults?.headers, Headers);
1388
+ let query;
1389
+ if (defaults?.query || defaults?.params || input?.params || input?.query) query = {
1390
+ ...defaults?.params,
1391
+ ...defaults?.query,
1392
+ ...input?.params,
1393
+ ...input?.query
744
1394
  };
745
1395
  return {
746
- code: "identity_authority_unavailable",
747
- status: 503
1396
+ ...defaults,
1397
+ ...input,
1398
+ query,
1399
+ params: query,
1400
+ headers
748
1401
  };
749
1402
  }
750
- function parseRetryAfter(value) {
751
- if (!value || !/^\d+$/.test(value)) return void 0;
752
- const seconds = Number(value);
753
- return Number.isSafeInteger(seconds) && seconds >= 1 && seconds <= 3600 ? seconds : void 0;
754
- }
755
- function toDate(value) {
756
- const result = value instanceof Date ? value : typeof value === "string" ? new Date(value) : void 0;
757
- return result && Number.isFinite(result.getTime()) ? result : void 0;
758
- }
759
- function isId(value) {
760
- return typeof value === "string" && id.test(value);
761
- }
762
- function exact$2(value, keys) {
763
- if (!isObject(value) || Object.keys(value).sort().join(",") !== [...keys].sort().join(",")) throw authorityUnavailable();
764
- }
765
- function boundedString(value, maximum) {
766
- return typeof value === "string" && value.length > 0 && new TextEncoder().encode(value).byteLength <= maximum;
1403
+ function mergeHeaders(input, defaults, Headers) {
1404
+ if (!defaults) return new Headers(input);
1405
+ const headers = new Headers(defaults);
1406
+ if (input) for (const [key, value] of Symbol.iterator in input || Array.isArray(input) ? input : new Headers(input)) headers.set(key, value);
1407
+ return headers;
767
1408
  }
768
- function role(value) {
769
- return value === "owner" || value === "admin" || value === "member";
1409
+ async function callHooks(context, hooks) {
1410
+ if (hooks) if (Array.isArray(hooks)) for (const hook of hooks) await hook(context);
1411
+ else await hooks(context);
770
1412
  }
771
- function nullableHttpsUrl(value) {
772
- if (value === null) return null;
773
- if (typeof value !== "string" || value.length > 2048) throw authorityUnavailable();
774
- let url;
775
- try {
776
- url = new URL(value);
777
- } catch {
778
- throw authorityUnavailable();
1413
+ const retryStatusCodes = new Set([
1414
+ 408,
1415
+ 409,
1416
+ 425,
1417
+ 429,
1418
+ 500,
1419
+ 502,
1420
+ 503,
1421
+ 504
1422
+ ]);
1423
+ const nullBodyResponses = new Set([
1424
+ 101,
1425
+ 204,
1426
+ 205,
1427
+ 304
1428
+ ]);
1429
+ function createFetch(globalOptions = {}) {
1430
+ const { fetch = globalThis.fetch, Headers = globalThis.Headers, AbortController = globalThis.AbortController } = globalOptions;
1431
+ async function onError(context) {
1432
+ const isAbort = context.error && context.error.name === "AbortError" && !context.options.timeout || false;
1433
+ if (context.options.retry !== false && !isAbort) {
1434
+ let retries;
1435
+ if (typeof context.options.retry === "number") retries = context.options.retry;
1436
+ else retries = isPayloadMethod(context.options.method) ? 0 : 1;
1437
+ const responseCode = context.response && context.response.status || 500;
1438
+ if (retries > 0 && (Array.isArray(context.options.retryStatusCodes) ? context.options.retryStatusCodes.includes(responseCode) : retryStatusCodes.has(responseCode))) {
1439
+ const retryDelay = typeof context.options.retryDelay === "function" ? context.options.retryDelay(context) : context.options.retryDelay || 0;
1440
+ if (retryDelay > 0) await new Promise((resolve) => setTimeout(resolve, retryDelay));
1441
+ return $fetchRaw(context.request, {
1442
+ ...context.options,
1443
+ retry: retries - 1
1444
+ });
1445
+ }
1446
+ }
1447
+ const error = createFetchError(context);
1448
+ if (Error.captureStackTrace) Error.captureStackTrace(error, $fetchRaw);
1449
+ throw error;
779
1450
  }
780
- if (url.protocol !== "https:" || url.username || url.password || url.toString() !== value) throw authorityUnavailable();
781
- return value;
1451
+ const $fetchRaw = async function $fetchRaw2(_request, _options = {}) {
1452
+ const context = {
1453
+ request: _request,
1454
+ options: resolveFetchOptions(_request, _options, globalOptions.defaults, Headers),
1455
+ response: void 0,
1456
+ error: void 0
1457
+ };
1458
+ if (context.options.method) context.options.method = context.options.method.toUpperCase();
1459
+ if (context.options.onRequest) {
1460
+ await callHooks(context, context.options.onRequest);
1461
+ if (!(context.options.headers instanceof Headers)) context.options.headers = new Headers(context.options.headers || {});
1462
+ }
1463
+ if (typeof context.request === "string") {
1464
+ if (context.options.baseURL) context.request = withBase(context.request, context.options.baseURL);
1465
+ if (context.options.query) {
1466
+ context.request = withQuery(context.request, context.options.query);
1467
+ delete context.options.query;
1468
+ }
1469
+ if ("query" in context.options) delete context.options.query;
1470
+ if ("params" in context.options) delete context.options.params;
1471
+ }
1472
+ if (context.options.body && isPayloadMethod(context.options.method)) {
1473
+ if (isJSONSerializable(context.options.body)) {
1474
+ const contentType = context.options.headers.get("content-type");
1475
+ if (typeof context.options.body !== "string") context.options.body = contentType === "application/x-www-form-urlencoded" ? new URLSearchParams(context.options.body).toString() : JSON.stringify(context.options.body);
1476
+ if (!contentType) context.options.headers.set("content-type", "application/json");
1477
+ if (!context.options.headers.has("accept")) context.options.headers.set("accept", "application/json");
1478
+ } else if ("pipeTo" in context.options.body && typeof context.options.body.pipeTo === "function" || typeof context.options.body.pipe === "function") {
1479
+ if (!("duplex" in context.options)) context.options.duplex = "half";
1480
+ }
1481
+ }
1482
+ let abortTimeout;
1483
+ if (!context.options.signal && context.options.timeout) {
1484
+ const controller = new AbortController();
1485
+ abortTimeout = setTimeout(() => {
1486
+ const error = new Error("[TimeoutError]: The operation was aborted due to timeout");
1487
+ error.name = "TimeoutError";
1488
+ error.code = 23;
1489
+ controller.abort(error);
1490
+ }, context.options.timeout);
1491
+ context.options.signal = controller.signal;
1492
+ }
1493
+ try {
1494
+ context.response = await fetch(context.request, context.options);
1495
+ } catch (error) {
1496
+ context.error = error;
1497
+ if (context.options.onRequestError) await callHooks(context, context.options.onRequestError);
1498
+ return await onError(context);
1499
+ } finally {
1500
+ if (abortTimeout) clearTimeout(abortTimeout);
1501
+ }
1502
+ if ((context.response.body || context.response._bodyInit) && !nullBodyResponses.has(context.response.status) && context.options.method !== "HEAD") {
1503
+ const responseType = (context.options.parseResponse ? "json" : context.options.responseType) || detectResponseType(context.response.headers.get("content-type") || "");
1504
+ switch (responseType) {
1505
+ case "json": {
1506
+ const data = await context.response.text();
1507
+ const parseFunction = context.options.parseResponse || destr;
1508
+ context.response._data = parseFunction(data);
1509
+ break;
1510
+ }
1511
+ case "stream":
1512
+ context.response._data = context.response.body || context.response._bodyInit;
1513
+ break;
1514
+ default: context.response._data = await context.response[responseType]();
1515
+ }
1516
+ }
1517
+ if (context.options.onResponse) await callHooks(context, context.options.onResponse);
1518
+ if (!context.options.ignoreResponseError && context.response.status >= 400 && context.response.status < 600) {
1519
+ if (context.options.onResponseError) await callHooks(context, context.options.onResponseError);
1520
+ return await onError(context);
1521
+ }
1522
+ return context.response;
1523
+ };
1524
+ const $fetch = async function $fetch2(request, options) {
1525
+ return (await $fetchRaw(request, options))._data;
1526
+ };
1527
+ $fetch.raw = $fetchRaw;
1528
+ $fetch.native = (...args) => fetch(...args);
1529
+ $fetch.create = (defaultOptions = {}, customGlobalOptions = {}) => createFetch({
1530
+ ...globalOptions,
1531
+ ...customGlobalOptions,
1532
+ defaults: {
1533
+ ...globalOptions.defaults,
1534
+ ...customGlobalOptions.defaults,
1535
+ ...defaultOptions
1536
+ }
1537
+ });
1538
+ return $fetch;
782
1539
  }
783
- function responseDate(value) {
784
- if (typeof value !== "string") throw authorityUnavailable();
785
- const date = new Date(value);
786
- if (!Number.isFinite(date.getTime()) || date.toISOString() !== value) throw authorityUnavailable();
787
- return date;
1540
+ //#endregion
1541
+ //#region src/shared.ts
1542
+ const DRIVE_CREDENTIAL_LIFETIME_SECONDS = 840;
1543
+ const id = /^[A-Za-z0-9_-]{1,128}$/;
1544
+ const email = /^[^\s@]+@[^\s@]+$/;
1545
+ const MAX_SOCIAL_ID_TOKEN_BYTES = 16 * 1024;
1546
+ function normalizeEmail(value) {
1547
+ if (typeof value !== "string") throw new TypeError("email is invalid");
1548
+ const normalized = value.trim().toLowerCase();
1549
+ if (normalized.length === 0 || normalized.length > 320 || !email.test(normalized)) throw new TypeError("email is invalid");
1550
+ return normalized;
788
1551
  }
789
- function nullableCursor(value) {
1552
+ function normalizeSocialIdTokenInput(value) {
1553
+ if (!isObject(value)) throw new TypeError("social ID token input is invalid");
1554
+ const keys = Object.keys(value);
1555
+ if (keys.length !== 3 && keys.length !== 4 || keys.some((key) => key !== "provider" && key !== "idToken" && key !== "nonce" && key !== "signUp") || value.provider !== "google" && value.provider !== "apple" || typeof value.signUp !== "boolean" || typeof value.idToken !== "string" || value.idToken.length < 1 || new TextEncoder().encode(value.idToken).byteLength > MAX_SOCIAL_ID_TOKEN_BYTES || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(value.idToken) || value.nonce !== void 0 && (typeof value.nonce !== "string" || value.nonce.length < 1 || value.nonce.length > 256 || !/^[\x20-\x7e]+$/.test(value.nonce))) throw new TypeError("social ID token input is invalid");
1556
+ return {
1557
+ provider: value.provider,
1558
+ idToken: value.idToken,
1559
+ ...value.nonce === void 0 ? {} : { nonce: value.nonce },
1560
+ signUp: value.signUp
1561
+ };
1562
+ }
1563
+ function socialIdTokenRequest(value) {
1564
+ return {
1565
+ provider: value.provider,
1566
+ idToken: {
1567
+ token: value.idToken,
1568
+ ...value.nonce === void 0 ? {} : { nonce: value.nonce }
1569
+ },
1570
+ requestSignUp: value.signUp
1571
+ };
1572
+ }
1573
+ function normalizeOrigin(value, name) {
1574
+ if (value.length === 0 || value.length > 2048 || /[^\x20-\x7e]/.test(value)) throw new TypeError(`${name} must be an ASCII HTTP origin`);
1575
+ let url;
1576
+ try {
1577
+ url = new URL(value);
1578
+ } catch {
1579
+ throw new TypeError(`${name} must be an ASCII HTTP origin`);
1580
+ }
1581
+ const local = url.hostname === "localhost" || url.hostname.endsWith(".localhost") || url.hostname === "127.0.0.1";
1582
+ if (url.protocol !== "https:" && !(local && url.protocol === "http:") || url.username || url.password || url.pathname !== "/" || url.search || url.hash || url.origin !== value) throw new TypeError(`${name} must be an ASCII HTTP origin`);
1583
+ return url.origin;
1584
+ }
1585
+ function normalizeTimeout(value) {
1586
+ const timeout = value ?? 1e4;
1587
+ if (!Number.isSafeInteger(timeout) || timeout < 1 || timeout > 6e4) throw new TypeError("timeoutMs must be an integer from 1 to 60000");
1588
+ return timeout;
1589
+ }
1590
+ function normalizeSession(value) {
790
1591
  if (value === null) return null;
791
- if (typeof value !== "string" || value.length < 1 || value.length > 820 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(value)) throw authorityUnavailable();
792
- return value;
1592
+ if (!isObject(value) || !isObject(value.session) || !isObject(value.user)) throw authorityUnavailable();
1593
+ const expiresAt = toDate(value.session.expiresAt);
1594
+ const image = value.user.image;
1595
+ if (!isId(value.session.id) || !expiresAt || !isId(value.user.id) || typeof value.user.name !== "string" || value.user.name.length > 256 || typeof value.user.email !== "string" || value.user.email.length > 320 || !email.test(value.user.email) || typeof value.user.emailVerified !== "boolean" || image !== null && image !== void 0 && (typeof image !== "string" || image.length > 2048)) throw authorityUnavailable();
1596
+ return {
1597
+ id: value.session.id,
1598
+ expiresAt,
1599
+ user: {
1600
+ id: value.user.id,
1601
+ name: value.user.name,
1602
+ email: value.user.email,
1603
+ emailVerified: value.user.emailVerified,
1604
+ image: image ?? null
1605
+ }
1606
+ };
793
1607
  }
794
- function normalizeResponseId(value) {
795
- if (!isId(value)) throw authorityUnavailable();
1608
+ function normalizeDriveCredential(value, now) {
1609
+ if (!isObject(value) || value.tokenType !== "Bearer" || value.expiresIn !== DRIVE_CREDENTIAL_LIFETIME_SECONDS || typeof value.token !== "string" || value.token.length === 0 || new TextEncoder().encode(`Bearer ${value.token}`).byteLength > 16 * 1024) throw authorityUnavailable();
1610
+ return {
1611
+ tokenType: "Bearer",
1612
+ token: value.token,
1613
+ expiresAt: new Date(now + value.expiresIn * 1e3)
1614
+ };
1615
+ }
1616
+ function normalizeOrganizationPageInput(value) {
1617
+ if (value === void 0) return new URLSearchParams();
1618
+ if (!isObject(value) || Object.keys(value).some((key) => key !== "limit" && key !== "cursor")) throw new AuthError("invalid_request", 400);
1619
+ const input = value;
1620
+ const query = new URLSearchParams();
1621
+ if (input.limit !== void 0) {
1622
+ if (!Number.isSafeInteger(input.limit) || input.limit < 1 || input.limit > 100) throw new AuthError("invalid_request", 400);
1623
+ query.set("limit", String(input.limit));
1624
+ }
1625
+ if (input.cursor !== void 0) {
1626
+ if (typeof input.cursor !== "string" || input.cursor.length < 1 || input.cursor.length > 820 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(input.cursor)) throw new AuthError("invalid_request", 400);
1627
+ query.set("cursor", input.cursor);
1628
+ }
1629
+ return query;
1630
+ }
1631
+ function normalizeIdInput(value) {
1632
+ if (!isId(value)) throw new AuthError("invalid_request", 400);
796
1633
  return value;
797
1634
  }
798
- function unique(items, key) {
799
- if (new Set(items.map(key)).size !== items.length) throw authorityUnavailable();
800
- return items;
1635
+ function normalizeOrganization(value) {
1636
+ exact$3(value, [
1637
+ "capabilities",
1638
+ "id",
1639
+ "lifecycle",
1640
+ "logo",
1641
+ "name",
1642
+ "role",
1643
+ "slug"
1644
+ ]);
1645
+ if (!isId(value.id) || !boundedString(value.name, 255) || !boundedString(value.slug, 255) || value.lifecycle !== "ordinary" && value.lifecycle !== "managed" || !role(value.role) || !isObject(value.capabilities)) throw authorityUnavailable();
1646
+ exact$3(value.capabilities, [
1647
+ "readInvitations",
1648
+ "readMembers",
1649
+ "readTeams"
1650
+ ]);
1651
+ if (value.capabilities.readMembers !== true || value.capabilities.readTeams !== true || typeof value.capabilities.readInvitations !== "boolean") throw authorityUnavailable();
1652
+ return {
1653
+ id: value.id,
1654
+ name: value.name,
1655
+ slug: value.slug,
1656
+ logo: nullableHttpsUrl(value.logo),
1657
+ lifecycle: value.lifecycle,
1658
+ role: value.role,
1659
+ capabilities: {
1660
+ readMembers: true,
1661
+ readTeams: true,
1662
+ readInvitations: value.capabilities.readInvitations
1663
+ }
1664
+ };
801
1665
  }
802
- function isObject(value) {
803
- return typeof value === "object" && value !== null && !Array.isArray(value);
1666
+ function normalizeOrganizationDisplayInput(value) {
1667
+ if (!isObject(value) || Object.keys(value).sort().join(",") !== "logo,name,slug") throw new AuthError("invalid_request", 400);
1668
+ if (!boundedString(value.name, 255) || !boundedString(value.slug, 255)) throw new AuthError("invalid_request", 400);
1669
+ let logo;
1670
+ try {
1671
+ logo = nullableHttpsUrl(value.logo);
1672
+ } catch {
1673
+ throw new AuthError("invalid_request", 400);
1674
+ }
1675
+ return {
1676
+ name: value.name,
1677
+ slug: value.slug,
1678
+ logo
1679
+ };
804
1680
  }
805
- //#endregion
806
- //#region src/identity-resolution.ts
807
- const emailPattern$1 = /^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9-]*\.)+[A-Za-z]{2,}$(?![\s\S])/;
808
- function exact$1(value, keys) {
809
- return value !== null && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
1681
+ function normalizeOrganizationDisplay(value) {
1682
+ try {
1683
+ return normalizeOrganizationDisplayInput(value);
1684
+ } catch {
1685
+ throw authorityUnavailable();
1686
+ }
810
1687
  }
811
- function createIdentityResolverAuth(options) {
812
- const url = joinURL(normalizeOrigin(options.authOrigin, "authOrigin"), "api/v1/auth/identities/resolve");
813
- const fetchImpl = options.fetch ?? globalThis.fetch?.bind(globalThis);
814
- if (typeof fetchImpl !== "function") throw new TypeError("fetch is required");
815
- const timeoutMs = normalizeTimeout(options.timeoutMs);
816
- let inFlight = false;
817
- return { async resolveIdentity(input, clientAssertion) {
818
- if (!exact$1(input, ["identifier"]) || typeof input.identifier !== "string" || input.identifier.length > 324) throw new AuthError("invalid_request", 400);
819
- const identifier = input.identifier.trim().toLowerCase();
820
- if (!(identifier.length <= 320 && emailPattern$1.test(identifier)) && !/^[a-z0-9_.]{3,30}$(?![\s\S])/.test(identifier)) throw new AuthError("invalid_request", 400);
821
- if (typeof clientAssertion !== "string" || clientAssertion.length + 7 > 16 * 1024 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$(?![\s\S])/.test(clientAssertion)) throw new AuthError("invalid_request", 400);
822
- if (inFlight) throw new AuthError("state_conflict", 409);
823
- inFlight = true;
824
- const controller = new AbortController();
825
- let reader;
826
- let timer;
827
- let mappedError;
828
- try {
829
- const deadline = new Promise((_, reject) => {
830
- timer = setTimeout(() => {
831
- reject(authorityUnavailable());
832
- controller.abort();
833
- reader?.cancel().catch(() => {});
834
- }, timeoutMs);
835
- });
836
- const exchange = async () => {
837
- const response = await fetchImpl(url, {
838
- method: "POST",
839
- headers: {
840
- authorization: `Bearer ${clientAssertion}`,
841
- accept: "application/json",
842
- "content-type": "application/json"
843
- },
844
- body: JSON.stringify({ identifier }),
845
- credentials: "omit",
846
- cache: "no-store",
847
- redirect: "manual",
848
- signal: controller.signal
849
- });
850
- if (controller.signal.aborted) {
851
- response.body?.cancel().catch(() => {});
852
- throw authorityUnavailable();
853
- }
854
- if (!response.body) throw authorityUnavailable();
855
- reader = response.body.getReader();
856
- const length = response.headers.get("content-length");
857
- if (response.redirected || response.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase() !== "application/json" || length !== null && (!/^\d+$/.test(length) || Number(length) > 1024)) throw authorityUnavailable();
858
- const bytes = new Uint8Array(1024);
859
- let size = 0;
860
- while (true) {
861
- const chunk = await reader.read();
862
- if (controller.signal.aborted) throw authorityUnavailable();
863
- if (chunk.done) break;
864
- if (size + chunk.value.byteLength > bytes.length) throw authorityUnavailable();
865
- bytes.set(chunk.value, size);
866
- size += chunk.value.byteLength;
867
- }
868
- const value = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(0, size)));
869
- if (response.status !== 200) {
870
- if (!exact$1(value, ["code", "message"])) throw authorityUnavailable();
871
- if (response.status === 401 && value.code === "UNAUTHORIZED" && value.message === "The identity resolution assertion is invalid.") mappedError = new AuthError("authentication_required", 401);
872
- if (response.status === 429 && value.code === "TOO_MANY_REQUESTS" && value.message === "Identity resolution requests are temporarily limited.") {
873
- const retryAfter = response.headers.get("retry-after");
874
- if (retryAfter === null || !/^(?:[1-9]|[1-5][0-9]|60)$/.test(retryAfter)) throw authorityUnavailable();
875
- mappedError = new AuthError("auth_request_rate_limited", 429, Number(retryAfter));
876
- }
877
- throw mappedError ?? authorityUnavailable();
878
- }
879
- if (!exact$1(value, ["identity"])) throw authorityUnavailable();
880
- if (value.identity === null) return null;
881
- if (!exact$1(value.identity, ["userId"]) || typeof value.identity.userId !== "string" || !/^[A-Za-z0-9_-]{1,128}$(?![\s\S])/.test(value.identity.userId)) throw authorityUnavailable();
882
- return { userId: value.identity.userId };
1688
+ function normalizeOrganizationTeamDisplayInput(value) {
1689
+ if (!isObject(value) || Object.keys(value).join(",") !== "name" || !boundedString(value.name, 255)) throw new AuthError("invalid_request", 400);
1690
+ return { name: value.name };
1691
+ }
1692
+ function normalizeOrganizationTeamDisplay(value) {
1693
+ try {
1694
+ return normalizeOrganizationTeamDisplayInput(value);
1695
+ } catch {
1696
+ throw authorityUnavailable();
1697
+ }
1698
+ }
1699
+ function normalizeOrganizationCreationInput(name, slug, idempotencyKey) {
1700
+ if (!boundedString(name, 255) || !boundedString(idempotencyKey, 255) || typeof slug !== "string" || !/^[a-z0-9-]{1,128}$/.test(slug)) throw new AuthError("invalid_request", 400);
1701
+ return {
1702
+ name,
1703
+ slug,
1704
+ idempotencyKey
1705
+ };
1706
+ }
1707
+ function normalizeCreatedOrganization(value) {
1708
+ exact$3(value, [
1709
+ "id",
1710
+ "name",
1711
+ "slug"
1712
+ ]);
1713
+ if (!isId(value.id) || !boundedString(value.name, 255) || !boundedString(value.slug, 128)) throw authorityUnavailable();
1714
+ return {
1715
+ id: value.id,
1716
+ name: value.name,
1717
+ slug: value.slug
1718
+ };
1719
+ }
1720
+ function normalizeOrganizationTeamCreationInput(name, idempotencyKey) {
1721
+ if (!boundedString(name, 255) || !boundedString(idempotencyKey, 255)) throw new AuthError("invalid_request", 400);
1722
+ return {
1723
+ name,
1724
+ idempotencyKey
1725
+ };
1726
+ }
1727
+ function normalizeCreatedOrganizationTeam(value) {
1728
+ exact$3(value, ["id", "name"]);
1729
+ if (!isId(value.id) || !boundedString(value.name, 255)) throw authorityUnavailable();
1730
+ return {
1731
+ id: value.id,
1732
+ name: value.name
1733
+ };
1734
+ }
1735
+ function normalizeOrganizationMemberInvitationCreationInput(value) {
1736
+ if (!isObject(value)) throw new AuthError("invalid_request", 400);
1737
+ const keys = Object.keys(value).sort().join(",");
1738
+ if (keys !== "email,idempotencyKey" && keys !== "email,idempotencyKey,teamIds") throw new AuthError("invalid_request", 400);
1739
+ let normalizedEmail;
1740
+ try {
1741
+ normalizedEmail = normalizeEmail(value.email);
1742
+ } catch {
1743
+ throw new AuthError("invalid_request", 400);
1744
+ }
1745
+ if (new TextEncoder().encode(normalizedEmail).byteLength > 320 || !boundedString(value.idempotencyKey, 255) || value.teamIds !== void 0 && (!Array.isArray(value.teamIds) || value.teamIds.length > 100)) throw new AuthError("invalid_request", 400);
1746
+ const teamIds = value.teamIds?.map((teamId) => normalizeIdInput(teamId));
1747
+ if (teamIds && new Set(teamIds).size !== teamIds.length) throw new AuthError("invalid_request", 400);
1748
+ return {
1749
+ email: normalizedEmail,
1750
+ ...teamIds === void 0 ? {} : { teamIds },
1751
+ idempotencyKey: value.idempotencyKey
1752
+ };
1753
+ }
1754
+ function normalizeCreatedOrganizationMemberInvitation(value) {
1755
+ exact$3(value, ["expiresAt", "id"]);
1756
+ if (!isId(value.id)) throw authorityUnavailable();
1757
+ return {
1758
+ id: value.id,
1759
+ expiresAt: responseDate(value.expiresAt)
1760
+ };
1761
+ }
1762
+ function normalizeResentOrganizationInvitation(value, invitationId) {
1763
+ const invitation = normalizeCreatedOrganizationMemberInvitation(value);
1764
+ if (invitation.id !== invitationId) throw authorityUnavailable();
1765
+ return invitation;
1766
+ }
1767
+ function normalizeOrganizationInvitationAdministrationInput(idempotencyKey) {
1768
+ if (!boundedString(idempotencyKey, 255)) throw new AuthError("invalid_request", 400);
1769
+ return { idempotencyKey };
1770
+ }
1771
+ function normalizeCanceledOrganizationInvitation(value) {
1772
+ exact$3(value, ["status"]);
1773
+ if (value.status !== "canceled") throw authorityUnavailable();
1774
+ return { status: "canceled" };
1775
+ }
1776
+ function normalizeOrganizationMembershipRemovalInput(idempotencyKey) {
1777
+ if (!boundedString(idempotencyKey, 255)) throw new AuthError("invalid_request", 400);
1778
+ return { idempotencyKey };
1779
+ }
1780
+ function normalizeRemovedOrganizationMember(value) {
1781
+ exact$3(value, ["status"]);
1782
+ if (value.status !== "removed") throw authorityUnavailable();
1783
+ return { status: "removed" };
1784
+ }
1785
+ function normalizeOrganizationDeparture(value) {
1786
+ exact$3(value, ["status"]);
1787
+ if (value.status !== "left") throw authorityUnavailable();
1788
+ return { status: "left" };
1789
+ }
1790
+ function normalizeOrganizations(value) {
1791
+ exact$3(value, ["nextCursor", "organizations"]);
1792
+ if (!Array.isArray(value.organizations) || value.organizations.length > 100) throw authorityUnavailable();
1793
+ return {
1794
+ organizations: unique(value.organizations.map(normalizeOrganization), (item) => item.id),
1795
+ nextCursor: nullableCursor(value.nextCursor)
1796
+ };
1797
+ }
1798
+ function normalizeOrganizationMembers(value) {
1799
+ exact$3(value, ["members", "nextCursor"]);
1800
+ if (!Array.isArray(value.members) || value.members.length > 100) throw authorityUnavailable();
1801
+ return {
1802
+ members: unique(value.members.map((member) => {
1803
+ exact$3(member, [
1804
+ "email",
1805
+ "id",
1806
+ "image",
1807
+ "joinedAt",
1808
+ "name",
1809
+ "owner",
1810
+ "role",
1811
+ "teamIds",
1812
+ "userId"
1813
+ ]);
1814
+ if (!isId(member.id) || !isId(member.userId) || !boundedString(member.name, 255) || typeof member.email !== "string" || member.email.length > 320 || !email.test(member.email) || !role(member.role) || typeof member.owner !== "boolean" || !Array.isArray(member.teamIds) || member.teamIds.length > 100) throw authorityUnavailable();
1815
+ const teamIds = unique(member.teamIds.map((teamId) => normalizeResponseId(teamId)), (item) => item);
1816
+ return {
1817
+ id: member.id,
1818
+ userId: member.userId,
1819
+ name: member.name,
1820
+ email: member.email,
1821
+ image: nullableHttpsUrl(member.image),
1822
+ role: member.role,
1823
+ owner: member.owner,
1824
+ joinedAt: responseDate(member.joinedAt),
1825
+ teamIds
883
1826
  };
884
- return await Promise.race([exchange().finally(() => {
885
- inFlight = false;
886
- }), deadline]);
887
- } catch (error) {
888
- if (mappedError && mappedError === error) throw mappedError;
889
- throw authorityUnavailable();
890
- } finally {
891
- clearTimeout(timer);
892
- controller.abort();
893
- reader?.cancel().catch(() => {});
894
- }
895
- } };
1827
+ }), (item) => item.id),
1828
+ nextCursor: nullableCursor(value.nextCursor)
1829
+ };
896
1830
  }
897
- //#endregion
898
- //#region src/drive-recipients.ts
899
- const encoder = new TextEncoder();
900
- const emailPattern = /^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9-]*\.)+[A-Za-z]{2,}$/;
901
- function validEmail(value) {
902
- return typeof value === "string" && encoder.encode(value).byteLength <= 320 && emailPattern.test(value);
1831
+ function normalizeOrganizationTeams(value) {
1832
+ exact$3(value, ["nextCursor", "teams"]);
1833
+ if (!Array.isArray(value.teams) || value.teams.length > 100) throw authorityUnavailable();
1834
+ return {
1835
+ teams: unique(value.teams.map((team) => {
1836
+ exact$3(team, [
1837
+ "category",
1838
+ "createdAt",
1839
+ "id",
1840
+ "name"
1841
+ ]);
1842
+ if (!isId(team.id) || !boundedString(team.name, 255) || team.category !== "manual" && team.category !== "managed") throw authorityUnavailable();
1843
+ return {
1844
+ id: team.id,
1845
+ name: team.name,
1846
+ category: team.category,
1847
+ createdAt: responseDate(team.createdAt)
1848
+ };
1849
+ }), (item) => item.id),
1850
+ nextCursor: nullableCursor(value.nextCursor)
1851
+ };
903
1852
  }
904
- function exact(value, keys) {
905
- return value !== null && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
1853
+ function normalizeOrganizationTeamMembers(value) {
1854
+ exact$3(value, ["memberIds", "nextCursor"]);
1855
+ if (!Array.isArray(value.memberIds) || value.memberIds.length > 100) throw authorityUnavailable();
1856
+ return {
1857
+ memberIds: unique(value.memberIds.map((item) => normalizeResponseId(item)), (item) => item),
1858
+ nextCursor: nullableCursor(value.nextCursor)
1859
+ };
906
1860
  }
907
- const failures = {
908
- 400: [
909
- "BAD_REQUEST",
910
- "The recipient request is invalid.",
911
- "invalid_request"
912
- ],
913
- 401: [
914
- "UNAUTHORIZED",
915
- "The recipient service assertion is invalid.",
916
- "authentication_required"
917
- ],
918
- 404: [
919
- "NOT_FOUND",
920
- "The recipient is unavailable.",
921
- "recipient_unavailable"
922
- ],
923
- 405: [
924
- "METHOD_NOT_ALLOWED",
925
- "METHOD_NOT_ALLOWED",
926
- "invalid_request"
927
- ],
928
- 413: [
929
- "REQUEST_TOO_LONG",
930
- "The recipient request is too large.",
931
- "invalid_request"
932
- ],
933
- 429: [
934
- "TOO_MANY_REQUESTS",
935
- "Recipient requests are temporarily limited.",
936
- "auth_request_rate_limited"
937
- ],
938
- 503: [
939
- "SERVICE_UNAVAILABLE",
940
- "Recipient resolution is temporarily unavailable.",
941
- "identity_authority_unavailable"
942
- ]
943
- };
944
- function createDriveRecipientAuth(options) {
945
- const url = joinURL(normalizeOrigin(options.authOrigin, "authOrigin"), "api/v1/auth/drive-share-recipients/resolve");
946
- const fetchImpl = options.fetch ?? globalThis.fetch?.bind(globalThis);
947
- if (typeof fetchImpl !== "function") throw new TypeError("fetch is required");
948
- const timeoutMs = normalizeTimeout(options.timeoutMs);
949
- let inFlight = false;
950
- return { async resolveRecipient(input, clientAssertion) {
951
- let body;
952
- let email;
953
- try {
954
- if (!exact(input, ["email"]) || typeof input.email !== "string") throw new Error();
955
- email = input.email.trim().toLowerCase();
956
- if (!validEmail(email)) throw new Error();
957
- body = JSON.stringify({ email });
958
- } catch {
959
- throw new AuthError("invalid_request", 400);
960
- }
961
- if (encoder.encode(body).byteLength > 1024) throw new AuthError("invalid_request", 413);
962
- if (typeof clientAssertion !== "string" || clientAssertion.length + 7 > 16 * 1024 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$(?![\s\S])/.test(clientAssertion)) throw new AuthError("invalid_request", 400);
963
- if (inFlight) throw new AuthError("state_conflict", 409);
964
- inFlight = true;
965
- const controller = new AbortController();
966
- let reader;
967
- let timer;
968
- let authorityError;
969
- try {
970
- const deadline = new Promise((_, reject) => {
971
- timer = setTimeout(() => {
972
- reject(authorityUnavailable());
973
- controller.abort();
974
- reader?.cancel().catch(() => {});
975
- }, timeoutMs);
976
- });
977
- const exchange = async () => {
978
- const response = await fetchImpl(url, {
979
- method: "POST",
980
- headers: {
981
- authorization: `Bearer ${clientAssertion}`,
982
- accept: "application/json",
983
- "content-type": "application/json"
984
- },
985
- body,
986
- credentials: "omit",
987
- cache: "no-store",
988
- redirect: "manual",
989
- signal: controller.signal
990
- });
991
- if (controller.signal.aborted) {
992
- response.body?.cancel().catch(() => {});
993
- throw authorityUnavailable();
994
- }
995
- if (!response.body) throw authorityUnavailable();
996
- reader = response.body.getReader();
997
- const contentType = response.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
998
- const length = response.headers.get("content-length");
999
- if (response.redirected || contentType !== "application/json" || length !== null && (!/^\d+$/.test(length) || Number(length) > 4096)) throw authorityUnavailable();
1000
- const bytes = new Uint8Array(4096);
1001
- let size = 0;
1002
- while (true) {
1003
- const chunk = await reader.read();
1004
- if (controller.signal.aborted) throw authorityUnavailable();
1005
- if (chunk.done) break;
1006
- if (size + chunk.value.byteLength > bytes.byteLength) throw authorityUnavailable();
1007
- bytes.set(chunk.value, size);
1008
- size += chunk.value.byteLength;
1009
- }
1010
- const value = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(0, size)));
1011
- if (response.status !== 200) {
1012
- const status = response.status;
1013
- const failure = failures[status];
1014
- if (!failure || !exact(value, ["code", "message"]) || value.code !== failure[0] || value.message !== failure[1]) throw authorityUnavailable();
1015
- let retryAfterSeconds;
1016
- if (status === 429) {
1017
- const retryAfter = response.headers.get("retry-after");
1018
- if (retryAfter === null || !/^(?:[1-9]|[1-5][0-9]|60)$/.test(retryAfter)) throw authorityUnavailable();
1019
- retryAfterSeconds = Number(retryAfter);
1020
- }
1021
- authorityError = new AuthError(failure[2], status, retryAfterSeconds);
1022
- throw authorityError;
1023
- }
1024
- if (!exact(value, ["recipient"]) || !exact(value.recipient, [
1025
- "userId",
1026
- "name",
1027
- "email"
1028
- ])) throw authorityUnavailable();
1029
- const recipient = value.recipient;
1030
- if (typeof recipient.userId !== "string" || !/^[A-Za-z0-9_-]{1,128}$(?![\s\S])/.test(recipient.userId) || typeof recipient.name !== "string" || recipient.name.length === 0 || encoder.encode(recipient.name).byteLength > 1024 || !validEmail(recipient.email) || recipient.email !== recipient.email.trim().toLowerCase() || recipient.email !== email) throw authorityUnavailable();
1031
- return {
1032
- userId: recipient.userId,
1033
- name: recipient.name,
1034
- email: recipient.email
1035
- };
1861
+ function normalizeOrganizationInvitation(value) {
1862
+ exact$3(value, [
1863
+ "createdAt",
1864
+ "email",
1865
+ "expiresAt",
1866
+ "id",
1867
+ "inviter",
1868
+ "role",
1869
+ "status",
1870
+ "teamIds"
1871
+ ]);
1872
+ if (!isId(value.id) || typeof value.email !== "string" || value.email.length > 320 || !email.test(value.email) || !role(value.role) || value.status !== "pending" || !Array.isArray(value.teamIds) || value.teamIds.length > 100 || !isObject(value.inviter)) throw authorityUnavailable();
1873
+ exact$3(value.inviter, ["membershipId", "name"]);
1874
+ if (!isId(value.inviter.membershipId) || !boundedString(value.inviter.name, 255)) throw authorityUnavailable();
1875
+ return {
1876
+ id: value.id,
1877
+ email: value.email,
1878
+ role: value.role,
1879
+ teamIds: unique(value.teamIds.map(normalizeResponseId), (item) => item),
1880
+ inviter: {
1881
+ membershipId: value.inviter.membershipId,
1882
+ name: value.inviter.name
1883
+ },
1884
+ createdAt: responseDate(value.createdAt),
1885
+ expiresAt: responseDate(value.expiresAt),
1886
+ status: "pending"
1887
+ };
1888
+ }
1889
+ function normalizeOrganizationInvitations(value) {
1890
+ exact$3(value, ["invitations", "nextCursor"]);
1891
+ if (!Array.isArray(value.invitations) || value.invitations.length > 100) throw authorityUnavailable();
1892
+ return {
1893
+ invitations: unique(value.invitations.map(normalizeOrganizationInvitation), (item) => item.id),
1894
+ nextCursor: nullableCursor(value.nextCursor)
1895
+ };
1896
+ }
1897
+ function normalizeReceivedInvitation(value) {
1898
+ exact$3(value, [
1899
+ "expiresAt",
1900
+ "id",
1901
+ "inviterName",
1902
+ "organization",
1903
+ "role",
1904
+ "teams"
1905
+ ]);
1906
+ if (!isId(value.id) || !boundedString(value.inviterName, 255) || !role(value.role) || !Array.isArray(value.teams) || value.teams.length > 100 || !isObject(value.organization)) throw authorityUnavailable();
1907
+ exact$3(value.organization, [
1908
+ "id",
1909
+ "logo",
1910
+ "name",
1911
+ "slug"
1912
+ ]);
1913
+ if (!isId(value.organization.id) || !boundedString(value.organization.name, 255) || !boundedString(value.organization.slug, 255)) throw authorityUnavailable();
1914
+ return {
1915
+ id: value.id,
1916
+ organization: {
1917
+ id: value.organization.id,
1918
+ name: value.organization.name,
1919
+ slug: value.organization.slug,
1920
+ logo: nullableHttpsUrl(value.organization.logo)
1921
+ },
1922
+ role: value.role,
1923
+ teams: unique(value.teams.map((team) => {
1924
+ exact$3(team, ["id", "name"]);
1925
+ if (!isId(team.id) || !boundedString(team.name, 255)) throw authorityUnavailable();
1926
+ return {
1927
+ id: team.id,
1928
+ name: team.name
1036
1929
  };
1037
- return await Promise.race([exchange().finally(() => {
1038
- inFlight = false;
1039
- }), deadline]);
1040
- } catch (error) {
1041
- if (authorityError && error === authorityError) throw authorityError;
1042
- throw authorityUnavailable();
1043
- } finally {
1044
- clearTimeout(timer);
1045
- controller.abort();
1046
- reader?.cancel().catch(() => {});
1047
- }
1048
- } };
1930
+ }), (item) => item.id),
1931
+ inviterName: value.inviterName,
1932
+ expiresAt: responseDate(value.expiresAt)
1933
+ };
1934
+ }
1935
+ function normalizeReceivedInvitations(value) {
1936
+ exact$3(value, ["invitations", "nextCursor"]);
1937
+ if (!Array.isArray(value.invitations) || value.invitations.length > 100) throw authorityUnavailable();
1938
+ return {
1939
+ invitations: unique(value.invitations.map(normalizeReceivedInvitation), (item) => item.id),
1940
+ nextCursor: nullableCursor(value.nextCursor)
1941
+ };
1942
+ }
1943
+ function normalizeInvitationInput(value) {
1944
+ if (!isObject(value) || Object.keys(value).length !== 1 || !isId(value.invitationId)) throw new AuthError("invalid_invitation", 422);
1945
+ return { invitationId: value.invitationId };
1946
+ }
1947
+ function normalizeInvitationAcceptance(value, invitationId) {
1948
+ if (!isObject(value) || !isObject(value.invitation) || !isObject(value.member) || value.invitation.id !== invitationId || value.invitation.status !== "accepted" || !isId(value.invitation.organizationId) || value.member.organizationId !== value.invitation.organizationId) throw authorityUnavailable();
1949
+ return { organizationId: value.invitation.organizationId };
1950
+ }
1951
+ function normalizeWorkspaceSelection(value) {
1952
+ if (!isObject(value)) throw new AuthError("invalid_workspace_selection", 422);
1953
+ const keys = Object.keys(value);
1954
+ if (value.type === "personal" && keys.length === 1 && keys[0] === "type") return { type: "personal" };
1955
+ if (value.type === "organization" && keys.length === 2 && keys.includes("type") && keys.includes("organizationId") && typeof value.organizationId === "string" && id.test(value.organizationId)) return {
1956
+ type: "organization",
1957
+ organizationId: value.organizationId
1958
+ };
1959
+ throw new AuthError("invalid_workspace_selection", 422);
1960
+ }
1961
+ function fromAuthorityError(value, fallbackStatus, retryAfter) {
1962
+ const mapped = mapError(isObject(value) && typeof value.code === "string" ? value.code : void 0, fallbackStatus);
1963
+ return new AuthError(mapped.code, mapped.status, parseRetryAfter(retryAfter));
1964
+ }
1965
+ function fromAccountAuthorityError(value, status, retryAfter) {
1966
+ const code = isObject(value) && typeof value.code === "string" ? value.code : void 0;
1967
+ if (status === 403 && (code === "INVALID_ORIGIN" || code === "MISSING_OR_NULL_ORIGIN")) return new AuthError("request_origin_denied", 403);
1968
+ if (code === "USER_ALREADY_EXISTS_USE_ANOTHER_EMAIL") return new AuthError("account_conflict", 409);
1969
+ if (code === "INVALID_TOKEN") return new AuthError("password_reset_invalid", 422);
1970
+ if (code === "INVALID_PASSWORD" || code === "INVALID_EMAIL_OR_PASSWORD") return new AuthError("invalid_credentials", 401);
1971
+ if (code === "INVALID_EMAIL" || code === "PASSWORD_TOO_SHORT" || code === "PASSWORD_TOO_LONG" || code === "BODY_MUST_BE_AN_OBJECT" || code === "EMAIL_CAN_NOT_BE_UPDATED") return new AuthError("invalid_auth_input", 422);
1972
+ if (status === 401) return new AuthError("authentication_required", 401);
1973
+ if (status === 403) return new AuthError("access_denied", 403);
1974
+ if (status === 409) return new AuthError("state_conflict", 409);
1975
+ if (status === 429) return new AuthError("auth_request_rate_limited", 429, parseRetryAfter(retryAfter));
1976
+ if (status === 400 || status === 422) return new AuthError("invalid_auth_input", 422);
1977
+ return authorityUnavailable();
1978
+ }
1979
+ function fromSocialIdTokenAuthorityError(value, status, retryAfter) {
1980
+ const code = isObject(value) && typeof value.code === "string" ? value.code : void 0;
1981
+ if (code === "INVALID_TOKEN" || code === "FAILED_TO_GET_USER_INFO" || code === "USER_EMAIL_NOT_FOUND") return new AuthError("invalid_credentials", 401);
1982
+ if (code === "OAUTH_LINK_ERROR") return new AuthError("account_conflict", 409);
1983
+ return fromAccountAuthorityError(value, status, retryAfter);
1984
+ }
1985
+ function authorityUnavailable() {
1986
+ return new AuthError("identity_authority_unavailable", 503);
1987
+ }
1988
+ function fromOrganizationListError(error) {
1989
+ if (error instanceof AuthError && error.status === 401) return new AuthError("authentication_required", 401);
1990
+ if (error instanceof AuthError) return error;
1991
+ return authorityUnavailable();
1992
+ }
1993
+ function fromOrganizationReadAuthorityError(value, status) {
1994
+ if (status === 400) return new AuthError("invalid_request", 400);
1995
+ if (status === 401) return new AuthError("authentication_required", 401);
1996
+ if (status === 403) return new AuthError("access_denied", 403);
1997
+ return authorityUnavailable();
1998
+ }
1999
+ function fromOrganizationMutationAuthorityError(value, status, retryAfter) {
2000
+ if (status === 400 || status === 413 || status === 415) return new AuthError("invalid_request", 400);
2001
+ if (status === 409) return new AuthError("state_conflict", 409);
2002
+ if (status === 429) return new AuthError("auth_request_rate_limited", 429, parseRetryAfter(retryAfter));
2003
+ const code = isObject(value) && typeof value.code === "string" ? value.code : void 0;
2004
+ if (status === 403 && code === "REQUEST_ORIGIN_DENIED") return new AuthError("request_origin_denied", 403);
2005
+ return fromOrganizationReadAuthorityError(value, status);
2006
+ }
2007
+ function fromOrganizationInvitationAdministrationError(value, status, retryAfter) {
2008
+ if (status === 422 && isObject(value) && value.code === "RECOVERY_REQUIRED") return new AuthError("invitation_recovery_required", 422);
2009
+ return fromOrganizationMutationAuthorityError(value, status, retryAfter);
2010
+ }
2011
+ function fromOrganizationMembershipRemovalError(value, status, retryAfter) {
2012
+ if (status === 422 && isObject(value) && value.code === "RECOVERY_REQUIRED") return new AuthError("membership_removal_recovery_required", 422);
2013
+ return fromOrganizationMutationAuthorityError(value, status, retryAfter);
2014
+ }
2015
+ function normalizeOrganizationMemberAuthority(value, organizationId, memberId) {
2016
+ exact$3(value, [
2017
+ "organizationId",
2018
+ "actor",
2019
+ "target"
2020
+ ]);
2021
+ if (!isId(value.organizationId) || value.organizationId !== organizationId) throw authorityUnavailable();
2022
+ const actor = normalizeOrganizationAuthorityMemberOutcome(value.actor);
2023
+ const target = normalizeOrganizationAuthorityMemberOutcome(value.target);
2024
+ if (target.memberId !== memberId || actor.manualRole !== "owner" && actor.manualRole !== "admin") throw authorityUnavailable();
2025
+ for (const member of [actor, target]) if (member.manualRole === "member" ? member.role === "owner" : member.role !== member.manualRole) throw authorityUnavailable();
2026
+ if (actor.memberId === target.memberId && (actor.manualRole !== target.manualRole || actor.role !== target.role || actor.authorityRevision !== target.authorityRevision)) throw authorityUnavailable();
2027
+ return {
2028
+ organizationId: value.organizationId,
2029
+ actor,
2030
+ target
2031
+ };
2032
+ }
2033
+ function normalizeOrganizationAuthorityMemberOutcome(value, includesStatus = false) {
2034
+ exact$3(value, [
2035
+ "memberId",
2036
+ "manualRole",
2037
+ "role",
2038
+ "authorityRevision",
2039
+ ...includesStatus ? ["status"] : []
2040
+ ]);
2041
+ if (!isId(value.memberId) || value.manualRole !== "owner" && value.manualRole !== "admin" && value.manualRole !== "member" || value.role !== "owner" && value.role !== "admin" && value.role !== "member") throw authorityUnavailable();
2042
+ return {
2043
+ memberId: value.memberId,
2044
+ manualRole: value.manualRole,
2045
+ role: value.role,
2046
+ authorityRevision: normalizeAuthorityResultRevision(value.authorityRevision)
2047
+ };
2048
+ }
2049
+ function normalizeAuthorityResultRevision(value) {
2050
+ if (!Number.isSafeInteger(value) || value < 0 || value >= Number.MAX_SAFE_INTEGER) throw authorityUnavailable();
2051
+ return value;
2052
+ }
2053
+ function fromInvitationAuthorityError(value, status) {
2054
+ const code = isObject(value) && typeof value.code === "string" ? value.code : void 0;
2055
+ if (status === 401 && code === "UNAUTHORIZED") return new AuthError("authentication_required", 401);
2056
+ if (status === 403 && (code === "INVALID_ORIGIN" || code === "MISSING_OR_NULL_ORIGIN")) return new AuthError("request_origin_denied", 403);
2057
+ if (status === 403 && code === "YOU_ARE_NOT_THE_RECIPIENT_OF_THE_INVITATION") return new AuthError("invitation_recipient_mismatch", 403);
2058
+ if (status === 403 && code === "EMAIL_VERIFICATION_REQUIRED_BEFORE_ACCEPTING_OR_REJECTING_INVITATION") return new AuthError("email_verification_required", 403);
2059
+ if (status === 400 && (code === "INVITATION_NOT_FOUND" || code === "ORGANIZATION_NOT_FOUND" || code === "TEAM_NOT_FOUND")) return new AuthError("invitation_unavailable", 409);
2060
+ return authorityUnavailable();
2061
+ }
2062
+ function fromInvitationError(error) {
2063
+ return error instanceof AuthError ? error : authorityUnavailable();
2064
+ }
2065
+ function mapError(code, status) {
2066
+ if (code === "authentication_required") return {
2067
+ code,
2068
+ status: 401
2069
+ };
2070
+ if (code === "request_origin_denied") return {
2071
+ code,
2072
+ status: 403
2073
+ };
2074
+ if (code === "invalid_workspace_selection") return {
2075
+ code,
2076
+ status: 422
2077
+ };
2078
+ if (code === "organization_context_too_large") return {
2079
+ code,
2080
+ status: 422
2081
+ };
2082
+ if (code === "credential_rate_limited") return {
2083
+ code,
2084
+ status: 429
2085
+ };
2086
+ if (code === "identity_authority_unavailable") return {
2087
+ code,
2088
+ status: 503
2089
+ };
2090
+ if (status === 401 || status === 400) return {
2091
+ code: "invalid_credentials",
2092
+ status: 401
2093
+ };
2094
+ if (status === 403) return {
2095
+ code: "access_denied",
2096
+ status: 403
2097
+ };
2098
+ if (status === 409) return {
2099
+ code: "state_conflict",
2100
+ status: 409
2101
+ };
2102
+ if (status === 422) return {
2103
+ code: "invalid_workspace_selection",
2104
+ status: 422
2105
+ };
2106
+ if (status === 429) return {
2107
+ code: "credential_rate_limited",
2108
+ status: 429
2109
+ };
2110
+ return {
2111
+ code: "identity_authority_unavailable",
2112
+ status: 503
2113
+ };
1049
2114
  }
1050
- //#endregion
1051
- //#region src/provisioning.ts
1052
- const MAX_BYTES = 16 * 1024;
1053
- const compactJwt = /^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/;
1054
- function isCompactCredential(value) {
1055
- return typeof value === "string" && value.length + 7 <= MAX_BYTES && compactJwt.test(value);
2115
+ function parseRetryAfter(value) {
2116
+ if (!value || !/^\d+$/.test(value)) return void 0;
2117
+ const seconds = Number(value);
2118
+ return Number.isSafeInteger(seconds) && seconds >= 1 && seconds <= 3600 ? seconds : void 0;
1056
2119
  }
1057
- function createDriveProvisioningAuth(options) {
1058
- const url = joinURL(normalizeOrigin(options.authOrigin, "authOrigin"), "api/v1/auth/drive-provisioning-credential");
1059
- const fetchImpl = options.fetch ?? globalThis.fetch?.bind(globalThis);
1060
- if (typeof fetchImpl !== "function") throw new TypeError("fetch is required");
1061
- const timeoutMs = normalizeTimeout(options.timeoutMs);
1062
- const now = options.now ?? Date.now;
1063
- let inFlight = false;
1064
- return { async getDriveProvisioningCredential(clientAssertion) {
1065
- if (!isCompactCredential(clientAssertion)) throw new AuthError("invalid_request", 400);
1066
- if (inFlight) throw new AuthError("state_conflict", 409);
1067
- inFlight = true;
1068
- const controller = new AbortController();
1069
- let reader;
1070
- let timer;
1071
- let exchangeStarted = false;
1072
- let authorityError;
1073
- try {
1074
- const startedAt = now();
1075
- if (!Number.isSafeInteger(startedAt) || startedAt < 0 || startedAt > 86399999997e5) throw authorityUnavailable();
1076
- const deadline = new Promise((_, reject) => {
1077
- timer = setTimeout(() => {
1078
- reject(authorityUnavailable());
1079
- controller.abort();
1080
- reader?.cancel().catch(() => {});
1081
- }, timeoutMs);
1082
- });
1083
- const exchange = async () => {
1084
- const response = await fetchImpl(url, {
1085
- method: "POST",
1086
- headers: {
1087
- authorization: `Bearer ${clientAssertion}`,
1088
- accept: "application/json"
1089
- },
1090
- credentials: "omit",
1091
- cache: "no-store",
1092
- redirect: "manual",
1093
- signal: controller.signal
1094
- });
1095
- if (controller.signal.aborted) {
1096
- response.body?.cancel().catch(() => {});
1097
- throw authorityUnavailable();
1098
- }
1099
- if (!response.body) throw authorityUnavailable();
1100
- reader = response.body.getReader();
1101
- const contentType = response.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
1102
- const length = response.headers.get("content-length");
1103
- if (contentType !== "application/json" || length !== null && (!/^\d+$/.test(length) || Number(length) > MAX_BYTES)) throw authorityUnavailable();
1104
- const bytes = new Uint8Array(MAX_BYTES);
1105
- let size = 0;
1106
- while (true) {
1107
- const chunk = await reader.read();
1108
- if (chunk.done) break;
1109
- if (controller.signal.aborted || size + chunk.value.byteLength > MAX_BYTES) throw authorityUnavailable();
1110
- bytes.set(chunk.value, size);
1111
- size += chunk.value.byteLength;
1112
- }
1113
- const value = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(0, size)));
1114
- if (!value || typeof value !== "object" || Array.isArray(value)) throw authorityUnavailable();
1115
- const record = value;
1116
- if (response.status !== 200) {
1117
- if (Object.keys(record).length !== 2 || !("code" in record) || !("message" in record)) throw authorityUnavailable();
1118
- if (response.status === 401 && record.code === "UNAUTHORIZED" && record.message === "The ecosystem client assertion is invalid.") {
1119
- authorityError = new AuthError("authentication_required", 401);
1120
- throw authorityError;
1121
- }
1122
- const retryAfter = response.headers.get("retry-after");
1123
- if (response.status === 429 && record.code === "TOO_MANY_REQUESTS" && record.message === "Ecosystem credential exchanges are temporarily limited." && retryAfter !== null && /^(?:[1-9]|[1-5][0-9]|60)$/.test(retryAfter)) {
1124
- authorityError = new AuthError("auth_request_rate_limited", 429, Number(retryAfter));
1125
- throw authorityError;
1126
- }
1127
- throw authorityUnavailable();
1128
- }
1129
- if (Object.keys(record).length !== 3 || record.tokenType !== "Bearer" || record.expiresIn !== 300 || !isCompactCredential(record.token)) throw authorityUnavailable();
1130
- const expiresAt = new Date(Math.floor(startedAt / 1e3) * 1e3 + 3e5);
1131
- const completedAt = now();
1132
- if (!Number.isSafeInteger(completedAt) || completedAt < 0 || completedAt >= expiresAt.getTime()) throw authorityUnavailable();
1133
- return {
1134
- tokenType: "Bearer",
1135
- token: record.token,
1136
- expiresAt
1137
- };
1138
- };
1139
- exchangeStarted = true;
1140
- return await Promise.race([exchange().finally(() => {
1141
- inFlight = false;
1142
- }), deadline]);
1143
- } catch (error) {
1144
- if (authorityError && error === authorityError) throw authorityError;
1145
- throw authorityUnavailable();
1146
- } finally {
1147
- clearTimeout(timer);
1148
- controller.abort();
1149
- reader?.cancel().catch(() => {});
1150
- if (!exchangeStarted) inFlight = false;
1151
- }
1152
- } };
2120
+ function toDate(value) {
2121
+ const result = value instanceof Date ? value : typeof value === "string" ? new Date(value) : void 0;
2122
+ return result && Number.isFinite(result.getTime()) ? result : void 0;
1153
2123
  }
1154
- //#endregion
1155
- //#region ../../node_modules/.pnpm/destr@2.0.5/node_modules/destr/dist/index.mjs
1156
- const suspectProtoRx = /"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/;
1157
- const suspectConstructorRx = /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;
1158
- const JsonSigRx = /^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/;
1159
- function jsonParseTransform(key, value) {
1160
- if (key === "__proto__" || key === "constructor" && value && typeof value === "object" && "prototype" in value) {
1161
- warnKeyDropped(key);
1162
- return;
1163
- }
1164
- return value;
2124
+ function isId(value) {
2125
+ return typeof value === "string" && id.test(value);
1165
2126
  }
1166
- function warnKeyDropped(key) {
1167
- console.warn(`[destr] Dropping "${key}" key to prevent prototype pollution.`);
2127
+ function exact$3(value, keys) {
2128
+ if (!isObject(value) || Object.keys(value).sort().join(",") !== [...keys].sort().join(",")) throw authorityUnavailable();
1168
2129
  }
1169
- function destr(value, options = {}) {
1170
- if (typeof value !== "string") return value;
1171
- if (value[0] === "\"" && value[value.length - 1] === "\"" && value.indexOf("\\") === -1) return value.slice(1, -1);
1172
- const _value = value.trim();
1173
- if (_value.length <= 9) switch (_value.toLowerCase()) {
1174
- case "true": return true;
1175
- case "false": return false;
1176
- case "undefined": return;
1177
- case "null": return null;
1178
- case "nan": return NaN;
1179
- case "infinity": return Number.POSITIVE_INFINITY;
1180
- case "-infinity": return Number.NEGATIVE_INFINITY;
1181
- }
1182
- if (!JsonSigRx.test(value)) {
1183
- if (options.strict) throw new SyntaxError("[destr] Invalid JSON");
1184
- return value;
1185
- }
1186
- try {
1187
- if (suspectProtoRx.test(value) || suspectConstructorRx.test(value)) {
1188
- if (options.strict) throw new Error("[destr] Possible prototype pollution");
1189
- return JSON.parse(value, jsonParseTransform);
1190
- }
1191
- return JSON.parse(value);
1192
- } catch (error) {
1193
- if (options.strict) throw error;
1194
- return value;
1195
- }
2130
+ function boundedString(value, maximum) {
2131
+ return typeof value === "string" && value.length > 0 && new TextEncoder().encode(value).byteLength <= maximum;
1196
2132
  }
1197
- //#endregion
1198
- //#region ../../node_modules/.pnpm/ofetch@1.5.1/node_modules/ofetch/dist/shared/ofetch.CWycOUEr.mjs
1199
- var FetchError = class extends Error {
1200
- constructor(message, opts) {
1201
- super(message, opts);
1202
- this.name = "FetchError";
1203
- if (opts?.cause && !this.cause) this.cause = opts.cause;
2133
+ function role(value) {
2134
+ return value === "owner" || value === "admin" || value === "member";
2135
+ }
2136
+ function nullableHttpsUrl(value) {
2137
+ if (value === null) return null;
2138
+ if (typeof value !== "string" || value.length > 2048) throw authorityUnavailable();
2139
+ let url;
2140
+ try {
2141
+ url = new URL(value);
2142
+ } catch {
2143
+ throw authorityUnavailable();
1204
2144
  }
1205
- };
1206
- function createFetchError(ctx) {
1207
- const errorMessage = ctx.error?.message || ctx.error?.toString() || "";
1208
- const method = ctx.request?.method || ctx.options?.method || "GET";
1209
- const url = ctx.request?.url || String(ctx.request) || "/";
1210
- const fetchError = new FetchError(`${`[${method}] ${JSON.stringify(url)}`}: ${ctx.response ? `${ctx.response.status} ${ctx.response.statusText}` : "<no response>"}${errorMessage ? ` ${errorMessage}` : ""}`, ctx.error ? { cause: ctx.error } : void 0);
1211
- for (const key of [
1212
- "request",
1213
- "options",
1214
- "response"
1215
- ]) Object.defineProperty(fetchError, key, { get() {
1216
- return ctx[key];
1217
- } });
1218
- for (const [key, refKey] of [
1219
- ["data", "_data"],
1220
- ["status", "status"],
1221
- ["statusCode", "status"],
1222
- ["statusText", "statusText"],
1223
- ["statusMessage", "statusText"]
1224
- ]) Object.defineProperty(fetchError, key, { get() {
1225
- return ctx.response && ctx.response[refKey];
1226
- } });
1227
- return fetchError;
2145
+ if (url.protocol !== "https:" || url.username || url.password || url.toString() !== value) throw authorityUnavailable();
2146
+ return value;
1228
2147
  }
1229
- const payloadMethods = new Set(Object.freeze([
1230
- "PATCH",
1231
- "POST",
1232
- "PUT",
1233
- "DELETE"
1234
- ]));
1235
- function isPayloadMethod(method = "GET") {
1236
- return payloadMethods.has(method.toUpperCase());
2148
+ function responseDate(value) {
2149
+ if (typeof value !== "string") throw authorityUnavailable();
2150
+ const date = new Date(value);
2151
+ if (!Number.isFinite(date.getTime()) || date.toISOString() !== value) throw authorityUnavailable();
2152
+ return date;
1237
2153
  }
1238
- function isJSONSerializable(value) {
1239
- if (value === void 0) return false;
1240
- const t = typeof value;
1241
- if (t === "string" || t === "number" || t === "boolean" || t === null) return true;
1242
- if (t !== "object") return false;
1243
- if (Array.isArray(value)) return true;
1244
- if (value.buffer) return false;
1245
- if (value instanceof FormData || value instanceof URLSearchParams) return false;
1246
- return value.constructor && value.constructor.name === "Object" || typeof value.toJSON === "function";
2154
+ function nullableCursor(value) {
2155
+ if (value === null) return null;
2156
+ if (typeof value !== "string" || value.length < 1 || value.length > 820 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(value)) throw authorityUnavailable();
2157
+ return value;
1247
2158
  }
1248
- const textTypes = new Set([
1249
- "image/svg",
1250
- "application/xml",
1251
- "application/xhtml",
1252
- "application/html"
1253
- ]);
1254
- const JSON_RE = /^application\/(?:[\w!#$%&*.^`~-]*\+)?json(;.+)?$/i;
1255
- function detectResponseType(_contentType = "") {
1256
- if (!_contentType) return "json";
1257
- const contentType = _contentType.split(";").shift() || "";
1258
- if (JSON_RE.test(contentType)) return "json";
1259
- if (contentType === "text/event-stream") return "stream";
1260
- if (textTypes.has(contentType) || contentType.startsWith("text/")) return "text";
1261
- return "blob";
2159
+ function normalizeResponseId(value) {
2160
+ if (!isId(value)) throw authorityUnavailable();
2161
+ return value;
1262
2162
  }
1263
- function resolveFetchOptions(request, input, defaults, Headers) {
1264
- const headers = mergeHeaders(input?.headers ?? request?.headers, defaults?.headers, Headers);
1265
- let query;
1266
- if (defaults?.query || defaults?.params || input?.params || input?.query) query = {
1267
- ...defaults?.params,
1268
- ...defaults?.query,
1269
- ...input?.params,
1270
- ...input?.query
1271
- };
2163
+ function unique(items, key) {
2164
+ if (new Set(items.map(key)).size !== items.length) throw authorityUnavailable();
2165
+ return items;
2166
+ }
2167
+ function isObject(value) {
2168
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2169
+ }
2170
+ //#endregion
2171
+ //#region src/http.ts
2172
+ const MAX_RESPONSE_BYTES = 64 * 1024;
2173
+ async function requestJson(url, options) {
2174
+ return (await requestJsonResponse(url, options)).value;
2175
+ }
2176
+ async function requestJsonResponse(url, options) {
2177
+ let response;
2178
+ try {
2179
+ response = await createFetch({ fetch: options.fetch }).raw(url, {
2180
+ method: options.method,
2181
+ headers: options.headers,
2182
+ body: options.body,
2183
+ credentials: options.credentials ?? "include",
2184
+ retry: 0,
2185
+ timeout: options.timeoutMs,
2186
+ redirect: "manual",
2187
+ signal: options.signal,
2188
+ responseType: "stream",
2189
+ ignoreResponseError: true
2190
+ });
2191
+ } catch {
2192
+ throw authorityUnavailable();
2193
+ }
2194
+ const contentType = response.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
2195
+ if (response.status >= 300 || response.status < 200 || contentType !== "application/json") {
2196
+ const body = contentType === "application/json" ? await readJson(response, options.maxResponseBytes) : void 0;
2197
+ await response.body?.cancel();
2198
+ throw (options.mapError ?? fromAuthorityError)(body, response.status, response.headers.get("retry-after"));
2199
+ }
1272
2200
  return {
1273
- ...defaults,
1274
- ...input,
1275
- query,
1276
- params: query,
1277
- headers
2201
+ value: await readJson(response, options.maxResponseBytes),
2202
+ headers: response.headers
1278
2203
  };
1279
2204
  }
1280
- function mergeHeaders(input, defaults, Headers) {
1281
- if (!defaults) return new Headers(input);
1282
- const headers = new Headers(defaults);
1283
- if (input) for (const [key, value] of Symbol.iterator in input || Array.isArray(input) ? input : new Headers(input)) headers.set(key, value);
1284
- return headers;
1285
- }
1286
- async function callHooks(context, hooks) {
1287
- if (hooks) if (Array.isArray(hooks)) for (const hook of hooks) await hook(context);
1288
- else await hooks(context);
2205
+ async function readJson(response, maximum = MAX_RESPONSE_BYTES) {
2206
+ const length = response.headers.get("content-length");
2207
+ if (length && (!/^\d+$/.test(length) || Number(length) > maximum)) {
2208
+ await response.body?.cancel();
2209
+ throw authorityUnavailable();
2210
+ }
2211
+ if (!response.body) throw authorityUnavailable();
2212
+ const reader = response.body.getReader();
2213
+ const chunks = [];
2214
+ let size = 0;
2215
+ try {
2216
+ while (true) {
2217
+ const { done, value } = await reader.read();
2218
+ if (done) break;
2219
+ size += value.byteLength;
2220
+ if (size > maximum) throw authorityUnavailable();
2221
+ chunks.push(value);
2222
+ }
2223
+ } catch (error) {
2224
+ await reader.cancel();
2225
+ throw error;
2226
+ } finally {
2227
+ reader.releaseLock();
2228
+ }
2229
+ const bytes = new Uint8Array(size);
2230
+ let offset = 0;
2231
+ for (const chunk of chunks) {
2232
+ bytes.set(chunk, offset);
2233
+ offset += chunk.byteLength;
2234
+ }
2235
+ try {
2236
+ return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
2237
+ } catch {
2238
+ throw authorityUnavailable();
2239
+ }
1289
2240
  }
1290
- const retryStatusCodes = new Set([
1291
- 408,
1292
- 409,
1293
- 425,
1294
- 429,
1295
- 500,
1296
- 502,
1297
- 503,
1298
- 504
1299
- ]);
1300
- const nullBodyResponses = new Set([
1301
- 101,
1302
- 204,
1303
- 205,
1304
- 304
1305
- ]);
1306
- function createFetch(globalOptions = {}) {
1307
- const { fetch = globalThis.fetch, Headers = globalThis.Headers, AbortController = globalThis.AbortController } = globalOptions;
1308
- async function onError(context) {
1309
- const isAbort = context.error && context.error.name === "AbortError" && !context.options.timeout || false;
1310
- if (context.options.retry !== false && !isAbort) {
1311
- let retries;
1312
- if (typeof context.options.retry === "number") retries = context.options.retry;
1313
- else retries = isPayloadMethod(context.options.method) ? 0 : 1;
1314
- const responseCode = context.response && context.response.status || 500;
1315
- if (retries > 0 && (Array.isArray(context.options.retryStatusCodes) ? context.options.retryStatusCodes.includes(responseCode) : retryStatusCodes.has(responseCode))) {
1316
- const retryDelay = typeof context.options.retryDelay === "function" ? context.options.retryDelay(context) : context.options.retryDelay || 0;
1317
- if (retryDelay > 0) await new Promise((resolve) => setTimeout(resolve, retryDelay));
1318
- return $fetchRaw(context.request, {
1319
- ...context.options,
1320
- retry: retries - 1
1321
- });
2241
+ //#endregion
2242
+ //#region src/user-api/verifier.ts
2243
+ const ID = /^[A-Za-z0-9_-]{1,128}$(?![\s\S])/;
2244
+ const KID = /^[A-Za-z0-9_-]{43}$(?![\s\S])/;
2245
+ const PROFILE = "finueva-user-api+jwt";
2246
+ const CACHE_MS = 3e5;
2247
+ const REFRESH_COOLDOWN_MS = 3e4;
2248
+ const TIMEOUT_MS = 2e3;
2249
+ const invalid = () => new AuthError("authentication_required", 401);
2250
+ const unavailable = () => new AuthError("identity_authority_unavailable", 503);
2251
+ function record(value) {
2252
+ return value !== null && typeof value === "object" && !Array.isArray(value);
2253
+ }
2254
+ function exactKeys(value, keys) {
2255
+ return Object.keys(value).sort().join(",") === keys.sort().join(",");
2256
+ }
2257
+ function createUserApiVerifier(options) {
2258
+ const { issuer, audience, applicationId, environment } = options;
2259
+ if (!issuer || !audience || issuer.length > 2048 || audience.length > 2048 || !ID.test(applicationId) || ![
2260
+ "local",
2261
+ "development",
2262
+ "staging",
2263
+ "production"
2264
+ ].includes(environment)) throw new TypeError("User API verifier configuration is invalid");
2265
+ const url = new URL(options.jwksUrl);
2266
+ const local = url.hostname === "localhost" || url.hostname.endsWith(".localhost");
2267
+ if (url.protocol !== "https:" && !(environment === "local" && local && url.protocol === "http:") || url.username || url.password || url.search || url.hash) throw new TypeError("User API JWKS URL is invalid");
2268
+ const jwksUrl = url.href;
2269
+ const fetchImpl = options.fetch ?? globalThis.fetch;
2270
+ const now = options.now ?? Date.now;
2271
+ let cached;
2272
+ let pending;
2273
+ let nextRefreshAt = -Infinity;
2274
+ async function loadKeys() {
2275
+ const controller = new AbortController();
2276
+ let timer;
2277
+ const deadline = new Promise((_, reject) => {
2278
+ timer = setTimeout(() => {
2279
+ controller.abort();
2280
+ reject(unavailable());
2281
+ }, TIMEOUT_MS);
2282
+ });
2283
+ const started = now();
2284
+ try {
2285
+ const value = await Promise.race([requestJson(jwksUrl, {
2286
+ fetch: fetchImpl,
2287
+ timeoutMs: TIMEOUT_MS,
2288
+ method: "GET",
2289
+ credentials: "omit",
2290
+ signal: controller.signal,
2291
+ maxResponseBytes: 64 * 1024
2292
+ }), deadline]);
2293
+ if (!record(value) || !exactKeys(value, ["keys"]) || !Array.isArray(value.keys) || value.keys.length < 1 || value.keys.length > 20) throw unavailable();
2294
+ const keys = new Map();
2295
+ for (const entry of value.keys) {
2296
+ if (!record(entry) || !exactKeys(entry, [
2297
+ "kty",
2298
+ "crv",
2299
+ "x",
2300
+ "kid",
2301
+ "alg",
2302
+ "use"
2303
+ ]) || entry.kty !== "OKP" || entry.crv !== "Ed25519" || entry.alg !== "EdDSA" || entry.use !== "sig" || typeof entry.x !== "string" || !KID.test(entry.x) || typeof entry.kid !== "string" || !KID.test(entry.kid) || keys.has(entry.kid)) throw unavailable();
2304
+ const jwk = {
2305
+ kty: "OKP",
2306
+ crv: "Ed25519",
2307
+ x: entry.x
2308
+ };
2309
+ if (await calculateJwkThumbprint(jwk) !== entry.kid) throw unavailable();
2310
+ keys.set(entry.kid, await importJWK(jwk, "EdDSA"));
1322
2311
  }
2312
+ if (controller.signal.aborted || now() < started || now() >= started + CACHE_MS) throw unavailable();
2313
+ cached = {
2314
+ keys,
2315
+ loadedAt: started,
2316
+ expiresAt: started + CACHE_MS
2317
+ };
2318
+ } catch {
2319
+ throw unavailable();
2320
+ } finally {
2321
+ clearTimeout(timer);
1323
2322
  }
1324
- const error = createFetchError(context);
1325
- if (Error.captureStackTrace) Error.captureStackTrace(error, $fetchRaw);
1326
- throw error;
1327
2323
  }
1328
- const $fetchRaw = async function $fetchRaw2(_request, _options = {}) {
1329
- const context = {
1330
- request: _request,
1331
- options: resolveFetchOptions(_request, _options, globalOptions.defaults, Headers),
1332
- response: void 0,
1333
- error: void 0
1334
- };
1335
- if (context.options.method) context.options.method = context.options.method.toUpperCase();
1336
- if (context.options.onRequest) {
1337
- await callHooks(context, context.options.onRequest);
1338
- if (!(context.options.headers instanceof Headers)) context.options.headers = new Headers(context.options.headers || {});
2324
+ async function keyFor(kid) {
2325
+ const time = now();
2326
+ const known = cached && time >= cached.loadedAt && time < cached.expiresAt ? cached?.keys.get(kid) : void 0;
2327
+ if (known) return known;
2328
+ if (pending) await pending;
2329
+ else if (time >= nextRefreshAt) {
2330
+ nextRefreshAt = time + REFRESH_COOLDOWN_MS;
2331
+ const request = loadKeys().finally(() => {
2332
+ if (pending === request) pending = void 0;
2333
+ });
2334
+ pending = request;
2335
+ await request;
1339
2336
  }
1340
- if (typeof context.request === "string") {
1341
- if (context.options.baseURL) context.request = withBase(context.request, context.options.baseURL);
1342
- if (context.options.query) {
1343
- context.request = withQuery(context.request, context.options.query);
1344
- delete context.options.query;
1345
- }
1346
- if ("query" in context.options) delete context.options.query;
1347
- if ("params" in context.options) delete context.options.params;
2337
+ const current = now();
2338
+ if (!cached || current < cached.loadedAt || current >= cached.expiresAt) throw unavailable();
2339
+ const key = cached.keys.get(kid);
2340
+ if (!key) throw invalid();
2341
+ return key;
2342
+ }
2343
+ return { async verify(token) {
2344
+ if (typeof token !== "string" || token.length + 7 > 16 * 1024 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(token)) throw invalid();
2345
+ let kid;
2346
+ try {
2347
+ const header = decodeProtectedHeader(token);
2348
+ if (!exactKeys(header, [
2349
+ "alg",
2350
+ "typ",
2351
+ "kid"
2352
+ ]) || header.alg !== "EdDSA" || header.typ !== PROFILE || typeof header.kid !== "string" || !KID.test(header.kid)) throw invalid();
2353
+ kid = header.kid;
2354
+ } catch {
2355
+ throw invalid();
1348
2356
  }
1349
- if (context.options.body && isPayloadMethod(context.options.method)) {
1350
- if (isJSONSerializable(context.options.body)) {
1351
- const contentType = context.options.headers.get("content-type");
1352
- if (typeof context.options.body !== "string") context.options.body = contentType === "application/x-www-form-urlencoded" ? new URLSearchParams(context.options.body).toString() : JSON.stringify(context.options.body);
1353
- if (!contentType) context.options.headers.set("content-type", "application/json");
1354
- if (!context.options.headers.has("accept")) context.options.headers.set("accept", "application/json");
1355
- } else if ("pipeTo" in context.options.body && typeof context.options.body.pipeTo === "function" || typeof context.options.body.pipe === "function") {
1356
- if (!("duplex" in context.options)) context.options.duplex = "half";
1357
- }
2357
+ let identity;
2358
+ try {
2359
+ const payload = decodeJwt(token);
2360
+ const time = Math.floor(now() / 1e3);
2361
+ if (!exactKeys(payload, [
2362
+ "iss",
2363
+ "aud",
2364
+ "sub",
2365
+ "sid",
2366
+ "iat",
2367
+ "exp",
2368
+ "ver",
2369
+ "principal_type",
2370
+ "scope",
2371
+ "app",
2372
+ "environment",
2373
+ "user"
2374
+ ]) || payload.iss !== issuer || payload.aud !== audience || payload.app !== applicationId || payload.environment !== environment || payload.ver !== 1 || payload.principal_type !== "user" || payload.scope !== "user:api" || typeof payload.sub !== "string" || !ID.test(payload.sub) || typeof payload.sid !== "string" || !ID.test(payload.sid) || !Number.isSafeInteger(payload.iat) || !Number.isSafeInteger(payload.exp) || payload.iat < 0 || payload.iat > time || payload.exp <= time || payload.exp <= payload.iat || payload.exp - payload.iat > 840) throw invalid();
2375
+ const user = payload.user;
2376
+ if (!record(user) || !exactKeys(user, [
2377
+ "name",
2378
+ "email",
2379
+ "emailVerified",
2380
+ "image"
2381
+ ]) || typeof user.name !== "string" || user.name.length > 200 || typeof user.email !== "string" || user.email.length < 1 || user.email.length > 320 || typeof user.emailVerified !== "boolean" || !(user.image === null || typeof user.image === "string" && user.image.length <= 2048)) throw invalid();
2382
+ identity = {
2383
+ userId: payload.sub,
2384
+ sessionId: payload.sid,
2385
+ applicationId,
2386
+ issuedAt: new Date(payload.iat * 1e3),
2387
+ expiresAt: new Date(payload.exp * 1e3),
2388
+ user: {
2389
+ id: payload.sub,
2390
+ name: user.name,
2391
+ email: user.email,
2392
+ emailVerified: user.emailVerified,
2393
+ image: user.image
2394
+ }
2395
+ };
2396
+ } catch {
2397
+ throw invalid();
1358
2398
  }
1359
- let abortTimeout;
1360
- if (!context.options.signal && context.options.timeout) {
1361
- const controller = new AbortController();
1362
- abortTimeout = setTimeout(() => {
1363
- const error = new Error("[TimeoutError]: The operation was aborted due to timeout");
1364
- error.name = "TimeoutError";
1365
- error.code = 23;
1366
- controller.abort(error);
1367
- }, context.options.timeout);
1368
- context.options.signal = controller.signal;
2399
+ const key = await keyFor(kid);
2400
+ try {
2401
+ await jwtVerify(token, key, {
2402
+ algorithms: ["EdDSA"],
2403
+ issuer,
2404
+ audience,
2405
+ typ: PROFILE,
2406
+ currentDate: new Date(now()),
2407
+ clockTolerance: 0,
2408
+ requiredClaims: [
2409
+ "iss",
2410
+ "aud",
2411
+ "sub",
2412
+ "sid",
2413
+ "iat",
2414
+ "exp"
2415
+ ]
2416
+ });
2417
+ } catch {
2418
+ throw invalid();
1369
2419
  }
2420
+ return identity;
2421
+ } };
2422
+ }
2423
+ //#endregion
2424
+ //#region src/identity-resolution.ts
2425
+ const emailPattern$1 = /^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9-]*\.)+[A-Za-z]{2,}$(?![\s\S])/;
2426
+ function exact$2(value, keys) {
2427
+ return value !== null && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
2428
+ }
2429
+ function createIdentityResolverAuth(options) {
2430
+ const url = joinURL(normalizeOrigin(options.authOrigin, "authOrigin"), "api/v1/auth/identities/resolve");
2431
+ const fetchImpl = options.fetch ?? globalThis.fetch?.bind(globalThis);
2432
+ if (typeof fetchImpl !== "function") throw new TypeError("fetch is required");
2433
+ const timeoutMs = normalizeTimeout(options.timeoutMs);
2434
+ let inFlight = false;
2435
+ return { async resolveIdentity(input, clientAssertion) {
2436
+ if (!exact$2(input, ["identifier"]) || typeof input.identifier !== "string" || input.identifier.length > 324) throw new AuthError("invalid_request", 400);
2437
+ const identifier = input.identifier.trim().toLowerCase();
2438
+ if (!(identifier.length <= 320 && emailPattern$1.test(identifier)) && !/^[a-z0-9_.]{3,30}$(?![\s\S])/.test(identifier)) throw new AuthError("invalid_request", 400);
2439
+ if (typeof clientAssertion !== "string" || clientAssertion.length + 7 > 16 * 1024 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$(?![\s\S])/.test(clientAssertion)) throw new AuthError("invalid_request", 400);
2440
+ if (inFlight) throw new AuthError("state_conflict", 409);
2441
+ inFlight = true;
2442
+ const controller = new AbortController();
2443
+ let reader;
2444
+ let timer;
2445
+ let mappedError;
1370
2446
  try {
1371
- context.response = await fetch(context.request, context.options);
2447
+ const deadline = new Promise((_, reject) => {
2448
+ timer = setTimeout(() => {
2449
+ reject(authorityUnavailable());
2450
+ controller.abort();
2451
+ reader?.cancel().catch(() => {});
2452
+ }, timeoutMs);
2453
+ });
2454
+ const exchange = async () => {
2455
+ const response = await fetchImpl(url, {
2456
+ method: "POST",
2457
+ headers: {
2458
+ authorization: `Bearer ${clientAssertion}`,
2459
+ accept: "application/json",
2460
+ "content-type": "application/json"
2461
+ },
2462
+ body: JSON.stringify({ identifier }),
2463
+ credentials: "omit",
2464
+ cache: "no-store",
2465
+ redirect: "manual",
2466
+ signal: controller.signal
2467
+ });
2468
+ if (controller.signal.aborted) {
2469
+ response.body?.cancel().catch(() => {});
2470
+ throw authorityUnavailable();
2471
+ }
2472
+ if (!response.body) throw authorityUnavailable();
2473
+ reader = response.body.getReader();
2474
+ const length = response.headers.get("content-length");
2475
+ if (response.redirected || response.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase() !== "application/json" || length !== null && (!/^\d+$/.test(length) || Number(length) > 1024)) throw authorityUnavailable();
2476
+ const bytes = new Uint8Array(1024);
2477
+ let size = 0;
2478
+ while (true) {
2479
+ const chunk = await reader.read();
2480
+ if (controller.signal.aborted) throw authorityUnavailable();
2481
+ if (chunk.done) break;
2482
+ if (size + chunk.value.byteLength > bytes.length) throw authorityUnavailable();
2483
+ bytes.set(chunk.value, size);
2484
+ size += chunk.value.byteLength;
2485
+ }
2486
+ const value = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(0, size)));
2487
+ if (response.status !== 200) {
2488
+ if (!exact$2(value, ["code", "message"])) throw authorityUnavailable();
2489
+ if (response.status === 401 && value.code === "UNAUTHORIZED" && value.message === "The identity resolution assertion is invalid.") mappedError = new AuthError("authentication_required", 401);
2490
+ if (response.status === 429 && value.code === "TOO_MANY_REQUESTS" && value.message === "Identity resolution requests are temporarily limited.") {
2491
+ const retryAfter = response.headers.get("retry-after");
2492
+ if (retryAfter === null || !/^(?:[1-9]|[1-5][0-9]|60)$/.test(retryAfter)) throw authorityUnavailable();
2493
+ mappedError = new AuthError("auth_request_rate_limited", 429, Number(retryAfter));
2494
+ }
2495
+ throw mappedError ?? authorityUnavailable();
2496
+ }
2497
+ if (!exact$2(value, ["identity"])) throw authorityUnavailable();
2498
+ if (value.identity === null) return null;
2499
+ if (!exact$2(value.identity, ["userId"]) || typeof value.identity.userId !== "string" || !/^[A-Za-z0-9_-]{1,128}$(?![\s\S])/.test(value.identity.userId)) throw authorityUnavailable();
2500
+ return { userId: value.identity.userId };
2501
+ };
2502
+ return await Promise.race([exchange().finally(() => {
2503
+ inFlight = false;
2504
+ }), deadline]);
1372
2505
  } catch (error) {
1373
- context.error = error;
1374
- if (context.options.onRequestError) await callHooks(context, context.options.onRequestError);
1375
- return await onError(context);
2506
+ if (mappedError && mappedError === error) throw mappedError;
2507
+ throw authorityUnavailable();
1376
2508
  } finally {
1377
- if (abortTimeout) clearTimeout(abortTimeout);
2509
+ clearTimeout(timer);
2510
+ controller.abort();
2511
+ reader?.cancel().catch(() => {});
1378
2512
  }
1379
- if ((context.response.body || context.response._bodyInit) && !nullBodyResponses.has(context.response.status) && context.options.method !== "HEAD") {
1380
- const responseType = (context.options.parseResponse ? "json" : context.options.responseType) || detectResponseType(context.response.headers.get("content-type") || "");
1381
- switch (responseType) {
1382
- case "json": {
1383
- const data = await context.response.text();
1384
- const parseFunction = context.options.parseResponse || destr;
1385
- context.response._data = parseFunction(data);
1386
- break;
2513
+ } };
2514
+ }
2515
+ //#endregion
2516
+ //#region src/membership-resolution.ts
2517
+ const idPattern = /^[A-Za-z0-9_-]{1,128}$(?![\s\S])/;
2518
+ const isoPattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?Z$(?![\s\S])/;
2519
+ const roles = [
2520
+ "admin",
2521
+ "member",
2522
+ "owner"
2523
+ ];
2524
+ const membershipKeys = [
2525
+ "checkedAt",
2526
+ "manualRole",
2527
+ "memberCount",
2528
+ "memberId",
2529
+ "organizationId",
2530
+ "owner",
2531
+ "role",
2532
+ "userId"
2533
+ ];
2534
+ function exact$1(value, keys) {
2535
+ return value !== null && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
2536
+ }
2537
+ function createMembershipResolverAuth(options) {
2538
+ const url = joinURL(normalizeOrigin(options.authOrigin, "authOrigin"), "api/v1/auth/memberships/resolve");
2539
+ const fetchImpl = options.fetch ?? globalThis.fetch?.bind(globalThis);
2540
+ if (typeof fetchImpl !== "function") throw new TypeError("fetch is required");
2541
+ const timeoutMs = normalizeTimeout(options.timeoutMs);
2542
+ let inFlight = false;
2543
+ return { async resolveMembership(input, clientAssertion) {
2544
+ if (!exact$1(input, ["organizationId", "userId"]) || typeof input.organizationId !== "string" || typeof input.userId !== "string" || !idPattern.test(input.organizationId) || !idPattern.test(input.userId)) throw new AuthError("invalid_request", 400);
2545
+ if (typeof clientAssertion !== "string" || clientAssertion.length + 7 > 16 * 1024 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$(?![\s\S])/.test(clientAssertion)) throw new AuthError("invalid_request", 400);
2546
+ if (inFlight) throw new AuthError("state_conflict", 409);
2547
+ inFlight = true;
2548
+ const organizationId = input.organizationId;
2549
+ const userId = input.userId;
2550
+ const controller = new AbortController();
2551
+ let reader;
2552
+ let timer;
2553
+ let mappedError;
2554
+ try {
2555
+ const deadline = new Promise((_, reject) => {
2556
+ timer = setTimeout(() => {
2557
+ reject(authorityUnavailable());
2558
+ controller.abort();
2559
+ reader?.cancel().catch(() => {});
2560
+ }, timeoutMs);
2561
+ });
2562
+ const exchange = async () => {
2563
+ const response = await fetchImpl(url, {
2564
+ method: "POST",
2565
+ headers: {
2566
+ authorization: `Bearer ${clientAssertion}`,
2567
+ accept: "application/json",
2568
+ "content-type": "application/json"
2569
+ },
2570
+ body: JSON.stringify({
2571
+ organizationId,
2572
+ userId
2573
+ }),
2574
+ credentials: "omit",
2575
+ cache: "no-store",
2576
+ redirect: "manual",
2577
+ signal: controller.signal
2578
+ });
2579
+ if (controller.signal.aborted) {
2580
+ response.body?.cancel().catch(() => {});
2581
+ throw authorityUnavailable();
1387
2582
  }
1388
- case "stream":
1389
- context.response._data = context.response.body || context.response._bodyInit;
1390
- break;
1391
- default: context.response._data = await context.response[responseType]();
1392
- }
2583
+ if (!response.body) throw authorityUnavailable();
2584
+ reader = response.body.getReader();
2585
+ const length = response.headers.get("content-length");
2586
+ if (response.redirected || response.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase() !== "application/json" || length !== null && (!/^\d+$/.test(length) || Number(length) > 1024)) throw authorityUnavailable();
2587
+ const bytes = new Uint8Array(1024);
2588
+ let size = 0;
2589
+ while (true) {
2590
+ const chunk = await reader.read();
2591
+ if (controller.signal.aborted) throw authorityUnavailable();
2592
+ if (chunk.done) break;
2593
+ if (size + chunk.value.byteLength > bytes.length) throw authorityUnavailable();
2594
+ bytes.set(chunk.value, size);
2595
+ size += chunk.value.byteLength;
2596
+ }
2597
+ const value = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(0, size)));
2598
+ if (response.status !== 200) {
2599
+ if (!exact$1(value, ["code", "message"])) throw authorityUnavailable();
2600
+ if (response.status === 401 && value.code === "UNAUTHORIZED" && value.message === "The membership resolution assertion is invalid.") mappedError = new AuthError("authentication_required", 401);
2601
+ if (response.status === 429 && value.code === "TOO_MANY_REQUESTS" && value.message === "Membership resolution requests are temporarily limited.") {
2602
+ const retryAfter = response.headers.get("retry-after");
2603
+ if (retryAfter === null || !/^(?:[1-9]|[1-5][0-9]|60)$/.test(retryAfter)) throw authorityUnavailable();
2604
+ mappedError = new AuthError("auth_request_rate_limited", 429, Number(retryAfter));
2605
+ }
2606
+ throw mappedError ?? authorityUnavailable();
2607
+ }
2608
+ if (!exact$1(value, ["membership"])) throw authorityUnavailable();
2609
+ if (value.membership === null) return null;
2610
+ const membership = value.membership;
2611
+ if (!exact$1(membership, membershipKeys) || typeof membership.checkedAt !== "string" || !isoPattern.test(membership.checkedAt) || Number.isNaN(Date.parse(membership.checkedAt)) || typeof membership.manualRole !== "string" || !roles.includes(membership.manualRole) || typeof membership.role !== "string" || !roles.includes(membership.role) || typeof membership.memberCount !== "number" || !Number.isSafeInteger(membership.memberCount) || membership.memberCount < 0 || typeof membership.memberId !== "string" || !idPattern.test(membership.memberId) || typeof membership.owner !== "boolean" || membership.organizationId !== organizationId || membership.userId !== userId) throw authorityUnavailable();
2612
+ return {
2613
+ checkedAt: membership.checkedAt,
2614
+ manualRole: membership.manualRole,
2615
+ memberCount: membership.memberCount,
2616
+ memberId: membership.memberId,
2617
+ organizationId,
2618
+ owner: membership.owner,
2619
+ role: membership.role,
2620
+ userId
2621
+ };
2622
+ };
2623
+ return await Promise.race([exchange().finally(() => {
2624
+ inFlight = false;
2625
+ }), deadline]);
2626
+ } catch (error) {
2627
+ if (mappedError && mappedError === error) throw mappedError;
2628
+ throw authorityUnavailable();
2629
+ } finally {
2630
+ clearTimeout(timer);
2631
+ controller.abort();
2632
+ reader?.cancel().catch(() => {});
1393
2633
  }
1394
- if (context.options.onResponse) await callHooks(context, context.options.onResponse);
1395
- if (!context.options.ignoreResponseError && context.response.status >= 400 && context.response.status < 600) {
1396
- if (context.options.onResponseError) await callHooks(context, context.options.onResponseError);
1397
- return await onError(context);
2634
+ } };
2635
+ }
2636
+ //#endregion
2637
+ //#region src/drive-recipients.ts
2638
+ const encoder = new TextEncoder();
2639
+ const emailPattern = /^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9-]*\.)+[A-Za-z]{2,}$/;
2640
+ function validEmail(value) {
2641
+ return typeof value === "string" && encoder.encode(value).byteLength <= 320 && emailPattern.test(value);
2642
+ }
2643
+ function exact(value, keys) {
2644
+ return value !== null && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
2645
+ }
2646
+ const failures = {
2647
+ 400: [
2648
+ "BAD_REQUEST",
2649
+ "The recipient request is invalid.",
2650
+ "invalid_request"
2651
+ ],
2652
+ 401: [
2653
+ "UNAUTHORIZED",
2654
+ "The recipient service assertion is invalid.",
2655
+ "authentication_required"
2656
+ ],
2657
+ 404: [
2658
+ "NOT_FOUND",
2659
+ "The recipient is unavailable.",
2660
+ "recipient_unavailable"
2661
+ ],
2662
+ 405: [
2663
+ "METHOD_NOT_ALLOWED",
2664
+ "METHOD_NOT_ALLOWED",
2665
+ "invalid_request"
2666
+ ],
2667
+ 413: [
2668
+ "REQUEST_TOO_LONG",
2669
+ "The recipient request is too large.",
2670
+ "invalid_request"
2671
+ ],
2672
+ 429: [
2673
+ "TOO_MANY_REQUESTS",
2674
+ "Recipient requests are temporarily limited.",
2675
+ "auth_request_rate_limited"
2676
+ ],
2677
+ 503: [
2678
+ "SERVICE_UNAVAILABLE",
2679
+ "Recipient resolution is temporarily unavailable.",
2680
+ "identity_authority_unavailable"
2681
+ ]
2682
+ };
2683
+ function createDriveRecipientAuth(options) {
2684
+ const url = joinURL(normalizeOrigin(options.authOrigin, "authOrigin"), "api/v1/auth/drive-share-recipients/resolve");
2685
+ const fetchImpl = options.fetch ?? globalThis.fetch?.bind(globalThis);
2686
+ if (typeof fetchImpl !== "function") throw new TypeError("fetch is required");
2687
+ const timeoutMs = normalizeTimeout(options.timeoutMs);
2688
+ let inFlight = false;
2689
+ return { async resolveRecipient(input, clientAssertion) {
2690
+ let body;
2691
+ let email;
2692
+ try {
2693
+ if (!exact(input, ["email"]) || typeof input.email !== "string") throw new Error();
2694
+ email = input.email.trim().toLowerCase();
2695
+ if (!validEmail(email)) throw new Error();
2696
+ body = JSON.stringify({ email });
2697
+ } catch {
2698
+ throw new AuthError("invalid_request", 400);
1398
2699
  }
1399
- return context.response;
1400
- };
1401
- const $fetch = async function $fetch2(request, options) {
1402
- return (await $fetchRaw(request, options))._data;
1403
- };
1404
- $fetch.raw = $fetchRaw;
1405
- $fetch.native = (...args) => fetch(...args);
1406
- $fetch.create = (defaultOptions = {}, customGlobalOptions = {}) => createFetch({
1407
- ...globalOptions,
1408
- ...customGlobalOptions,
1409
- defaults: {
1410
- ...globalOptions.defaults,
1411
- ...customGlobalOptions.defaults,
1412
- ...defaultOptions
2700
+ if (encoder.encode(body).byteLength > 1024) throw new AuthError("invalid_request", 413);
2701
+ if (typeof clientAssertion !== "string" || clientAssertion.length + 7 > 16 * 1024 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$(?![\s\S])/.test(clientAssertion)) throw new AuthError("invalid_request", 400);
2702
+ if (inFlight) throw new AuthError("state_conflict", 409);
2703
+ inFlight = true;
2704
+ const controller = new AbortController();
2705
+ let reader;
2706
+ let timer;
2707
+ let authorityError;
2708
+ try {
2709
+ const deadline = new Promise((_, reject) => {
2710
+ timer = setTimeout(() => {
2711
+ reject(authorityUnavailable());
2712
+ controller.abort();
2713
+ reader?.cancel().catch(() => {});
2714
+ }, timeoutMs);
2715
+ });
2716
+ const exchange = async () => {
2717
+ const response = await fetchImpl(url, {
2718
+ method: "POST",
2719
+ headers: {
2720
+ authorization: `Bearer ${clientAssertion}`,
2721
+ accept: "application/json",
2722
+ "content-type": "application/json"
2723
+ },
2724
+ body,
2725
+ credentials: "omit",
2726
+ cache: "no-store",
2727
+ redirect: "manual",
2728
+ signal: controller.signal
2729
+ });
2730
+ if (controller.signal.aborted) {
2731
+ response.body?.cancel().catch(() => {});
2732
+ throw authorityUnavailable();
2733
+ }
2734
+ if (!response.body) throw authorityUnavailable();
2735
+ reader = response.body.getReader();
2736
+ const contentType = response.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
2737
+ const length = response.headers.get("content-length");
2738
+ if (response.redirected || contentType !== "application/json" || length !== null && (!/^\d+$/.test(length) || Number(length) > 4096)) throw authorityUnavailable();
2739
+ const bytes = new Uint8Array(4096);
2740
+ let size = 0;
2741
+ while (true) {
2742
+ const chunk = await reader.read();
2743
+ if (controller.signal.aborted) throw authorityUnavailable();
2744
+ if (chunk.done) break;
2745
+ if (size + chunk.value.byteLength > bytes.byteLength) throw authorityUnavailable();
2746
+ bytes.set(chunk.value, size);
2747
+ size += chunk.value.byteLength;
2748
+ }
2749
+ const value = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(0, size)));
2750
+ if (response.status !== 200) {
2751
+ const status = response.status;
2752
+ const failure = failures[status];
2753
+ if (!failure || !exact(value, ["code", "message"]) || value.code !== failure[0] || value.message !== failure[1]) throw authorityUnavailable();
2754
+ let retryAfterSeconds;
2755
+ if (status === 429) {
2756
+ const retryAfter = response.headers.get("retry-after");
2757
+ if (retryAfter === null || !/^(?:[1-9]|[1-5][0-9]|60)$/.test(retryAfter)) throw authorityUnavailable();
2758
+ retryAfterSeconds = Number(retryAfter);
2759
+ }
2760
+ authorityError = new AuthError(failure[2], status, retryAfterSeconds);
2761
+ throw authorityError;
2762
+ }
2763
+ if (!exact(value, ["recipient"]) || !exact(value.recipient, [
2764
+ "userId",
2765
+ "name",
2766
+ "email"
2767
+ ])) throw authorityUnavailable();
2768
+ const recipient = value.recipient;
2769
+ if (typeof recipient.userId !== "string" || !/^[A-Za-z0-9_-]{1,128}$(?![\s\S])/.test(recipient.userId) || typeof recipient.name !== "string" || recipient.name.length === 0 || encoder.encode(recipient.name).byteLength > 1024 || !validEmail(recipient.email) || recipient.email !== recipient.email.trim().toLowerCase() || recipient.email !== email) throw authorityUnavailable();
2770
+ return {
2771
+ userId: recipient.userId,
2772
+ name: recipient.name,
2773
+ email: recipient.email
2774
+ };
2775
+ };
2776
+ return await Promise.race([exchange().finally(() => {
2777
+ inFlight = false;
2778
+ }), deadline]);
2779
+ } catch (error) {
2780
+ if (authorityError && error === authorityError) throw authorityError;
2781
+ throw authorityUnavailable();
2782
+ } finally {
2783
+ clearTimeout(timer);
2784
+ controller.abort();
2785
+ reader?.cancel().catch(() => {});
1413
2786
  }
1414
- });
1415
- return $fetch;
2787
+ } };
1416
2788
  }
1417
2789
  //#endregion
1418
- //#region src/http.ts
1419
- const MAX_RESPONSE_BYTES = 64 * 1024;
1420
- async function requestJson(url, options) {
1421
- return (await requestJsonResponse(url, options)).value;
1422
- }
1423
- async function requestJsonResponse(url, options) {
1424
- let response;
1425
- try {
1426
- response = await createFetch({ fetch: options.fetch }).raw(url, {
1427
- method: options.method,
1428
- headers: options.headers,
1429
- body: options.body,
1430
- credentials: options.credentials ?? "include",
1431
- retry: 0,
1432
- timeout: options.timeoutMs,
1433
- redirect: "manual",
1434
- signal: options.signal,
1435
- responseType: "stream",
1436
- ignoreResponseError: true
1437
- });
1438
- } catch {
1439
- throw authorityUnavailable();
1440
- }
1441
- const contentType = response.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
1442
- if (response.status >= 300 || response.status < 200 || contentType !== "application/json") {
1443
- const body = contentType === "application/json" ? await readJson(response, options.maxResponseBytes) : void 0;
1444
- await response.body?.cancel();
1445
- throw (options.mapError ?? fromAuthorityError)(body, response.status, response.headers.get("retry-after"));
1446
- }
1447
- return {
1448
- value: await readJson(response, options.maxResponseBytes),
1449
- headers: response.headers
1450
- };
2790
+ //#region src/provisioning.ts
2791
+ const MAX_BYTES = 16 * 1024;
2792
+ const compactJwt = /^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/;
2793
+ function isCompactCredential(value) {
2794
+ return typeof value === "string" && value.length + 7 <= MAX_BYTES && compactJwt.test(value);
1451
2795
  }
1452
- async function readJson(response, maximum = MAX_RESPONSE_BYTES) {
1453
- const length = response.headers.get("content-length");
1454
- if (length && (!/^\d+$/.test(length) || Number(length) > maximum)) {
1455
- await response.body?.cancel();
1456
- throw authorityUnavailable();
1457
- }
1458
- if (!response.body) throw authorityUnavailable();
1459
- const reader = response.body.getReader();
1460
- const chunks = [];
1461
- let size = 0;
1462
- try {
1463
- while (true) {
1464
- const { done, value } = await reader.read();
1465
- if (done) break;
1466
- size += value.byteLength;
1467
- if (size > maximum) throw authorityUnavailable();
1468
- chunks.push(value);
2796
+ function createDriveProvisioningAuth(options) {
2797
+ const url = joinURL(normalizeOrigin(options.authOrigin, "authOrigin"), "api/v1/auth/drive-provisioning-credential");
2798
+ const fetchImpl = options.fetch ?? globalThis.fetch?.bind(globalThis);
2799
+ if (typeof fetchImpl !== "function") throw new TypeError("fetch is required");
2800
+ const timeoutMs = normalizeTimeout(options.timeoutMs);
2801
+ const now = options.now ?? Date.now;
2802
+ let inFlight = false;
2803
+ return { async getDriveProvisioningCredential(clientAssertion) {
2804
+ if (!isCompactCredential(clientAssertion)) throw new AuthError("invalid_request", 400);
2805
+ if (inFlight) throw new AuthError("state_conflict", 409);
2806
+ inFlight = true;
2807
+ const controller = new AbortController();
2808
+ let reader;
2809
+ let timer;
2810
+ let exchangeStarted = false;
2811
+ let authorityError;
2812
+ try {
2813
+ const startedAt = now();
2814
+ if (!Number.isSafeInteger(startedAt) || startedAt < 0 || startedAt > 86399999997e5) throw authorityUnavailable();
2815
+ const deadline = new Promise((_, reject) => {
2816
+ timer = setTimeout(() => {
2817
+ reject(authorityUnavailable());
2818
+ controller.abort();
2819
+ reader?.cancel().catch(() => {});
2820
+ }, timeoutMs);
2821
+ });
2822
+ const exchange = async () => {
2823
+ const response = await fetchImpl(url, {
2824
+ method: "POST",
2825
+ headers: {
2826
+ authorization: `Bearer ${clientAssertion}`,
2827
+ accept: "application/json"
2828
+ },
2829
+ credentials: "omit",
2830
+ cache: "no-store",
2831
+ redirect: "manual",
2832
+ signal: controller.signal
2833
+ });
2834
+ if (controller.signal.aborted) {
2835
+ response.body?.cancel().catch(() => {});
2836
+ throw authorityUnavailable();
2837
+ }
2838
+ if (!response.body) throw authorityUnavailable();
2839
+ reader = response.body.getReader();
2840
+ const contentType = response.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
2841
+ const length = response.headers.get("content-length");
2842
+ if (contentType !== "application/json" || length !== null && (!/^\d+$/.test(length) || Number(length) > MAX_BYTES)) throw authorityUnavailable();
2843
+ const bytes = new Uint8Array(MAX_BYTES);
2844
+ let size = 0;
2845
+ while (true) {
2846
+ const chunk = await reader.read();
2847
+ if (chunk.done) break;
2848
+ if (controller.signal.aborted || size + chunk.value.byteLength > MAX_BYTES) throw authorityUnavailable();
2849
+ bytes.set(chunk.value, size);
2850
+ size += chunk.value.byteLength;
2851
+ }
2852
+ const value = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(0, size)));
2853
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw authorityUnavailable();
2854
+ const record = value;
2855
+ if (response.status !== 200) {
2856
+ if (Object.keys(record).length !== 2 || !("code" in record) || !("message" in record)) throw authorityUnavailable();
2857
+ if (response.status === 401 && record.code === "UNAUTHORIZED" && record.message === "The ecosystem client assertion is invalid.") {
2858
+ authorityError = new AuthError("authentication_required", 401);
2859
+ throw authorityError;
2860
+ }
2861
+ const retryAfter = response.headers.get("retry-after");
2862
+ if (response.status === 429 && record.code === "TOO_MANY_REQUESTS" && record.message === "Ecosystem credential exchanges are temporarily limited." && retryAfter !== null && /^(?:[1-9]|[1-5][0-9]|60)$/.test(retryAfter)) {
2863
+ authorityError = new AuthError("auth_request_rate_limited", 429, Number(retryAfter));
2864
+ throw authorityError;
2865
+ }
2866
+ throw authorityUnavailable();
2867
+ }
2868
+ if (Object.keys(record).length !== 3 || record.tokenType !== "Bearer" || record.expiresIn !== 300 || !isCompactCredential(record.token)) throw authorityUnavailable();
2869
+ const expiresAt = new Date(Math.floor(startedAt / 1e3) * 1e3 + 3e5);
2870
+ const completedAt = now();
2871
+ if (!Number.isSafeInteger(completedAt) || completedAt < 0 || completedAt >= expiresAt.getTime()) throw authorityUnavailable();
2872
+ return {
2873
+ tokenType: "Bearer",
2874
+ token: record.token,
2875
+ expiresAt
2876
+ };
2877
+ };
2878
+ exchangeStarted = true;
2879
+ return await Promise.race([exchange().finally(() => {
2880
+ inFlight = false;
2881
+ }), deadline]);
2882
+ } catch (error) {
2883
+ if (authorityError && error === authorityError) throw authorityError;
2884
+ throw authorityUnavailable();
2885
+ } finally {
2886
+ clearTimeout(timer);
2887
+ controller.abort();
2888
+ reader?.cancel().catch(() => {});
2889
+ if (!exchangeStarted) inFlight = false;
1469
2890
  }
1470
- } catch (error) {
1471
- await reader.cancel();
1472
- throw error;
1473
- } finally {
1474
- reader.releaseLock();
1475
- }
1476
- const bytes = new Uint8Array(size);
1477
- let offset = 0;
1478
- for (const chunk of chunks) {
1479
- bytes.set(chunk, offset);
1480
- offset += chunk.byteLength;
1481
- }
1482
- try {
1483
- return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
1484
- } catch {
1485
- throw authorityUnavailable();
1486
- }
2891
+ } };
1487
2892
  }
1488
2893
  //#endregion
1489
2894
  //#region src/server.ts
@@ -1566,6 +2971,21 @@ function createServerAuth(options) {
1566
2971
  const member = normalizeIdInput(memberId);
1567
2972
  return organizationRead(`${organization}/members/${member}/authority`, void 0, (value) => normalizeOrganizationMemberAuthority(value, organization, member));
1568
2973
  },
2974
+ async createOrganization(name, slug, idempotencyKey) {
2975
+ const body = normalizeOrganizationCreationInput(name, slug, idempotencyKey);
2976
+ return normalizeCreatedOrganization(await requestJson(joinURL(authOrigin, "api/v1/auth/organizations"), {
2977
+ fetch: fetchImpl,
2978
+ timeoutMs,
2979
+ method: "POST",
2980
+ credentials,
2981
+ headers: {
2982
+ ...authHeaders(!authorization),
2983
+ "content-type": "application/json"
2984
+ },
2985
+ body,
2986
+ mapError: fromOrganizationMutationAuthorityError
2987
+ }));
2988
+ },
1569
2989
  async createOrganizationTeam(organizationId, name, idempotencyKey) {
1570
2990
  const id = normalizeIdInput(organizationId);
1571
2991
  const body = normalizeOrganizationTeamCreationInput(name, idempotencyKey);
@@ -1634,6 +3054,41 @@ function createServerAuth(options) {
1634
3054
  mapError: fromOrganizationInvitationAdministrationError
1635
3055
  }));
1636
3056
  },
3057
+ async removeOrganizationMember(organizationId, memberId, idempotencyKey) {
3058
+ if (authorization) throw new AuthError("authentication_required", 401);
3059
+ const organization = normalizeIdInput(organizationId);
3060
+ const member = normalizeIdInput(memberId);
3061
+ const body = normalizeOrganizationMembershipRemovalInput(idempotencyKey);
3062
+ return normalizeRemovedOrganizationMember(await requestJson(joinURL(authOrigin, "api/v1/auth/organizations", organization, "members", member, "remove"), {
3063
+ fetch: fetchImpl,
3064
+ timeoutMs,
3065
+ method: "POST",
3066
+ credentials,
3067
+ headers: {
3068
+ ...authHeaders(),
3069
+ "content-type": "application/json"
3070
+ },
3071
+ body,
3072
+ mapError: fromOrganizationMembershipRemovalError
3073
+ }));
3074
+ },
3075
+ async leaveOrganization(organizationId, idempotencyKey) {
3076
+ if (authorization) throw new AuthError("authentication_required", 401);
3077
+ const organization = normalizeIdInput(organizationId);
3078
+ const body = normalizeOrganizationMembershipRemovalInput(idempotencyKey);
3079
+ return normalizeOrganizationDeparture(await requestJson(joinURL(authOrigin, "api/v1/auth/organizations", organization, "leave"), {
3080
+ fetch: fetchImpl,
3081
+ timeoutMs,
3082
+ method: "POST",
3083
+ credentials,
3084
+ headers: {
3085
+ ...authHeaders(),
3086
+ "content-type": "application/json"
3087
+ },
3088
+ body,
3089
+ mapError: fromOrganizationMembershipRemovalError
3090
+ }));
3091
+ },
1637
3092
  async updateOrganizationDisplay(organizationId, input) {
1638
3093
  const id = normalizeIdInput(organizationId);
1639
3094
  const desired = normalizeOrganizationDisplayInput(input);
@@ -1734,6 +3189,21 @@ function createServerAuth(options) {
1734
3189
  body: { workspace }
1735
3190
  }), now());
1736
3191
  },
3192
+ async getUserApiCredential(input) {
3193
+ const applicationId = userApiApplication(input);
3194
+ const startedAt = now();
3195
+ return normalizeUserApiCredential(await requestJson(joinURL(authOrigin, "api/v1/auth/user-api-credential"), {
3196
+ fetch: fetchImpl,
3197
+ timeoutMs,
3198
+ method: "POST",
3199
+ credentials,
3200
+ headers: {
3201
+ ...authHeaders(),
3202
+ "content-type": "application/json; charset=utf-8"
3203
+ },
3204
+ body: { applicationId }
3205
+ }), startedAt);
3206
+ },
1737
3207
  async signOut() {
1738
3208
  let response;
1739
3209
  try {
@@ -1785,4 +3255,4 @@ function authAuthorizationHeader(value) {
1785
3255
  return value;
1786
3256
  }
1787
3257
  //#endregion
1788
- export { AuthError, createDriveProvisioningAuth, createDriveRecipientAuth, createIdentityResolverAuth, createServerAuth };
3258
+ export { AuthError, createDriveProvisioningAuth, createDriveRecipientAuth, createIdentityResolverAuth, createMembershipResolverAuth, createServerAuth, createUserApiVerifier };