@pymthouse/builder-sdk 0.4.1-rc.1 → 0.4.1-rc.3

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.
Files changed (47) hide show
  1. package/dist/{index-BixH4VIG.d.cts → index-D5wdxNYy.d.cts} +4 -2
  2. package/dist/{index-BTDKEorK.d.ts → index-DFJ6qcK0.d.ts} +4 -2
  3. package/dist/index.d.cts +1 -1
  4. package/dist/index.d.ts +1 -1
  5. package/dist/{proxy-JrT6raU_.d.cts → proxy-0wa8QZIU.d.cts} +16 -2
  6. package/dist/{proxy-U32DFNuj.d.ts → proxy-KrA1vEmh.d.ts} +16 -2
  7. package/dist/signer/server.cjs +90 -67
  8. package/dist/signer/server.cjs.map +1 -1
  9. package/dist/signer/server.d.cts +4 -4
  10. package/dist/signer/server.d.ts +4 -4
  11. package/dist/signer/server.js +90 -67
  12. package/dist/signer/server.js.map +1 -1
  13. package/dist/signer/webhook/adapters/api-key.cjs +15 -11
  14. package/dist/signer/webhook/adapters/api-key.cjs.map +1 -1
  15. package/dist/signer/webhook/adapters/api-key.d.cts +1 -1
  16. package/dist/signer/webhook/adapters/api-key.d.ts +1 -1
  17. package/dist/signer/webhook/adapters/api-key.js +15 -11
  18. package/dist/signer/webhook/adapters/api-key.js.map +1 -1
  19. package/dist/signer/webhook/adapters/composite.cjs +1 -1
  20. package/dist/signer/webhook/adapters/composite.cjs.map +1 -1
  21. package/dist/signer/webhook/adapters/composite.d.cts +1 -1
  22. package/dist/signer/webhook/adapters/composite.d.ts +1 -1
  23. package/dist/signer/webhook/adapters/composite.js +1 -1
  24. package/dist/signer/webhook/adapters/composite.js.map +1 -1
  25. package/dist/signer/webhook/adapters/oauth1.d.cts +1 -1
  26. package/dist/signer/webhook/adapters/oauth1.d.ts +1 -1
  27. package/dist/signer/webhook/adapters/oidc.cjs +39 -25
  28. package/dist/signer/webhook/adapters/oidc.cjs.map +1 -1
  29. package/dist/signer/webhook/adapters/oidc.d.cts +2 -2
  30. package/dist/signer/webhook/adapters/oidc.d.ts +2 -2
  31. package/dist/signer/webhook/adapters/oidc.js +39 -25
  32. package/dist/signer/webhook/adapters/oidc.js.map +1 -1
  33. package/dist/signer/webhook/adapters/trusted-headers.cjs +18 -11
  34. package/dist/signer/webhook/adapters/trusted-headers.cjs.map +1 -1
  35. package/dist/signer/webhook/adapters/trusted-headers.d.cts +1 -1
  36. package/dist/signer/webhook/adapters/trusted-headers.d.ts +1 -1
  37. package/dist/signer/webhook/adapters/trusted-headers.js +18 -11
  38. package/dist/signer/webhook/adapters/trusted-headers.js.map +1 -1
  39. package/dist/signer/webhook.cjs +90 -38
  40. package/dist/signer/webhook.cjs.map +1 -1
  41. package/dist/signer/webhook.d.cts +6 -4
  42. package/dist/signer/webhook.d.ts +6 -4
  43. package/dist/signer/webhook.js +90 -39
  44. package/dist/signer/webhook.js.map +1 -1
  45. package/dist/{verifier-B-WFDMz6.d.cts → verifier-Be9WAjFF.d.cts} +3 -2
  46. package/dist/{verifier-B-WFDMz6.d.ts → verifier-Be9WAjFF.d.ts} +3 -2
  47. package/package.json +2 -2
@@ -17,20 +17,24 @@ var PmtHouseError = class extends Error {
17
17
  };
18
18
 
19
19
  // src/signer/webhook/bearer.ts
20
- function bearerTokenFromAuthorization(authorization) {
20
+ var BEARER_PREFIX = "Bearer ";
21
+ function optionalBearerToken(authorization) {
21
22
  const trimmed = authorization.trim();
22
- if (!trimmed) {
23
- throw new Error("missing authorization");
23
+ if (!trimmed.startsWith(BEARER_PREFIX)) {
24
+ return null;
24
25
  }
25
- const prefix = "Bearer ";
26
- if (!trimmed.startsWith(prefix)) {
27
- throw new Error("authorization must be Bearer token");
26
+ const token = trimmed.slice(BEARER_PREFIX.length).trim();
27
+ return token || null;
28
+ }
29
+ function bearerTokenFromAuthorization(authorization) {
30
+ const token = optionalBearerToken(authorization);
31
+ if (token) {
32
+ return token;
28
33
  }
29
- const token = trimmed.slice(prefix.length).trim();
30
- if (!token) {
31
- throw new Error("empty bearer token");
34
+ if (!authorization.trim()) {
35
+ throw new Error("missing authorization");
32
36
  }
33
- return token;
37
+ throw new Error("authorization must be Bearer token");
34
38
  }
35
39
 
36
40
  // src/signer/webhook/adapters/api-key/verifier.ts
@@ -40,7 +44,7 @@ function createApiKeyEndUserVerifier(config) {
40
44
  const defaultUsageSubjectType = config.defaultUsageSubjectType ?? "clerk_user_id";
41
45
  const ttl = config.expiryTtlSeconds ?? 60;
42
46
  return {
43
- kind: "custom",
47
+ kind: "api_key",
44
48
  verify: async ({ authorization }) => {
45
49
  const token = bearerTokenFromAuthorization(authorization);
46
50
  if (prefix && !token.startsWith(prefix)) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/errors.ts","../../../../src/signer/webhook/bearer.ts","../../../../src/signer/webhook/adapters/api-key/verifier.ts"],"names":[],"mappings":";AAAO,IAAM,aAAA,GAAN,cAA4B,KAAA,CAAM;AAAA,EAC9B,MAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA;AAAA,EAET,YACE,OAAA,EACA;AAAA,IACE,MAAA,GAAS,GAAA;AAAA,IACT,IAAA,GAAO,iBAAA;AAAA,IACP;AAAA,GACF,GAII,EAAC,EACL;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA;AACZ,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AACF,CAAA;;;ACvBO,SAAS,6BAA6B,aAAA,EAA+B;AAC1E,EAAA,MAAM,OAAA,GAAU,cAAc,IAAA,EAAK;AACnC,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,IAAI,MAAM,uBAAuB,CAAA;AAAA,EACzC;AACA,EAAA,MAAM,MAAA,GAAS,SAAA;AACf,EAAA,IAAI,CAAC,OAAA,CAAQ,UAAA,CAAW,MAAM,CAAA,EAAG;AAC/B,IAAA,MAAM,IAAI,MAAM,oCAAoC,CAAA;AAAA,EACtD;AACA,EAAA,MAAM,QAAQ,OAAA,CAAQ,KAAA,CAAM,MAAA,CAAO,MAAM,EAAE,IAAA,EAAK;AAChD,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,MAAM,IAAI,MAAM,oBAAoB,CAAA;AAAA,EACtC;AACA,EAAA,OAAO,KAAA;AACT;;;ACMO,SAAS,4BACd,MAAA,EACqB;AACrB,EAAA,MAAM,MAAA,GAAS,OAAO,YAAA,IAAgB,KAAA;AACtC,EAAA,MAAM,eAAA,GAAkB,OAAO,eAAA,IAAmB,gBAAA;AAClD,EAAA,MAAM,uBAAA,GACJ,OAAO,uBAAA,IAA2B,eAAA;AACpC,EAAA,MAAM,GAAA,GAAM,OAAO,gBAAA,IAAoB,EAAA;AAEvC,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,QAAA;AAAA,IACN,MAAA,EAAQ,OAAO,EAAE,aAAA,EAAc,KAAM;AACnC,MAAA,MAAM,KAAA,GAAQ,6BAA6B,aAAa,CAAA;AACxD,MAAA,IAAI,MAAA,IAAU,CAAC,KAAA,CAAM,UAAA,CAAW,MAAM,CAAA,EAAG;AACvC,QAAA,MAAM,IAAI,cAAc,iBAAA,EAAmB;AAAA,UACzC,MAAA,EAAQ,GAAA;AAAA,UACR,IAAA,EAAM;AAAA,SACP,CAAA;AAAA,MACH;AAEA,MAAA,MAAM,QAAA,GAAW,MAAM,MAAA,CAAO,aAAA,CAAc,KAAK,CAAA;AACjD,MAAA,IAAI,CAAC,UAAU,MAAA,EAAQ;AACrB,QAAA,MAAM,IAAI,cAAc,iBAAA,EAAmB;AAAA,UACzC,MAAA,EAAQ,GAAA;AAAA,UACR,IAAA,EAAM;AAAA,SACP,CAAA;AAAA,MACH;AAEA,MAAA,MAAM,QAAA,GAA0B;AAAA,QAC9B,QAAQ,MAAA,CAAO,MAAA;AAAA,QACf,SAAA,EAAW,SAAS,QAAA,IAAY,eAAA;AAAA,QAChC,eAAe,QAAA,CAAS,MAAA;AAAA,QACxB,kBAAA,EACE,SAAS,gBAAA,IAAoB;AAAA,OACjC;AAEA,MAAA,OAAO;AAAA,QACL,QAAA;AAAA,QACA,QAAQ,IAAA,CAAK,KAAA,CAAM,KAAK,GAAA,EAAI,GAAI,GAAI,CAAA,GAAI,GAAA;AAAA,QACxC,GAAA,EAAK;AAAA,OACP;AAAA,IACF;AAAA,GACF;AACF","file":"api-key.js","sourcesContent":["export class PmtHouseError extends Error {\n readonly status: number;\n readonly code: string;\n readonly details?: unknown;\n\n constructor(\n message: string,\n {\n status = 500,\n code = \"pymthouse_error\",\n details,\n }: {\n status?: number;\n code?: string;\n details?: unknown;\n } = {},\n ) {\n super(message);\n this.name = \"PmtHouseError\";\n this.status = status;\n this.code = code;\n this.details = details;\n }\n}\n\nexport function toPmtHouseError(\n error: unknown,\n fallbackMessage: string,\n): PmtHouseError {\n if (error instanceof PmtHouseError) {\n return error;\n }\n\n if (error instanceof Error) {\n return new PmtHouseError(error.message || fallbackMessage, {\n code: \"unexpected_error\",\n status: 500,\n });\n }\n\n return new PmtHouseError(fallbackMessage, {\n code: \"unexpected_error\",\n status: 500,\n });\n}\n","export function bearerTokenFromAuthorization(authorization: string): string {\n const trimmed = authorization.trim();\n if (!trimmed) {\n throw new Error(\"missing authorization\");\n }\n const prefix = \"Bearer \";\n if (!trimmed.startsWith(prefix)) {\n throw new Error(\"authorization must be Bearer token\");\n }\n const token = trimmed.slice(prefix.length).trim();\n if (!token) {\n throw new Error(\"empty bearer token\");\n }\n return token;\n}\n","import { PmtHouseError } from \"../../../../errors.js\";\nimport { bearerTokenFromAuthorization } from \"../../bearer.js\";\nimport type { UsageIdentity } from \"../../types.js\";\nimport type { EndUserAuthVerifier } from \"../../verifier.js\";\n\nexport type ApiKeyResolveResult = {\n userId: string;\n clientId?: string;\n usageSubjectType?: string;\n};\n\nexport type ApiKeyEndUserVerifierConfig = {\n issuer: string;\n resolveApiKey: (apiKey: string) => Promise<ApiKeyResolveResult | null>;\n expiryTtlSeconds?: number;\n apiKeyPrefix?: string;\n defaultClientId?: string;\n defaultUsageSubjectType?: string;\n};\n\nexport function createApiKeyEndUserVerifier(\n config: ApiKeyEndUserVerifierConfig,\n): EndUserAuthVerifier {\n const prefix = config.apiKeyPrefix ?? \"sk_\";\n const defaultClientId = config.defaultClientId ?? \"daydream-scope\";\n const defaultUsageSubjectType =\n config.defaultUsageSubjectType ?? \"clerk_user_id\";\n const ttl = config.expiryTtlSeconds ?? 60;\n\n return {\n kind: \"custom\",\n verify: async ({ authorization }) => {\n const token = bearerTokenFromAuthorization(authorization);\n if (prefix && !token.startsWith(prefix)) {\n throw new PmtHouseError(\"invalid api key\", {\n status: 401,\n code: \"invalid_api_key\",\n });\n }\n\n const resolved = await config.resolveApiKey(token);\n if (!resolved?.userId) {\n throw new PmtHouseError(\"invalid api key\", {\n status: 401,\n code: \"invalid_api_key\",\n });\n }\n\n const identity: UsageIdentity = {\n issuer: config.issuer,\n client_id: resolved.clientId ?? defaultClientId,\n usage_subject: resolved.userId,\n usage_subject_type:\n resolved.usageSubjectType ?? defaultUsageSubjectType,\n };\n\n return {\n identity,\n expiry: Math.trunc(Date.now() / 1000) + ttl,\n raw: resolved,\n };\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../../../../src/errors.ts","../../../../src/signer/webhook/bearer.ts","../../../../src/signer/webhook/adapters/api-key/verifier.ts"],"names":[],"mappings":"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","file":"api-key.js","sourcesContent":["export class PmtHouseError extends Error {\n readonly status: number;\n readonly code: string;\n readonly details?: unknown;\n\n constructor(\n message: string,\n {\n status = 500,\n code = \"pymthouse_error\",\n details,\n }: {\n status?: number;\n code?: string;\n details?: unknown;\n } = {},\n ) {\n super(message);\n this.name = \"PmtHouseError\";\n this.status = status;\n this.code = code;\n this.details = details;\n }\n}\n\nexport function toPmtHouseError(\n error: unknown,\n fallbackMessage: string,\n): PmtHouseError {\n if (error instanceof PmtHouseError) {\n return error;\n }\n\n if (error instanceof Error) {\n return new PmtHouseError(error.message || fallbackMessage, {\n code: \"unexpected_error\",\n status: 500,\n });\n }\n\n return new PmtHouseError(fallbackMessage, {\n code: \"unexpected_error\",\n status: 500,\n });\n}\n","const BEARER_PREFIX = \"Bearer \";\n\n/** Returns the token after `Bearer `, or null when the header is missing or not Bearer. */\nexport function optionalBearerToken(authorization: string): string | null {\n const trimmed = authorization.trim();\n if (!trimmed.startsWith(BEARER_PREFIX)) {\n return null;\n }\n const token = trimmed.slice(BEARER_PREFIX.length).trim();\n return token || null;\n}\n\nexport function bearerTokenFromAuthorization(authorization: string): string {\n const token = optionalBearerToken(authorization);\n if (token) {\n return token;\n }\n if (!authorization.trim()) {\n throw new Error(\"missing authorization\");\n }\n throw new Error(\"authorization must be Bearer token\");\n}\n","import { PmtHouseError } from \"../../../../errors.js\";\nimport { bearerTokenFromAuthorization } from \"../../bearer.js\";\nimport type { UsageIdentity } from \"../../types.js\";\nimport type { EndUserAuthVerifier } from \"../../verifier.js\";\n\nexport type ApiKeyResolveResult = {\n userId: string;\n clientId?: string;\n usageSubjectType?: string;\n};\n\nexport type ApiKeyEndUserVerifierConfig = {\n issuer: string;\n resolveApiKey: (apiKey: string) => Promise<ApiKeyResolveResult | null>;\n expiryTtlSeconds?: number;\n apiKeyPrefix?: string;\n defaultClientId?: string;\n defaultUsageSubjectType?: string;\n};\n\nexport function createApiKeyEndUserVerifier(\n config: ApiKeyEndUserVerifierConfig,\n): EndUserAuthVerifier {\n const prefix = config.apiKeyPrefix ?? \"sk_\";\n const defaultClientId = config.defaultClientId ?? \"daydream-scope\";\n const defaultUsageSubjectType =\n config.defaultUsageSubjectType ?? \"clerk_user_id\";\n const ttl = config.expiryTtlSeconds ?? 60;\n\n return {\n kind: \"api_key\",\n verify: async ({ authorization }) => {\n const token = bearerTokenFromAuthorization(authorization);\n if (prefix && !token.startsWith(prefix)) {\n throw new PmtHouseError(\"invalid api key\", {\n status: 401,\n code: \"invalid_api_key\",\n });\n }\n\n const resolved = await config.resolveApiKey(token);\n if (!resolved?.userId) {\n throw new PmtHouseError(\"invalid api key\", {\n status: 401,\n code: \"invalid_api_key\",\n });\n }\n\n const identity: UsageIdentity = {\n issuer: config.issuer,\n client_id: resolved.clientId ?? defaultClientId,\n usage_subject: resolved.userId,\n usage_subject_type:\n resolved.usageSubjectType ?? defaultUsageSubjectType,\n };\n\n return {\n identity,\n expiry: Math.trunc(Date.now() / 1000) + ttl,\n raw: resolved,\n };\n },\n };\n}\n"]}
@@ -27,7 +27,7 @@ function createFirstMatchEndUserVerifier(verifiers) {
27
27
  });
28
28
  }
29
29
  return {
30
- kind: "custom",
30
+ kind: "composite",
31
31
  verify: async (context) => {
32
32
  let lastError;
33
33
  for (const verifier of verifiers) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/errors.ts","../../../../src/signer/webhook/adapters/composite/verifier.ts"],"names":[],"mappings":";;;AAAO,IAAM,aAAA,GAAN,cAA4B,KAAA,CAAM;AAAA,EAC9B,MAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA;AAAA,EAET,YACE,OAAA,EACA;AAAA,IACE,MAAA,GAAS,GAAA;AAAA,IACT,IAAA,GAAO,iBAAA;AAAA,IACP;AAAA,GACF,GAII,EAAC,EACL;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA;AACZ,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AACF,CAAA;;;ACpBO,SAAS,gCACd,SAAA,EACqB;AACrB,EAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG;AAC1B,IAAA,MAAM,IAAI,cAAc,mCAAA,EAAqC;AAAA,MAC3D,MAAA,EAAQ,GAAA;AAAA,MACR,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AAEA,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,QAAA;AAAA,IACN,MAAA,EAAQ,OAAO,OAAA,KAAY;AACzB,MAAA,IAAI,SAAA;AACJ,MAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAChC,QAAA,IAAI;AACF,UAAA,OAAO,MAAM,QAAA,CAAS,MAAA,CAAO,OAAO,CAAA;AAAA,QACtC,SAAS,GAAA,EAAK;AACZ,UAAA,SAAA,GAAY,GAAA;AAAA,QACd;AAAA,MACF;AAEA,MAAA,IAAI,qBAAqB,aAAA,EAAe;AACtC,QAAA,MAAM,SAAA;AAAA,MACR;AACA,MAAA,IAAI,qBAAqB,KAAA,EAAO;AAC9B,QAAA,MAAM,IAAI,aAAA,CAAc,SAAA,CAAU,OAAA,EAAS;AAAA,UACzC,MAAA,EAAQ,GAAA;AAAA,UACR,IAAA,EAAM;AAAA,SACP,CAAA;AAAA,MACH;AACA,MAAA,MAAM,IAAI,cAAc,qBAAA,EAAuB;AAAA,QAC7C,MAAA,EAAQ,GAAA;AAAA,QACR,IAAA,EAAM;AAAA,OACP,CAAA;AAAA,IACH,CAAA;AAAA,IACA,WAAA,EAAa,UAAU,OAAA,CAAQ,CAAC,aAAa,QAAA,CAAS,WAAA,IAAe,EAAE;AAAA,GACzE;AACF","file":"composite.cjs","sourcesContent":["export class PmtHouseError extends Error {\n readonly status: number;\n readonly code: string;\n readonly details?: unknown;\n\n constructor(\n message: string,\n {\n status = 500,\n code = \"pymthouse_error\",\n details,\n }: {\n status?: number;\n code?: string;\n details?: unknown;\n } = {},\n ) {\n super(message);\n this.name = \"PmtHouseError\";\n this.status = status;\n this.code = code;\n this.details = details;\n }\n}\n\nexport function toPmtHouseError(\n error: unknown,\n fallbackMessage: string,\n): PmtHouseError {\n if (error instanceof PmtHouseError) {\n return error;\n }\n\n if (error instanceof Error) {\n return new PmtHouseError(error.message || fallbackMessage, {\n code: \"unexpected_error\",\n status: 500,\n });\n }\n\n return new PmtHouseError(fallbackMessage, {\n code: \"unexpected_error\",\n status: 500,\n });\n}\n","import { PmtHouseError } from \"../../../../errors.js\";\nimport type { EndUserAuthVerifier } from \"../../verifier.js\";\n\nexport function createFirstMatchEndUserVerifier(\n verifiers: EndUserAuthVerifier[],\n): EndUserAuthVerifier {\n if (verifiers.length === 0) {\n throw new PmtHouseError(\"at least one verifier is required\", {\n status: 500,\n code: \"invalid_verifier_config\",\n });\n }\n\n return {\n kind: \"custom\",\n verify: async (context) => {\n let lastError: unknown;\n for (const verifier of verifiers) {\n try {\n return await verifier.verify(context);\n } catch (err) {\n lastError = err;\n }\n }\n\n if (lastError instanceof PmtHouseError) {\n throw lastError;\n }\n if (lastError instanceof Error) {\n throw new PmtHouseError(lastError.message, {\n status: 401,\n code: \"invalid_credentials\",\n });\n }\n throw new PmtHouseError(\"invalid credentials\", {\n status: 401,\n code: \"invalid_credentials\",\n });\n },\n adminRoutes: verifiers.flatMap((verifier) => verifier.adminRoutes ?? []),\n };\n}\n"]}
1
+ {"version":3,"sources":["../../../../src/errors.ts","../../../../src/signer/webhook/adapters/composite/verifier.ts"],"names":[],"mappings":";;;AAAO,IAAM,aAAA,GAAN,cAA4B,KAAA,CAAM;AAAA,EAC9B,MAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA;AAAA,EAET,YACE,OAAA,EACA;AAAA,IACE,MAAA,GAAS,GAAA;AAAA,IACT,IAAA,GAAO,iBAAA;AAAA,IACP;AAAA,GACF,GAII,EAAC,EACL;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA;AACZ,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AACF,CAAA;;;ACpBO,SAAS,gCACd,SAAA,EACqB;AACrB,EAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG;AAC1B,IAAA,MAAM,IAAI,cAAc,mCAAA,EAAqC;AAAA,MAC3D,MAAA,EAAQ,GAAA;AAAA,MACR,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AAEA,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,WAAA;AAAA,IACN,MAAA,EAAQ,OAAO,OAAA,KAAY;AACzB,MAAA,IAAI,SAAA;AACJ,MAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAChC,QAAA,IAAI;AACF,UAAA,OAAO,MAAM,QAAA,CAAS,MAAA,CAAO,OAAO,CAAA;AAAA,QACtC,SAAS,GAAA,EAAK;AACZ,UAAA,SAAA,GAAY,GAAA;AAAA,QACd;AAAA,MACF;AAEA,MAAA,IAAI,qBAAqB,aAAA,EAAe;AACtC,QAAA,MAAM,SAAA;AAAA,MACR;AACA,MAAA,IAAI,qBAAqB,KAAA,EAAO;AAC9B,QAAA,MAAM,IAAI,aAAA,CAAc,SAAA,CAAU,OAAA,EAAS;AAAA,UACzC,MAAA,EAAQ,GAAA;AAAA,UACR,IAAA,EAAM;AAAA,SACP,CAAA;AAAA,MACH;AACA,MAAA,MAAM,IAAI,cAAc,qBAAA,EAAuB;AAAA,QAC7C,MAAA,EAAQ,GAAA;AAAA,QACR,IAAA,EAAM;AAAA,OACP,CAAA;AAAA,IACH,CAAA;AAAA,IACA,WAAA,EAAa,UAAU,OAAA,CAAQ,CAAC,aAAa,QAAA,CAAS,WAAA,IAAe,EAAE;AAAA,GACzE;AACF","file":"composite.cjs","sourcesContent":["export class PmtHouseError extends Error {\n readonly status: number;\n readonly code: string;\n readonly details?: unknown;\n\n constructor(\n message: string,\n {\n status = 500,\n code = \"pymthouse_error\",\n details,\n }: {\n status?: number;\n code?: string;\n details?: unknown;\n } = {},\n ) {\n super(message);\n this.name = \"PmtHouseError\";\n this.status = status;\n this.code = code;\n this.details = details;\n }\n}\n\nexport function toPmtHouseError(\n error: unknown,\n fallbackMessage: string,\n): PmtHouseError {\n if (error instanceof PmtHouseError) {\n return error;\n }\n\n if (error instanceof Error) {\n return new PmtHouseError(error.message || fallbackMessage, {\n code: \"unexpected_error\",\n status: 500,\n });\n }\n\n return new PmtHouseError(fallbackMessage, {\n code: \"unexpected_error\",\n status: 500,\n });\n}\n","import { PmtHouseError } from \"../../../../errors.js\";\nimport type { EndUserAuthVerifier } from \"../../verifier.js\";\n\nexport function createFirstMatchEndUserVerifier(\n verifiers: EndUserAuthVerifier[],\n): EndUserAuthVerifier {\n if (verifiers.length === 0) {\n throw new PmtHouseError(\"at least one verifier is required\", {\n status: 500,\n code: \"invalid_verifier_config\",\n });\n }\n\n return {\n kind: \"composite\",\n verify: async (context) => {\n let lastError: unknown;\n for (const verifier of verifiers) {\n try {\n return await verifier.verify(context);\n } catch (err) {\n lastError = err;\n }\n }\n\n if (lastError instanceof PmtHouseError) {\n throw lastError;\n }\n if (lastError instanceof Error) {\n throw new PmtHouseError(lastError.message, {\n status: 401,\n code: \"invalid_credentials\",\n });\n }\n throw new PmtHouseError(\"invalid credentials\", {\n status: 401,\n code: \"invalid_credentials\",\n });\n },\n adminRoutes: verifiers.flatMap((verifier) => verifier.adminRoutes ?? []),\n };\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { E as EndUserAuthVerifier } from '../../../verifier-B-WFDMz6.cjs';
1
+ import { E as EndUserAuthVerifier } from '../../../verifier-Be9WAjFF.cjs';
2
2
 
3
3
  declare function createFirstMatchEndUserVerifier(verifiers: EndUserAuthVerifier[]): EndUserAuthVerifier;
4
4
 
@@ -1,4 +1,4 @@
1
- import { E as EndUserAuthVerifier } from '../../../verifier-B-WFDMz6.js';
1
+ import { E as EndUserAuthVerifier } from '../../../verifier-Be9WAjFF.js';
2
2
 
3
3
  declare function createFirstMatchEndUserVerifier(verifiers: EndUserAuthVerifier[]): EndUserAuthVerifier;
4
4
 
@@ -25,7 +25,7 @@ function createFirstMatchEndUserVerifier(verifiers) {
25
25
  });
26
26
  }
27
27
  return {
28
- kind: "custom",
28
+ kind: "composite",
29
29
  verify: async (context) => {
30
30
  let lastError;
31
31
  for (const verifier of verifiers) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/errors.ts","../../../../src/signer/webhook/adapters/composite/verifier.ts"],"names":[],"mappings":";AAAO,IAAM,aAAA,GAAN,cAA4B,KAAA,CAAM;AAAA,EAC9B,MAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA;AAAA,EAET,YACE,OAAA,EACA;AAAA,IACE,MAAA,GAAS,GAAA;AAAA,IACT,IAAA,GAAO,iBAAA;AAAA,IACP;AAAA,GACF,GAII,EAAC,EACL;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA;AACZ,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AACF,CAAA;;;ACpBO,SAAS,gCACd,SAAA,EACqB;AACrB,EAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG;AAC1B,IAAA,MAAM,IAAI,cAAc,mCAAA,EAAqC;AAAA,MAC3D,MAAA,EAAQ,GAAA;AAAA,MACR,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AAEA,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,QAAA;AAAA,IACN,MAAA,EAAQ,OAAO,OAAA,KAAY;AACzB,MAAA,IAAI,SAAA;AACJ,MAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAChC,QAAA,IAAI;AACF,UAAA,OAAO,MAAM,QAAA,CAAS,MAAA,CAAO,OAAO,CAAA;AAAA,QACtC,SAAS,GAAA,EAAK;AACZ,UAAA,SAAA,GAAY,GAAA;AAAA,QACd;AAAA,MACF;AAEA,MAAA,IAAI,qBAAqB,aAAA,EAAe;AACtC,QAAA,MAAM,SAAA;AAAA,MACR;AACA,MAAA,IAAI,qBAAqB,KAAA,EAAO;AAC9B,QAAA,MAAM,IAAI,aAAA,CAAc,SAAA,CAAU,OAAA,EAAS;AAAA,UACzC,MAAA,EAAQ,GAAA;AAAA,UACR,IAAA,EAAM;AAAA,SACP,CAAA;AAAA,MACH;AACA,MAAA,MAAM,IAAI,cAAc,qBAAA,EAAuB;AAAA,QAC7C,MAAA,EAAQ,GAAA;AAAA,QACR,IAAA,EAAM;AAAA,OACP,CAAA;AAAA,IACH,CAAA;AAAA,IACA,WAAA,EAAa,UAAU,OAAA,CAAQ,CAAC,aAAa,QAAA,CAAS,WAAA,IAAe,EAAE;AAAA,GACzE;AACF","file":"composite.js","sourcesContent":["export class PmtHouseError extends Error {\n readonly status: number;\n readonly code: string;\n readonly details?: unknown;\n\n constructor(\n message: string,\n {\n status = 500,\n code = \"pymthouse_error\",\n details,\n }: {\n status?: number;\n code?: string;\n details?: unknown;\n } = {},\n ) {\n super(message);\n this.name = \"PmtHouseError\";\n this.status = status;\n this.code = code;\n this.details = details;\n }\n}\n\nexport function toPmtHouseError(\n error: unknown,\n fallbackMessage: string,\n): PmtHouseError {\n if (error instanceof PmtHouseError) {\n return error;\n }\n\n if (error instanceof Error) {\n return new PmtHouseError(error.message || fallbackMessage, {\n code: \"unexpected_error\",\n status: 500,\n });\n }\n\n return new PmtHouseError(fallbackMessage, {\n code: \"unexpected_error\",\n status: 500,\n });\n}\n","import { PmtHouseError } from \"../../../../errors.js\";\nimport type { EndUserAuthVerifier } from \"../../verifier.js\";\n\nexport function createFirstMatchEndUserVerifier(\n verifiers: EndUserAuthVerifier[],\n): EndUserAuthVerifier {\n if (verifiers.length === 0) {\n throw new PmtHouseError(\"at least one verifier is required\", {\n status: 500,\n code: \"invalid_verifier_config\",\n });\n }\n\n return {\n kind: \"custom\",\n verify: async (context) => {\n let lastError: unknown;\n for (const verifier of verifiers) {\n try {\n return await verifier.verify(context);\n } catch (err) {\n lastError = err;\n }\n }\n\n if (lastError instanceof PmtHouseError) {\n throw lastError;\n }\n if (lastError instanceof Error) {\n throw new PmtHouseError(lastError.message, {\n status: 401,\n code: \"invalid_credentials\",\n });\n }\n throw new PmtHouseError(\"invalid credentials\", {\n status: 401,\n code: \"invalid_credentials\",\n });\n },\n adminRoutes: verifiers.flatMap((verifier) => verifier.adminRoutes ?? []),\n };\n}\n"]}
1
+ {"version":3,"sources":["../../../../src/errors.ts","../../../../src/signer/webhook/adapters/composite/verifier.ts"],"names":[],"mappings":";AAAO,IAAM,aAAA,GAAN,cAA4B,KAAA,CAAM;AAAA,EAC9B,MAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA;AAAA,EAET,YACE,OAAA,EACA;AAAA,IACE,MAAA,GAAS,GAAA;AAAA,IACT,IAAA,GAAO,iBAAA;AAAA,IACP;AAAA,GACF,GAII,EAAC,EACL;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA;AACZ,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AACF,CAAA;;;ACpBO,SAAS,gCACd,SAAA,EACqB;AACrB,EAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG;AAC1B,IAAA,MAAM,IAAI,cAAc,mCAAA,EAAqC;AAAA,MAC3D,MAAA,EAAQ,GAAA;AAAA,MACR,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AAEA,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,WAAA;AAAA,IACN,MAAA,EAAQ,OAAO,OAAA,KAAY;AACzB,MAAA,IAAI,SAAA;AACJ,MAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAChC,QAAA,IAAI;AACF,UAAA,OAAO,MAAM,QAAA,CAAS,MAAA,CAAO,OAAO,CAAA;AAAA,QACtC,SAAS,GAAA,EAAK;AACZ,UAAA,SAAA,GAAY,GAAA;AAAA,QACd;AAAA,MACF;AAEA,MAAA,IAAI,qBAAqB,aAAA,EAAe;AACtC,QAAA,MAAM,SAAA;AAAA,MACR;AACA,MAAA,IAAI,qBAAqB,KAAA,EAAO;AAC9B,QAAA,MAAM,IAAI,aAAA,CAAc,SAAA,CAAU,OAAA,EAAS;AAAA,UACzC,MAAA,EAAQ,GAAA;AAAA,UACR,IAAA,EAAM;AAAA,SACP,CAAA;AAAA,MACH;AACA,MAAA,MAAM,IAAI,cAAc,qBAAA,EAAuB;AAAA,QAC7C,MAAA,EAAQ,GAAA;AAAA,QACR,IAAA,EAAM;AAAA,OACP,CAAA;AAAA,IACH,CAAA;AAAA,IACA,WAAA,EAAa,UAAU,OAAA,CAAQ,CAAC,aAAa,QAAA,CAAS,WAAA,IAAe,EAAE;AAAA,GACzE;AACF","file":"composite.js","sourcesContent":["export class PmtHouseError extends Error {\n readonly status: number;\n readonly code: string;\n readonly details?: unknown;\n\n constructor(\n message: string,\n {\n status = 500,\n code = \"pymthouse_error\",\n details,\n }: {\n status?: number;\n code?: string;\n details?: unknown;\n } = {},\n ) {\n super(message);\n this.name = \"PmtHouseError\";\n this.status = status;\n this.code = code;\n this.details = details;\n }\n}\n\nexport function toPmtHouseError(\n error: unknown,\n fallbackMessage: string,\n): PmtHouseError {\n if (error instanceof PmtHouseError) {\n return error;\n }\n\n if (error instanceof Error) {\n return new PmtHouseError(error.message || fallbackMessage, {\n code: \"unexpected_error\",\n status: 500,\n });\n }\n\n return new PmtHouseError(fallbackMessage, {\n code: \"unexpected_error\",\n status: 500,\n });\n}\n","import { PmtHouseError } from \"../../../../errors.js\";\nimport type { EndUserAuthVerifier } from \"../../verifier.js\";\n\nexport function createFirstMatchEndUserVerifier(\n verifiers: EndUserAuthVerifier[],\n): EndUserAuthVerifier {\n if (verifiers.length === 0) {\n throw new PmtHouseError(\"at least one verifier is required\", {\n status: 500,\n code: \"invalid_verifier_config\",\n });\n }\n\n return {\n kind: \"composite\",\n verify: async (context) => {\n let lastError: unknown;\n for (const verifier of verifiers) {\n try {\n return await verifier.verify(context);\n } catch (err) {\n lastError = err;\n }\n }\n\n if (lastError instanceof PmtHouseError) {\n throw lastError;\n }\n if (lastError instanceof Error) {\n throw new PmtHouseError(lastError.message, {\n status: 401,\n code: \"invalid_credentials\",\n });\n }\n throw new PmtHouseError(\"invalid credentials\", {\n status: 401,\n code: \"invalid_credentials\",\n });\n },\n adminRoutes: verifiers.flatMap((verifier) => verifier.adminRoutes ?? []),\n };\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { U as UsageIdentity, E as EndUserAuthVerifier } from '../../../verifier-B-WFDMz6.cjs';
1
+ import { U as UsageIdentity, E as EndUserAuthVerifier } from '../../../verifier-Be9WAjFF.cjs';
2
2
 
3
3
  type OAuth1EndUserAuthConfig = {
4
4
  consumerKey: string;
@@ -1,4 +1,4 @@
1
- import { U as UsageIdentity, E as EndUserAuthVerifier } from '../../../verifier-B-WFDMz6.js';
1
+ import { U as UsageIdentity, E as EndUserAuthVerifier } from '../../../verifier-Be9WAjFF.js';
2
2
 
3
3
  type OAuth1EndUserAuthConfig = {
4
4
  consumerKey: string;
@@ -4,20 +4,24 @@ var oauth4webapi = require('oauth4webapi');
4
4
  var crypto = require('crypto');
5
5
 
6
6
  // src/signer/webhook/bearer.ts
7
- function bearerTokenFromAuthorization(authorization) {
7
+ var BEARER_PREFIX = "Bearer ";
8
+ function optionalBearerToken(authorization) {
8
9
  const trimmed = authorization.trim();
9
- if (!trimmed) {
10
- throw new Error("missing authorization");
10
+ if (!trimmed.startsWith(BEARER_PREFIX)) {
11
+ return null;
11
12
  }
12
- const prefix = "Bearer ";
13
- if (!trimmed.startsWith(prefix)) {
14
- throw new Error("authorization must be Bearer token");
13
+ const token = trimmed.slice(BEARER_PREFIX.length).trim();
14
+ return token || null;
15
+ }
16
+ function bearerTokenFromAuthorization(authorization) {
17
+ const token = optionalBearerToken(authorization);
18
+ if (token) {
19
+ return token;
15
20
  }
16
- const token = trimmed.slice(prefix.length).trim();
17
- if (!token) {
18
- throw new Error("empty bearer token");
21
+ if (!authorization.trim()) {
22
+ throw new Error("missing authorization");
19
23
  }
20
- return token;
24
+ throw new Error("authorization must be Bearer token");
21
25
  }
22
26
 
23
27
  // src/errors.ts
@@ -193,22 +197,29 @@ async function verifyJwt(token, options) {
193
197
  }
194
198
 
195
199
  // src/signer/webhook/payload.ts
200
+ function firstHeaderValue(values) {
201
+ if (!Array.isArray(values)) {
202
+ return "";
203
+ }
204
+ for (const value of values) {
205
+ if (typeof value === "string" && value.trim()) {
206
+ return value.trim();
207
+ }
208
+ }
209
+ return "";
210
+ }
196
211
  function headerValueFromWebhookPayload(headers, name) {
197
212
  if (!headers) {
198
213
  return "";
199
214
  }
215
+ const direct = firstHeaderValue(headers[name]);
216
+ if (direct) {
217
+ return direct;
218
+ }
200
219
  const target = name.toLowerCase();
201
220
  for (const [key, values] of Object.entries(headers)) {
202
- if (key.toLowerCase() !== target) {
203
- continue;
204
- }
205
- if (!Array.isArray(values)) {
206
- continue;
207
- }
208
- for (const value of values) {
209
- if (typeof value === "string" && value.trim()) {
210
- return value.trim();
211
- }
221
+ if (key.toLowerCase() === target) {
222
+ return firstHeaderValue(values);
212
223
  }
213
224
  }
214
225
  return "";
@@ -228,8 +239,8 @@ function authenticateWebhookCaller(request, secret) {
228
239
  return false;
229
240
  }
230
241
  const trimmed = secret.trim();
231
- const auth = request.headers.get("authorization")?.trim() ?? "";
232
- if (auth === `Bearer ${trimmed}`) {
242
+ const bearer = optionalBearerToken(request.headers.get("authorization") ?? "");
243
+ if (bearer && timingSafeEqualStrings(bearer, trimmed)) {
233
244
  return true;
234
245
  }
235
246
  const apiKey = request.headers.get("x-api-key")?.trim() ?? "";
@@ -367,7 +378,7 @@ function createFirstMatchEndUserVerifier(verifiers) {
367
378
  });
368
379
  }
369
380
  return {
370
- kind: "custom",
381
+ kind: "composite",
371
382
  verify: async (context) => {
372
383
  let lastError;
373
384
  for (const verifier of verifiers) {
@@ -431,7 +442,7 @@ function identityFromTrustedHeaders(headers, config) {
431
442
  });
432
443
  }
433
444
  return {
434
- issuer,
445
+ issuer: normalizeIssuer(issuer),
435
446
  client_id: clientId,
436
447
  usage_subject: usageSubject,
437
448
  usage_subject_type: usageSubjectType
@@ -456,6 +467,9 @@ function envTrim(env, key) {
456
467
  const value = env[key]?.trim();
457
468
  return value || void 0;
458
469
  }
470
+ function defaultSignerWebhookJwtAudience(jwtIssuer) {
471
+ return stripTrailingSlashes(jwtIssuer);
472
+ }
459
473
  function createOidcRemoteSignerWebhookConfig(input) {
460
474
  const { afterVerify, ...oidcConfig } = input;
461
475
  return {
@@ -488,7 +502,7 @@ function createSignerDmzRemoteSignerWebhookConfig(input) {
488
502
  function readOidcRemoteSignerWebhookConfigFromEnv(env = process.env) {
489
503
  const webhookSecret = envTrim(env, "WEBHOOK_SECRET");
490
504
  const jwtIssuer = envTrim(env, "JWT_ISSUER");
491
- const jwtAudience = envTrim(env, "JWT_AUDIENCE") ?? jwtIssuer;
505
+ const jwtAudience = envTrim(env, "JWT_AUDIENCE") ?? (jwtIssuer ? defaultSignerWebhookJwtAudience(jwtIssuer) : void 0);
492
506
  if (!webhookSecret) {
493
507
  throw new Error("WEBHOOK_SECRET is required");
494
508
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/signer/webhook/bearer.ts","../../../../src/errors.ts","../../../../src/string-utils.ts","../../../../src/discovery.ts","../../../../src/oauth-map.ts","../../../../src/verify.ts","../../../../src/signer/webhook/payload.ts","../../../../src/signer/webhook/authorize.ts","../../../../src/signer/webhook/identity.ts","../../../../src/signer/webhook/adapters/oidc/verifier.ts","../../../../src/signer/webhook/adapters/composite/verifier.ts","../../../../src/signer/webhook/adapters/trusted-headers/verifier.ts","../../../../src/signer/webhook/adapters/oidc/config.ts"],"names":["customFetch","allowInsecureRequests","discoveryRequest","processDiscoveryResponse","ResponseBodyError","OperationProcessingError","validateJwtAccessToken","timingSafeEqual"],"mappings":";;;;;;AAAO,SAAS,6BAA6B,aAAA,EAA+B;AAC1E,EAAA,MAAM,OAAA,GAAU,cAAc,IAAA,EAAK;AACnC,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,IAAI,MAAM,uBAAuB,CAAA;AAAA,EACzC;AACA,EAAA,MAAM,MAAA,GAAS,SAAA;AACf,EAAA,IAAI,CAAC,OAAA,CAAQ,UAAA,CAAW,MAAM,CAAA,EAAG;AAC/B,IAAA,MAAM,IAAI,MAAM,oCAAoC,CAAA;AAAA,EACtD;AACA,EAAA,MAAM,QAAQ,OAAA,CAAQ,KAAA,CAAM,MAAA,CAAO,MAAM,EAAE,IAAA,EAAK;AAChD,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,MAAM,IAAI,MAAM,oBAAoB,CAAA;AAAA,EACtC;AACA,EAAA,OAAO,KAAA;AACT;;;ACdO,IAAM,aAAA,GAAN,cAA4B,KAAA,CAAM;AAAA,EAC9B,MAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA;AAAA,EAET,YACE,OAAA,EACA;AAAA,IACE,MAAA,GAAS,GAAA;AAAA,IACT,IAAA,GAAO,iBAAA;AAAA,IACP;AAAA,GACF,GAII,EAAC,EACL;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA;AACZ,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AACF,CAAA;;;ACtBO,SAAS,qBAAqB,KAAA,EAAuB;AAC1D,EAAA,IAAI,MAAM,KAAA,CAAM,MAAA;AAChB,EAAA,OAAO,GAAA,GAAM,MAAM,KAAA,CAAM,WAAA,CAAY,MAAM,CAAC,CAAA,IAAK,OAAO,EAAA,EAAI;AAC1D,IAAA,GAAA,EAAA;AAAA,EACF;AACA,EAAA,OAAO,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,GAAG,CAAA;AAC3B;;;ACuBA,IAAM,YAAA,GAAe,IAAI,EAAA,GAAK,GAAA;AAO9B,IAAM,cAAA,uBAAqB,GAAA,EAAwB;AAEnD,SAAS,oBAAoB,SAAA,EAA2B;AACtD,EAAA,OAAO,qBAAqB,SAAS,CAAA;AACvC;AAUA,eAAsB,uBAAA,CACpB,SAAA,EACA,SAAA,EACA,OAAA,GAA0C,EAAC,EACb;AAC9B,EAAA,MAAM,GAAA,GAAM,oBAAoB,SAAS,CAAA;AACzC,EAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,EAAA,MAAM,MAAA,GAAS,cAAA,CAAe,GAAA,CAAI,GAAG,CAAA;AAErC,EAAA,IAAI,CAAC,OAAA,CAAQ,KAAA,IAAS,UAAU,GAAA,GAAM,MAAA,CAAO,YAAY,YAAA,EAAc;AACrE,IAAA,OAAO,MAAA,CAAO,EAAA;AAAA,EAChB;AAEA,EAAA,MAAM,gBAAA,GAAmB,IAAI,GAAA,CAAI,GAAG,CAAA;AACpC,EAAA,MAAM,aAAA,GAAwD;AAAA,IAC5D,SAAA,EAAW,MAAA;AAAA,IACX,CAACA,wBAAW,GAAG;AAAA,GACjB;AACA,EAAA,IAAI,QAAQ,iBAAA,EAAmB;AAC7B,IAAA,aAAA,CAAcC,kCAAqB,CAAA,GAAI,IAAA;AAAA,EACzC;AAEA,EAAA,IAAI,QAAA;AACJ,EAAA,IAAI;AACF,IAAA,QAAA,GAAW,MAAMC,6BAAA,CAAiB,gBAAA,EAAkB,aAAa,CAAA;AAAA,EACnE,SAAS,CAAA,EAAG;AACV,IAAA,MAAM,yBAAyB,CAAC,CAAA;AAAA,EAClC;AAEA,EAAA,IAAI,EAAA;AACJ,EAAA,IAAI;AACF,IAAA,EAAA,GAAK,MAAMC,qCAAA,CAAyB,gBAAA,EAAkB,QAAQ,CAAA;AAAA,EAChE,SAAS,CAAA,EAAG;AACV,IAAA,MAAM,uBAAuB,CAAC,CAAA;AAAA,EAChC;AAEA,EAAA,cAAA,CAAe,IAAI,GAAA,EAAK,EAAE,EAAA,EAAI,SAAA,EAAW,KAAK,CAAA;AAC9C,EAAA,OAAO,EAAA;AACT;AAmBA,SAAS,uBAAuB,KAAA,EAA+B;AAC7D,EAAA,IAAI,iBAAiB,aAAA,EAAe;AAClC,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,IAAI,iBAAiB,KAAA,EAAO;AAC1B,IAAA,OAAO,IAAI,aAAA,CAAc,KAAA,CAAM,OAAA,EAAS;AAAA,MACtC,MAAA,EAAQ,GAAA;AAAA,MACR,IAAA,EAAM,wBAAA;AAAA,MACN,OAAA,EAAS,EAAE,KAAA,EAAO,KAAA,CAAM,KAAA;AAAM,KAC/B,CAAA;AAAA,EACH;AACA,EAAA,OAAO,IAAI,cAAc,uBAAA,EAAyB;AAAA,IAChD,MAAA,EAAQ,GAAA;AAAA,IACR,IAAA,EAAM;AAAA,GACP,CAAA;AACH;AAEA,SAAS,yBAAyB,KAAA,EAA+B;AAC/D,EAAA,IAAI,iBAAiB,aAAA,EAAe;AAClC,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,IAAI,iBAAiB,KAAA,EAAO;AAC1B,IAAA,OAAO,IAAI,aAAA,CAAc,CAAA,+BAAA,EAAkC,KAAA,CAAM,OAAO,CAAA,CAAA,EAAI;AAAA,MAC1E,MAAA,EAAQ,GAAA;AAAA,MACR,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AACA,EAAA,OAAO,IAAI,cAAc,+BAAA,EAAiC;AAAA,IACxD,MAAA,EAAQ,GAAA;AAAA,IACR,IAAA,EAAM;AAAA,GACP,CAAA;AACH;AClIO,SAAS,cAAc,KAAA,EAA+B;AAC3D,EAAA,IAAI,iBAAiB,aAAA,EAAe;AAClC,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,IAAI,iBAAiBC,8BAAA,EAAmB;AACtC,IAAA,MAAM,QAAQ,KAAA,CAAM,KAAA;AACpB,IAAA,MAAM,cACJ,OAAO,KAAA,CAAM,sBAAsB,QAAA,GAC/B,KAAA,CAAM,oBACN,KAAA,CAAM,OAAA;AACZ,IAAA,MAAM,OAAA,GAAmC,EAAE,GAAG,KAAA,EAAM;AACpD,IAAA,IAAI,OAAO,KAAA,CAAM,SAAA,KAAc,QAAA,EAAU;AACvC,MAAA,OAAA,CAAQ,YAAY,KAAA,CAAM,SAAA;AAAA,IAC5B;AACA,IAAA,OAAO,IAAI,cAAc,WAAA,EAAa;AAAA,MACpC,QAAQ,KAAA,CAAM,MAAA;AAAA,MACd,MAAM,KAAA,CAAM,KAAA;AAAA,MACZ;AAAA,KACD,CAAA;AAAA,EACH;AAEA,EAAA,IAAI,iBAAiBC,qCAAA,EAA0B;AAC7C,IAAA,OAAO,IAAI,aAAA,CAAc,KAAA,CAAM,OAAA,EAAS;AAAA,MACtC,MAAA,EAAQ,GAAA;AAAA,MACR,IAAA,EAAM,MAAM,IAAA,IAAQ,wBAAA;AAAA,MACpB,OAAA,EAAS,EAAE,KAAA,EAAO,KAAA,CAAM,KAAA;AAAM,KAC/B,CAAA;AAAA,EACH;AAEA,EAAA,IAAI,iBAAiB,KAAA,EAAO;AAC1B,IAAA,OAAO,IAAI,aAAA,CAAc,KAAA,CAAM,OAAA,EAAS;AAAA,MACtC,MAAA,EAAQ,GAAA;AAAA,MACR,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,IAAI,cAAc,kBAAA,EAAoB;AAAA,IAC3C,MAAA,EAAQ,GAAA;AAAA,IACR,IAAA,EAAM;AAAA,GACP,CAAA;AACH;;;AC1BA,eAAsB,SAAA,CACpB,OACA,OAAA,EAC+B;AAC/B,EAAA,MAAM,SAAA,GAAY,QAAQ,KAAA,IAAS,KAAA;AACnC,EAAA,MAAM,EAAA,GAAK,MAAM,uBAAA,CAAwB,OAAA,CAAQ,WAAW,SAAA,EAAW;AAAA,IACrE,mBAAmB,OAAA,CAAQ;AAAA,GAC5B,CAAA;AAED,EAAA,MAAM,OAAA,GAAU,IAAI,OAAA,CAAQ,2BAAA,EAA6B;AAAA,IACvD,OAAA,EAAS;AAAA,MACP,aAAA,EAAe,UAAU,KAAK,CAAA;AAAA;AAChC,GACD,CAAA;AAED,EAAA,MAAM,QAAA,GAAoC;AAAA,IACxC,CAACL,wBAAW,GAAG;AAAA,GACjB;AACA,EAAA,IAAI,QAAQ,iBAAA,EAAmB;AAC7B,IAAA,QAAA,CAASC,kCAAqB,CAAA,GAAI,IAAA;AAAA,EACpC;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,SAAS,MAAMK,mCAAA;AAAA,MACnB,EAAA;AAAA,MACA,OAAA;AAAA,MACA,OAAA,CAAQ,QAAA;AAAA,MACR;AAAA,KACF;AAEA,IAAA,IAAI,OAAA,CAAQ,gBAAgB,MAAA,EAAQ;AAClC,MAAA,MAAM,WAAW,OAAO,MAAA,CAAO,KAAA,KAAU,QAAA,GAAW,OAAO,KAAA,GAAQ,EAAA;AACnE,MAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI,QAAA,CAAS,MAAM,KAAK,CAAA,CAAE,MAAA,CAAO,OAAO,CAAC,CAAA;AAC1D,MAAA,KAAA,MAAW,CAAA,IAAK,QAAQ,cAAA,EAAgB;AACtC,QAAA,IAAI,CAAC,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,EAAG;AAChB,UAAA,MAAM,IAAI,aAAA,CAAc,CAAA,wBAAA,EAA2B,CAAC,CAAA,CAAA,EAAI;AAAA,YACtD,MAAA,EAAQ,GAAA;AAAA,YACR,IAAA,EAAM;AAAA,WACP,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,IAAA,OAAO,MAAA;AAAA,EACT,SAAS,CAAA,EAAG;AACV,IAAA,MAAM,cAAc,CAAC,CAAA;AAAA,EACvB;AACF;;;ACrEO,SAAS,6BAAA,CACd,SACA,IAAA,EACQ;AACR,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,OAAO,EAAA;AAAA,EACT;AACA,EAAA,MAAM,MAAA,GAAS,KAAK,WAAA,EAAY;AAChC,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,MAAM,KAAK,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,EAAG;AACnD,IAAA,IAAI,GAAA,CAAI,WAAA,EAAY,KAAM,MAAA,EAAQ;AAChC,MAAA;AAAA,IACF;AACA,IAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,EAAG;AAC1B,MAAA;AAAA,IACF;AACA,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,CAAM,MAAK,EAAG;AAC7C,QAAA,OAAO,MAAM,IAAA,EAAK;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,EAAA;AACT;;;ACOA,SAAS,sBAAA,CAAuB,GAAW,CAAA,EAAoB;AAC7D,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA;AAC7B,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA;AAC7B,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,OAAA,CAAQ,MAAA,EAAQ;AACrC,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OAAOC,sBAAA,CAAgB,SAAS,OAAO,CAAA;AACzC;AAEO,SAAS,yBAAA,CAA0B,SAAkB,MAAA,EAAyB;AACnF,EAAA,IAAI,CAAC,MAAA,CAAO,IAAA,EAAK,EAAG;AAClB,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,MAAM,OAAA,GAAU,OAAO,IAAA,EAAK;AAC5B,EAAA,MAAM,OAAO,OAAA,CAAQ,OAAA,CAAQ,IAAI,eAAe,CAAA,EAAG,MAAK,IAAK,EAAA;AAC7D,EAAA,IAAI,IAAA,KAAS,CAAA,OAAA,EAAU,OAAO,CAAA,CAAA,EAAI;AAChC,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,SAAS,OAAA,CAAQ,OAAA,CAAQ,IAAI,WAAW,CAAA,EAAG,MAAK,IAAK,EAAA;AAC3D,EAAA,IAAI,MAAA,IAAU,sBAAA,CAAuB,MAAA,EAAQ,OAAO,CAAA,EAAG;AACrD,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,eAAe,OAAA,CAAQ,OAAA,CAAQ,IAAI,kBAAkB,CAAA,EAAG,MAAK,IAAK,EAAA;AACxE,EAAA,IAAI,YAAA,IAAgB,sBAAA,CAAuB,YAAA,EAAc,OAAO,CAAA,EAAG;AACjE,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,KAAA;AACT;;;ACjDO,IAAM,+BAAA,GAA+D;AAAA,EAC1E,aAAA,EAAe,WAAA;AAAA,EACf,iBAAA,EAAmB,KAAA;AAAA,EACnB,gBAAA,EAAkB;AACpB,CAAA;AAEA,SAAS,SAAA,CAAU,SAAkC,GAAA,EAAqB;AACxE,EAAA,MAAM,KAAA,GAAQ,QAAQ,GAAG,CAAA;AACzB,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,CAAM,MAAK,EAAG;AAC7C,IAAA,OAAO,MAAM,IAAA,EAAK;AAAA,EACpB;AACA,EAAA,IACE,OAAO,UAAU,QAAA,IACjB,OAAO,UAAU,SAAA,IACjB,OAAO,UAAU,QAAA,EACjB;AACA,IAAA,OAAO,KAAA,CAAM,QAAA,EAAS,CAAE,IAAA,EAAK;AAAA,EAC/B;AACA,EAAA,OAAO,EAAA;AACT;AAEO,SAAS,yBAAA,CACd,MAAA,EACA,OAAA,GAAgD,EAAC,EAClC;AACf,EAAA,MAAM,aAAA,GACJ,OAAA,CAAQ,aAAA,IAAiB,+BAAA,CAAgC,aAAA;AAC3D,EAAA,MAAM,iBAAA,GACJ,OAAA,CAAQ,iBAAA,IAAqB,+BAAA,CAAgC,iBAAA;AAC/D,EAAA,MAAM,uBAAA,GACJ,OAAA,CAAQ,gBAAA,IAAoB,+BAAA,CAAgC,gBAAA;AAE9D,EAAA,IAAI,QAAA,GAAW,SAAA,CAAU,MAAA,EAAQ,aAAa,CAAA;AAC9C,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,QAAA,GAAW,SAAA,CAAU,QAAQ,KAAK,CAAA;AAAA,EACpC;AAEA,EAAA,MAAM,YAAA,GAAe,SAAA,CAAU,MAAA,EAAQ,iBAAiB,CAAA;AACxD,EAAA,IAAI,gBAAA,GAAmB,uBAAA;AACvB,EAAA,MAAM,qBAAA,GAAwB,SAAA,CAAU,MAAA,EAAQ,oBAAoB,CAAA;AACpE,EAAA,IAAI,qBAAA,EAAuB;AACzB,IAAA,gBAAA,GAAmB,qBAAA;AAAA,EACrB;AAEA,EAAA,MAAM,QAAA,GAA0B;AAAA,IAC9B,MAAA,EAAQ,SAAA,CAAU,MAAA,EAAQ,KAAK,CAAA;AAAA,IAC/B,SAAA,EAAW,QAAA;AAAA,IACX,aAAA,EAAe,YAAA;AAAA,IACf,kBAAA,EAAoB;AAAA,GACtB;AAEA,EAAA,IAAI,CAAC,SAAS,MAAA,IAAU,CAAC,SAAS,SAAA,IAAa,CAAC,SAAS,aAAA,EAAe;AACtE,IAAA,MAAM,IAAI,cAAc,sCAAA,EAAwC;AAAA,MAC9D,MAAA,EAAQ,GAAA;AAAA,MACR,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,QAAA;AACT;AAEO,SAAS,kBAAA,CACd,MAAA,EACA,kBAAA,GAAqB,GAAA,EACb;AACR,EAAA,MAAM,MAAM,MAAA,CAAO,GAAA;AACnB,EAAA,IAAI,OAAO,GAAA,KAAQ,QAAA,IAAY,MAAA,CAAO,QAAA,CAAS,GAAG,CAAA,EAAG;AACnD,IAAA,OAAO,IAAA,CAAK,MAAM,GAAG,CAAA;AAAA,EACvB;AACA,EAAA,IAAI,OAAO,GAAA,KAAQ,QAAA,IAAY,GAAA,CAAI,MAAK,EAAG;AACzC,IAAA,MAAM,MAAA,GAAS,OAAO,GAAG,CAAA;AACzB,IAAA,IAAI,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA,EAAG;AAC3B,MAAA,OAAO,IAAA,CAAK,MAAM,MAAM,CAAA;AAAA,IAC1B;AAAA,EACF;AACA,EAAA,OAAO,KAAK,KAAA,CAAM,IAAA,CAAK,GAAA,EAAI,GAAI,GAAI,CAAA,GAAI,kBAAA;AACzC;;;AC9DA,eAAsB,6BAAA,CACpB,SACA,MAAA,EAImB;AACnB,EAAA,IAAI,CAAC,yBAAA,CAA0B,OAAA,EAAS,MAAA,CAAO,aAAa,CAAA,EAAG;AAC7D,IAAA,OAAO,IAAI,QAAA,CAAS,cAAA,EAAgB,EAAE,MAAA,EAAQ,KAAK,CAAA;AAAA,EACrD;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,uBAAA,CAAwB,MAAA,CAAO,SAAA,EAAW,MAAA,CAAO,SAAS,KAAA,EAAO;AAAA,MACrE,KAAA,EAAO,IAAA;AAAA,MACP,mBAAmB,MAAA,CAAO;AAAA,KAC3B,CAAA;AACD,IAAA,OAAO,IAAI,SAAS,IAAA,CAAK,SAAA,CAAU,EAAE,MAAA,EAAQ,IAAA,EAAM,CAAA,EAAG;AAAA,MACpD,MAAA,EAAQ,GAAA;AAAA,MACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,KAC/C,CAAA;AAAA,EACH,SAAS,GAAA,EAAK;AACZ,IAAA,MAAM,OAAA,GAAU,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,qBAAA;AACrD,IAAA,OAAO,IAAI,QAAA,CAAS,OAAA,EAAS,EAAE,MAAA,EAAQ,KAAK,CAAA;AAAA,EAC9C;AACF;AAEO,SAAS,0BACd,MAAA,EACqB;AACrB,EAAA,MAAM,YAAA,GAAe;AAAA,IACnB,GAAG,+BAAA;AAAA,IACH,GAAG,MAAA,CAAO;AAAA,GACZ;AAEA,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,MAAA;AAAA,IACN,MAAA,EAAQ,OAAO,EAAE,aAAA,EAAc,KAAM;AACnC,MAAA,MAAM,KAAA,GAAQ,6BAA6B,aAAa,CAAA;AACxD,MAAA,MAAM,QAAA,GAAW,MAAA,CAAO,WAAA,CAAY,IAAA,EAAK;AACzC,MAAA,IAAI,CAAC,QAAA,EAAU;AACb,QAAA,MAAM,IAAI,MAAM,mDAAmD,CAAA;AAAA,MACrE;AAEA,MAAA,MAAM,MAAA,GAAS,MAAM,SAAA,CAAU,KAAA,EAAO;AAAA,QACpC,WAAW,MAAA,CAAO,SAAA;AAAA,QAClB,QAAA;AAAA,QACA,OAAO,MAAA,CAAO,KAAA;AAAA,QACd,mBAAmB,MAAA,CAAO,iBAAA;AAAA,QAC1B,gBAAgB,MAAA,CAAO;AAAA,OACxB,CAAA;AAED,MAAA,MAAM,YAAA,GAAe,MAAA;AACrB,MAAA,MAAM,QAAA,GAAW,yBAAA,CAA0B,YAAA,EAAc,YAAY,CAAA;AAErE,MAAA,OAAO;AAAA,QACL,QAAA;AAAA,QACA,MAAA,EAAQ,mBAAmB,YAAY,CAAA;AAAA,QACvC,GAAA,EAAK;AAAA,OACP;AAAA,IACF,CAAA;AAAA,IACA,WAAA,EAAa;AAAA,MACX;AAAA,QACE,MAAA,EAAQ,MAAA;AAAA,QACR,QAAA,EAAU,qBAAA;AAAA,QACV,OAAA,EAAS,CAAC,OAAA,KAAY,6BAAA,CAA8B,SAAS,MAAM;AAAA;AACrE;AACF,GACF;AACF;;;ACxFO,SAAS,gCACd,SAAA,EACqB;AACrB,EAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG;AAC1B,IAAA,MAAM,IAAI,cAAc,mCAAA,EAAqC;AAAA,MAC3D,MAAA,EAAQ,GAAA;AAAA,MACR,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AAEA,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,QAAA;AAAA,IACN,MAAA,EAAQ,OAAO,OAAA,KAAY;AACzB,MAAA,IAAI,SAAA;AACJ,MAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAChC,QAAA,IAAI;AACF,UAAA,OAAO,MAAM,QAAA,CAAS,MAAA,CAAO,OAAO,CAAA;AAAA,QACtC,SAAS,GAAA,EAAK;AACZ,UAAA,SAAA,GAAY,GAAA;AAAA,QACd;AAAA,MACF;AAEA,MAAA,IAAI,qBAAqB,aAAA,EAAe;AACtC,QAAA,MAAM,SAAA;AAAA,MACR;AACA,MAAA,IAAI,qBAAqB,KAAA,EAAO;AAC9B,QAAA,MAAM,IAAI,aAAA,CAAc,SAAA,CAAU,OAAA,EAAS;AAAA,UACzC,MAAA,EAAQ,GAAA;AAAA,UACR,IAAA,EAAM;AAAA,SACP,CAAA;AAAA,MACH;AACA,MAAA,MAAM,IAAI,cAAc,qBAAA,EAAuB;AAAA,QAC7C,MAAA,EAAQ,GAAA;AAAA,QACR,IAAA,EAAM;AAAA,OACP,CAAA;AAAA,IACH,CAAA;AAAA,IACA,WAAA,EAAa,UAAU,OAAA,CAAQ,CAAC,aAAa,QAAA,CAAS,WAAA,IAAe,EAAE;AAAA,GACzE;AACF;;;ACpCO,IAAM,2BAAA,GAA8B;AAAA,EACzC,MAAA,EAAQ,yBAAA;AAAA,EACR,QAAA,EAAU,sBAAA;AAAA,EACV,YAAA,EAAc,0BAAA;AAAA,EACd,gBAAA,EAAkB;AACpB,CAAA;AASA,SAAS,gBAAgB,KAAA,EAAuB;AAC9C,EAAA,IAAI,MAAM,KAAA,CAAM,MAAA;AAChB,EAAA,OAAO,MAAM,CAAA,IAAK,KAAA,CAAM,GAAA,GAAM,CAAC,MAAM,GAAA,EAAK;AACxC,IAAA,GAAA,IAAO,CAAA;AAAA,EACT;AACA,EAAA,OAAO,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,GAAG,CAAA;AAC3B;AAEO,SAAS,0BAAA,CACd,SACA,MAAA,EACe;AACf,EAAA,MAAM,KAAA,GAAQ;AAAA,IACZ,GAAG,2BAAA;AAAA,IACH,GAAG,MAAA,CAAO;AAAA,GACZ;AACA,EAAA,MAAM,MAAA,GAAS,6BAAA,CAA8B,OAAA,EAAS,KAAA,CAAM,MAAM,CAAA;AAClE,EAAA,MAAM,QAAA,GAAW,6BAAA,CAA8B,OAAA,EAAS,KAAA,CAAM,QAAQ,CAAA;AACtE,EAAA,MAAM,YAAA,GAAe,6BAAA,CAA8B,OAAA,EAAS,KAAA,CAAM,YAAY,CAAA;AAC9E,EAAA,MAAM,gBAAA,GACJ,6BAAA,CAA8B,OAAA,EAAS,KAAA,CAAM,gBAAgB,CAAA,IAC7D,kBAAA;AAEF,EAAA,IAAI,CAAC,MAAA,IAAU,CAAC,QAAA,IAAY,CAAC,YAAA,EAAc;AACzC,IAAA,MAAM,IAAI,cAAc,wCAAA,EAA0C;AAAA,MAChE,MAAA,EAAQ,GAAA;AAAA,MACR,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AAEA,EAAA,IACE,eAAA,CAAgB,MAAM,CAAA,KAAM,eAAA,CAAgB,OAAO,cAAA,CAAe,IAAA,EAAM,CAAA,EACxE;AACA,IAAA,MAAM,IAAI,cAAc,+BAAA,EAAiC;AAAA,MACvD,MAAA,EAAQ,GAAA;AAAA,MACR,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AAEA,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA,SAAA,EAAW,QAAA;AAAA,IACX,aAAA,EAAe,YAAA;AAAA,IACf,kBAAA,EAAoB;AAAA,GACtB;AACF;AAEO,SAAS,oCACd,MAAA,EACqB;AACrB,EAAA,MAAM,gBAAA,GAAmB,OAAO,gBAAA,IAAoB,GAAA;AAEpD,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,iBAAA;AAAA,IACN,MAAA,EAAQ,OAAO,EAAE,OAAA,EAAQ,KAAM;AAC7B,MAAA,MAAM,QAAA,GAAW,0BAAA,CAA2B,OAAA,CAAQ,OAAA,EAAS,MAAM,CAAA;AACnE,MAAA,OAAO;AAAA,QACL,QAAA;AAAA,QACA,QAAQ,IAAA,CAAK,KAAA,CAAM,KAAK,GAAA,EAAI,GAAI,GAAI,CAAA,GAAI;AAAA,OAC1C;AAAA,IACF;AAAA,GACF;AACF;;;ACnEA,SAAS,OAAA,CAAQ,KAAwB,GAAA,EAAiC;AACxE,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,GAAG,CAAA,EAAG,IAAA,EAAK;AAC7B,EAAA,OAAO,KAAA,IAAS,MAAA;AAClB;AAaO,SAAS,oCACd,KAAA,EAC2B;AAC3B,EAAA,MAAM,EAAE,WAAA,EAAa,GAAG,UAAA,EAAW,GAAI,KAAA;AACvC,EAAA,OAAO;AAAA,IACL,eAAe,UAAA,CAAW,aAAA;AAAA,IAC1B,WAAA,EAAa,0BAA0B,UAAU,CAAA;AAAA,IACjD;AAAA,GACF;AACF;AAOO,SAAS,yCACd,KAAA,EAC2B;AAC3B,EAAA,MAAM;AAAA,IACJ,WAAA;AAAA,IACA,iBAAA,GAAoB,IAAA;AAAA,IACpB,cAAA;AAAA,IACA,GAAG;AAAA,GACL,GAAI,KAAA;AACJ,EAAA,MAAM,YAAA,GAAe,0BAA0B,UAAU,CAAA;AACzD,EAAA,MAAM,WAAA,GACJ,iBAAA,KAAsB,KAAA,GAClB,YAAA,GACA,+BAAA,CAAgC;AAAA,IAC9B,mCAAA,CAAoC;AAAA,MAClC,gBAAgB,UAAA,CAAW,SAAA;AAAA,MAC3B,GAAG;AAAA,KACJ,CAAA;AAAA,IACD;AAAA,GACD,CAAA;AAEP,EAAA,OAAO;AAAA,IACL,eAAe,UAAA,CAAW,aAAA;AAAA,IAC1B,WAAA;AAAA,IACA;AAAA,GACF;AACF;AAEO,SAAS,wCAAA,CACd,GAAA,GAAyB,OAAA,CAAQ,GAAA,EACN;AAC3B,EAAA,MAAM,aAAA,GAAgB,OAAA,CAAQ,GAAA,EAAK,gBAAgB,CAAA;AACnD,EAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,GAAA,EAAK,YAAY,CAAA;AAC3C,EAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,GAAA,EAAK,cAAc,CAAA,IAAK,SAAA;AAEpD,EAAA,IAAI,CAAC,aAAA,EAAe;AAClB,IAAA,MAAM,IAAI,MAAM,4BAA4B,CAAA;AAAA,EAC9C;AACA,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,MAAM,IAAI,MAAM,wBAAwB,CAAA;AAAA,EAC1C;AACA,EAAA,IAAI,CAAC,WAAA,EAAa;AAChB,IAAA,MAAM,IAAI,MAAM,0BAA0B,CAAA;AAAA,EAC5C;AAEA,EAAA,OAAO,wCAAA,CAAyC;AAAA,IAC9C,aAAA;AAAA,IACA,SAAA;AAAA,IACA,WAAA;AAAA,IACA,YAAA,EAAc;AAAA,MACZ,aAAA,EAAe,OAAA,CAAQ,GAAA,EAAK,iBAAiB,CAAA,IAAK,WAAA;AAAA,MAClD,iBAAA,EAAmB,OAAA,CAAQ,GAAA,EAAK,qBAAqB,CAAA,IAAK,KAAA;AAAA,MAC1D,gBAAA,EAAkB,OAAA,CAAQ,GAAA,EAAK,oBAAoB,CAAA,IAAK;AAAA,KAC1D;AAAA,IACA,iBAAA,EAAmB,OAAA,CAAQ,GAAA,EAAK,qBAAqB,CAAA,KAAM;AAAA,GAC5D,CAAA;AACH;AAGO,IAAM,oCAAA,GACX","file":"oidc.cjs","sourcesContent":["export function bearerTokenFromAuthorization(authorization: string): string {\n const trimmed = authorization.trim();\n if (!trimmed) {\n throw new Error(\"missing authorization\");\n }\n const prefix = \"Bearer \";\n if (!trimmed.startsWith(prefix)) {\n throw new Error(\"authorization must be Bearer token\");\n }\n const token = trimmed.slice(prefix.length).trim();\n if (!token) {\n throw new Error(\"empty bearer token\");\n }\n return token;\n}\n","export class PmtHouseError extends Error {\n readonly status: number;\n readonly code: string;\n readonly details?: unknown;\n\n constructor(\n message: string,\n {\n status = 500,\n code = \"pymthouse_error\",\n details,\n }: {\n status?: number;\n code?: string;\n details?: unknown;\n } = {},\n ) {\n super(message);\n this.name = \"PmtHouseError\";\n this.status = status;\n this.code = code;\n this.details = details;\n }\n}\n\nexport function toPmtHouseError(\n error: unknown,\n fallbackMessage: string,\n): PmtHouseError {\n if (error instanceof PmtHouseError) {\n return error;\n }\n\n if (error instanceof Error) {\n return new PmtHouseError(error.message || fallbackMessage, {\n code: \"unexpected_error\",\n status: 500,\n });\n }\n\n return new PmtHouseError(fallbackMessage, {\n code: \"unexpected_error\",\n status: 500,\n });\n}\n","/** Removes trailing `/` without regex (linear time). */\nexport function stripTrailingSlashes(value: string): string {\n let end = value.length;\n while (end > 0 && (value.codePointAt(end - 1) ?? 0) === 47) {\n end--;\n }\n return value.slice(0, end);\n}\n\nfunction endsWithIgnoreCase(value: string, suffix: string): boolean {\n if (suffix.length > value.length) {\n return false;\n }\n const start = value.length - suffix.length;\n for (let i = 0; i < suffix.length; i++) {\n const a = value.codePointAt(start + i) ?? 0;\n const b = suffix.codePointAt(i) ?? 0;\n if (a !== b && (a | 32) !== (b | 32)) {\n return false;\n }\n }\n return true;\n}\n\nfunction stripSuffixIgnoreCase(value: string, suffix: string): string {\n return endsWithIgnoreCase(value, suffix)\n ? value.slice(0, value.length - suffix.length)\n : value;\n}\n\n/** Issuer URL (`…/oidc`) → Builder API base (`…/api/v1`). Linear-time; no regex. */\nexport function stripOidcPathSuffix(issuerUrl: string): string {\n let base = stripTrailingSlashes(issuerUrl.trim());\n base = stripSuffixIgnoreCase(base, \"/oidc\");\n return stripTrailingSlashes(base);\n}\n\n/** Issuer URL (`…/api/v1/oidc`) → host origin for signer/API-key routes. Linear-time; no regex. */\nexport function stripIssuerOriginFromOidcUrl(issuerUrl: string): string {\n let base = stripTrailingSlashes(issuerUrl.trim());\n base = stripSuffixIgnoreCase(base, \"/api/v1/oidc\");\n base = stripSuffixIgnoreCase(base, \"/oidc\");\n return stripTrailingSlashes(base);\n}\n\n/** Parse and validate an http(s) facade origin (no path). */\nexport function parseHttpOrigin(raw: string | undefined, fallback: string): string {\n const trimmed = (raw ?? fallback).trim();\n let parsed: URL;\n try {\n parsed = new URL(trimmed);\n } catch {\n throw new TypeError(\"Origin must be a valid http(s) URL\");\n }\n if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n throw new TypeError(\"Origin must use http or https\");\n }\n return parsed.origin;\n}\n\n","import {\n allowInsecureRequests,\n customFetch,\n discoveryRequest,\n processDiscoveryResponse,\n type AuthorizationServer,\n} from \"oauth4webapi\";\nimport { PmtHouseError } from \"./errors.js\";\nimport { stripTrailingSlashes } from \"./string-utils.js\";\nimport type { FetchLike, OidcDiscoveryDocument } from \"./types.js\";\n\nexport function authorizationServerToOidcDocument(as: AuthorizationServer): OidcDiscoveryDocument {\n const tokenEndpoint = as.token_endpoint;\n const jwksUri = as.jwks_uri;\n if (!tokenEndpoint || !jwksUri) {\n throw new PmtHouseError(\"OIDC discovery document is missing token_endpoint or jwks_uri\", {\n status: 500,\n code: \"oidc_discovery_invalid\",\n });\n }\n return {\n issuer: as.issuer,\n authorization_endpoint: as.authorization_endpoint ?? \"\",\n token_endpoint: tokenEndpoint,\n jwks_uri: jwksUri,\n userinfo_endpoint: as.userinfo_endpoint,\n device_authorization_endpoint: as.device_authorization_endpoint,\n };\n}\n\nconst CACHE_TTL_MS = 5 * 60 * 1000;\n\ntype CacheEntry = {\n as: AuthorizationServer;\n fetchedAt: number;\n};\n\nconst discoveryCache = new Map<string, CacheEntry>();\n\nfunction normalizedIssuerKey(issuerUrl: string): string {\n return stripTrailingSlashes(issuerUrl);\n}\n\nexport interface LoadAuthorizationServerOptions {\n force?: boolean;\n allowInsecureHttp?: boolean;\n}\n\n/**\n * Loads OIDC discovery metadata via oauth4webapi (RFC 8414 / OIDC Discovery), with a 5-minute cache.\n */\nexport async function loadAuthorizationServer(\n issuerUrl: string,\n fetchImpl: FetchLike,\n options: LoadAuthorizationServerOptions = {},\n): Promise<AuthorizationServer> {\n const key = normalizedIssuerKey(issuerUrl);\n const now = Date.now();\n const cached = discoveryCache.get(key);\n\n if (!options.force && cached && now - cached.fetchedAt < CACHE_TTL_MS) {\n return cached.as;\n }\n\n const issuerIdentifier = new URL(key);\n const discoveryOpts: Parameters<typeof discoveryRequest>[1] = {\n algorithm: \"oidc\",\n [customFetch]: fetchImpl,\n };\n if (options.allowInsecureHttp) {\n discoveryOpts[allowInsecureRequests] = true;\n }\n\n let response: Response;\n try {\n response = await discoveryRequest(issuerIdentifier, discoveryOpts);\n } catch (e) {\n throw mapDiscoveryNetworkError(e);\n }\n\n let as: AuthorizationServer;\n try {\n as = await processDiscoveryResponse(issuerIdentifier, response);\n } catch (e) {\n throw mapOAuthDiscoveryError(e);\n }\n\n discoveryCache.set(key, { as, fetchedAt: now });\n return as;\n}\n\nexport async function fetchDiscoveryDocument(\n issuerUrl: string,\n fetchImpl: FetchLike,\n options: LoadAuthorizationServerOptions = {},\n): Promise<OidcDiscoveryDocument> {\n const as = await loadAuthorizationServer(issuerUrl, fetchImpl, options);\n return authorizationServerToOidcDocument(as);\n}\n\nexport function clearDiscoveryCache(issuerUrl?: string): void {\n if (!issuerUrl) {\n discoveryCache.clear();\n return;\n }\n discoveryCache.delete(normalizedIssuerKey(issuerUrl));\n}\n\nfunction mapOAuthDiscoveryError(error: unknown): PmtHouseError {\n if (error instanceof PmtHouseError) {\n return error;\n }\n if (error instanceof Error) {\n return new PmtHouseError(error.message, {\n status: 500,\n code: \"oidc_discovery_invalid\",\n details: { cause: error.cause },\n });\n }\n return new PmtHouseError(\"OIDC discovery failed\", {\n status: 500,\n code: \"oidc_discovery_invalid\",\n });\n}\n\nfunction mapDiscoveryNetworkError(error: unknown): PmtHouseError {\n if (error instanceof PmtHouseError) {\n return error;\n }\n if (error instanceof Error) {\n return new PmtHouseError(`Failed to load OIDC discovery: ${error.message}`, {\n status: 502,\n code: \"oidc_discovery_failed\",\n });\n }\n return new PmtHouseError(\"Failed to load OIDC discovery\", {\n status: 502,\n code: \"oidc_discovery_failed\",\n });\n}\n","import { type Client, OperationProcessingError, ResponseBodyError } from \"oauth4webapi\";\nimport { PmtHouseError } from \"./errors.js\";\nimport type { ClientCredentialsTokenResponse, TokenExchangeResponse } from \"./types.js\";\n\nconst ACCEPTED_ISSUED_TOKEN_TYPES = new Set([\n \"urn:ietf:params:oauth:token-type:access_token\",\n \"urn:pmth:token-type:remote-signer-session\",\n]);\n\nexport function mapOAuthError(error: unknown): PmtHouseError {\n if (error instanceof PmtHouseError) {\n return error;\n }\n\n if (error instanceof ResponseBodyError) {\n const cause = error.cause as Record<string, unknown>;\n const description =\n typeof error.error_description === \"string\"\n ? error.error_description\n : error.message;\n const details: Record<string, unknown> = { ...cause };\n if (typeof cause.error_uri === \"string\") {\n details.error_uri = cause.error_uri;\n }\n return new PmtHouseError(description, {\n status: error.status,\n code: error.error,\n details,\n });\n }\n\n if (error instanceof OperationProcessingError) {\n return new PmtHouseError(error.message, {\n status: 502,\n code: error.code ?? \"oauth_processing_error\",\n details: { cause: error.cause },\n });\n }\n\n if (error instanceof Error) {\n return new PmtHouseError(error.message, {\n status: 500,\n code: \"unexpected_error\",\n });\n }\n\n return new PmtHouseError(\"Unexpected error\", {\n status: 500,\n code: \"unexpected_error\",\n });\n}\n\nexport function tokenEndpointResponseToExchange(\n tr: import(\"oauth4webapi\").TokenEndpointResponse,\n): TokenExchangeResponse {\n const issued = tr.issued_token_type;\n if (typeof issued !== \"string\" || !ACCEPTED_ISSUED_TOKEN_TYPES.has(issued)) {\n throw new PmtHouseError(\"Token exchange returned an unexpected issued_token_type\", {\n status: 502,\n code: \"invalid_token_response\",\n details: { issued_token_type: issued },\n });\n }\n\n const tt = tr.token_type;\n if (typeof tt !== \"string\" || tt.toLowerCase() !== \"bearer\") {\n throw new PmtHouseError(\"Token endpoint returned a non-Bearer token_type\", {\n status: 502,\n code: \"invalid_token_response\",\n details: { token_type: tt },\n });\n }\n\n const expiresIn = tr.expires_in;\n if (typeof expiresIn !== \"number\") {\n throw new PmtHouseError(\"Token response missing expires_in\", {\n status: 502,\n code: \"invalid_token_response\",\n });\n }\n\n const scope = typeof tr.scope === \"string\" ? tr.scope : \"\";\n\n return {\n access_token: tr.access_token,\n token_type: \"Bearer\",\n expires_in: expiresIn,\n scope,\n issued_token_type: issued,\n };\n}\n\nexport function tokenEndpointResponseToClientCredentials(\n tr: import(\"oauth4webapi\").TokenEndpointResponse,\n): ClientCredentialsTokenResponse {\n const tt = tr.token_type;\n if (typeof tt !== \"string\" || tt.toLowerCase() !== \"bearer\") {\n throw new PmtHouseError(\"Token endpoint returned a non-Bearer token_type\", {\n status: 502,\n code: \"invalid_token_response\",\n details: { token_type: tt },\n });\n }\n\n return {\n access_token: tr.access_token,\n token_type: \"Bearer\",\n expires_in: tr.expires_in,\n scope: typeof tr.scope === \"string\" ? tr.scope : undefined,\n };\n}\n\nexport function m2mClient(clientId: string): Client {\n return { client_id: clientId };\n}\n","import {\n allowInsecureRequests,\n customFetch,\n validateJwtAccessToken,\n type JWTAccessTokenClaims,\n} from \"oauth4webapi\";\nimport { loadAuthorizationServer } from \"./discovery.js\";\nimport { PmtHouseError } from \"./errors.js\";\nimport { mapOAuthError } from \"./oauth-map.js\";\nimport type { FetchLike } from \"./types.js\";\n\nexport interface VerifyJwtOptions {\n issuerUrl: string;\n /** Expected JWT `aud` (resource identifier). */\n audience: string;\n fetch?: FetchLike;\n allowInsecureHttp?: boolean;\n /** If set, every scope here must appear in the token's `scope` claim (space-separated). */\n requiredScopes?: string[];\n}\n\n/**\n * RFC 9068 / RFC 6750: validate a JWT access token using issuer JWKS via oauth4webapi.\n */\nexport async function verifyJwt(\n token: string,\n options: VerifyJwtOptions,\n): Promise<JWTAccessTokenClaims> {\n const fetchImpl = options.fetch ?? fetch;\n const as = await loadAuthorizationServer(options.issuerUrl, fetchImpl, {\n allowInsecureHttp: options.allowInsecureHttp,\n });\n\n const request = new Request(\"https://resource.invalid/\", {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n const httpOpts: Record<symbol, unknown> = {\n [customFetch]: fetchImpl,\n };\n if (options.allowInsecureHttp) {\n httpOpts[allowInsecureRequests] = true;\n }\n\n try {\n const claims = await validateJwtAccessToken(\n as,\n request,\n options.audience,\n httpOpts as import(\"oauth4webapi\").ValidateJWTAccessTokenOptions,\n );\n\n if (options.requiredScopes?.length) {\n const scopeStr = typeof claims.scope === \"string\" ? claims.scope : \"\";\n const have = new Set(scopeStr.split(/\\s+/).filter(Boolean));\n for (const s of options.requiredScopes) {\n if (!have.has(s)) {\n throw new PmtHouseError(`Missing required scope: ${s}`, {\n status: 403,\n code: \"insufficient_scope\",\n });\n }\n }\n }\n\n return claims;\n } catch (e) {\n throw mapOAuthError(e);\n }\n}\n","import type { PaymentWebhookRequest } from \"./types.js\";\n\nexport function headerValueFromWebhookPayload(\n headers: Record<string, string[]> | undefined,\n name: string,\n): string {\n if (!headers) {\n return \"\";\n }\n const target = name.toLowerCase();\n for (const [key, values] of Object.entries(headers)) {\n if (key.toLowerCase() !== target) {\n continue;\n }\n if (!Array.isArray(values)) {\n continue;\n }\n for (const value of values) {\n if (typeof value === \"string\" && value.trim()) {\n return value.trim();\n }\n }\n }\n return \"\";\n}\n\n/** End-user Authorization from go-livepeer webhook body (headers map or legacy field). */\nexport function authorizationFromWebhookPayload(\n payload: PaymentWebhookRequest,\n): string {\n const fromHeaders = headerValueFromWebhookPayload(\n payload.headers,\n \"Authorization\",\n );\n if (fromHeaders) {\n return fromHeaders;\n }\n return payload.authorization?.trim() ?? \"\";\n}\n","import { timingSafeEqual } from \"node:crypto\";\nimport { PmtHouseError } from \"../../errors.js\";\nimport { authorizationFromWebhookPayload } from \"./payload.js\";\nimport type { PaymentWebhookRequest, PaymentWebhookResponse } from \"./types.js\";\nimport type { EndUserAuthVerifier, VerifiedEndUserAuth } from \"./verifier.js\";\n\nexport type {\n EndUserAuthVerifier,\n EndUserAuthVerifyContext,\n VerifiedEndUserAuth,\n WebhookAdminRoute,\n} from \"./verifier.js\";\n\nexport type WebhookAuthorizeContext = {\n authorization: string;\n payload: PaymentWebhookRequest;\n request: Request;\n verified: VerifiedEndUserAuth;\n identity: VerifiedEndUserAuth[\"identity\"];\n};\n\nexport type RemoteSignerWebhookConfig = {\n webhookSecret: string;\n endUserAuth: EndUserAuthVerifier;\n afterVerify?: (context: WebhookAuthorizeContext) => Promise<void>;\n};\n\nfunction authIdFromIdentity(identity: VerifiedEndUserAuth[\"identity\"]): string {\n return `${identity.client_id}:${identity.usage_subject}`;\n}\n\nfunction timingSafeEqualStrings(a: string, b: string): boolean {\n const aBuffer = Buffer.from(a);\n const bBuffer = Buffer.from(b);\n if (aBuffer.length !== bBuffer.length) {\n return false;\n }\n return timingSafeEqual(aBuffer, bBuffer);\n}\n\nexport function authenticateWebhookCaller(request: Request, secret: string): boolean {\n if (!secret.trim()) {\n return false;\n }\n const trimmed = secret.trim();\n const auth = request.headers.get(\"authorization\")?.trim() ?? \"\";\n if (auth === `Bearer ${trimmed}`) {\n return true;\n }\n const apiKey = request.headers.get(\"x-api-key\")?.trim() ?? \"\";\n if (apiKey && timingSafeEqualStrings(apiKey, trimmed)) {\n return true;\n }\n const legacySecret = request.headers.get(\"x-webhook-secret\")?.trim() ?? \"\";\n if (legacySecret && timingSafeEqualStrings(legacySecret, trimmed)) {\n return true;\n }\n return false;\n}\n\nfunction paymentWebhookJson(\n httpStatus: number,\n body: PaymentWebhookResponse,\n): Response {\n return new Response(JSON.stringify(body), {\n status: httpStatus,\n headers: { \"Content-Type\": \"application/json\" },\n });\n}\n\nfunction rejectStatusFromError(err: unknown): { status: number; reason: string } {\n if (err instanceof PmtHouseError) {\n return {\n status: err.status >= 400 && err.status < 600 ? err.status : 403,\n reason: err.message,\n };\n }\n const reason = err instanceof Error ? err.message : \"authorization rejected\";\n return { status: 403, reason };\n}\n\nexport async function handleRemoteSignerAuthorize(\n request: Request,\n config: RemoteSignerWebhookConfig,\n): Promise<Response> {\n if (!authenticateWebhookCaller(request, config.webhookSecret)) {\n return paymentWebhookJson(401, {\n status: 401,\n reason: \"unauthorized webhook caller\",\n });\n }\n\n let payload: PaymentWebhookRequest;\n try {\n payload = (await request.json()) as PaymentWebhookRequest;\n } catch {\n return paymentWebhookJson(400, {\n status: 400,\n reason: \"invalid request json\",\n });\n }\n\n const authorization = authorizationFromWebhookPayload(payload) ?? \"\";\n\n try {\n const verified = await config.endUserAuth.verify({\n authorization,\n payload,\n request,\n });\n\n if (config.afterVerify) {\n await config.afterVerify({\n authorization,\n payload,\n request,\n verified,\n identity: verified.identity,\n });\n }\n\n return paymentWebhookJson(200, {\n status: 200,\n expiry: verified.expiry,\n auth_id: authIdFromIdentity(verified.identity),\n identity: verified.identity,\n });\n } catch (err) {\n const { status, reason } = rejectStatusFromError(err);\n return paymentWebhookJson(200, {\n status,\n reason,\n });\n }\n}\n\nexport function createRemoteSignerAuthorizeHandler(\n config: RemoteSignerWebhookConfig,\n): (request: Request) => Promise<Response> {\n return (request) => handleRemoteSignerAuthorize(request, config);\n}\n\nexport async function routeRemoteSignerWebhookRequest(\n request: Request,\n config: RemoteSignerWebhookConfig,\n): Promise<Response | null> {\n const url = new URL(request.url);\n if (request.method === \"POST\" && url.pathname === \"/authorize\") {\n return handleRemoteSignerAuthorize(request, config);\n }\n\n const adminRoutes = config.endUserAuth.adminRoutes ?? [];\n for (const route of adminRoutes) {\n if (request.method === route.method && url.pathname === route.pathname) {\n return route.handler(request);\n }\n }\n\n return null;\n}\n","import { PmtHouseError } from \"../../errors.js\";\nimport type { UsageIdentity } from \"./types.js\";\n\nexport type WebhookIdentityClaimMapping = {\n claimClientId: string;\n claimUsageSubject: string;\n usageSubjectType: string;\n};\n\nexport const DEFAULT_WEBHOOK_IDENTITY_CLAIMS: WebhookIdentityClaimMapping = {\n claimClientId: \"client_id\",\n claimUsageSubject: \"sub\",\n usageSubjectType: \"external_user_id\",\n};\n\nfunction readClaim(payload: Record<string, unknown>, key: string): string {\n const value = payload[key];\n if (typeof value === \"string\" && value.trim()) {\n return value.trim();\n }\n if (\n typeof value === \"number\" ||\n typeof value === \"boolean\" ||\n typeof value === \"bigint\"\n ) {\n return value.toString().trim();\n }\n return \"\";\n}\n\nexport function identityFromWebhookClaims(\n claims: Record<string, unknown>,\n mapping: Partial<WebhookIdentityClaimMapping> = {},\n): UsageIdentity {\n const claimClientId =\n mapping.claimClientId ?? DEFAULT_WEBHOOK_IDENTITY_CLAIMS.claimClientId;\n const claimUsageSubject =\n mapping.claimUsageSubject ?? DEFAULT_WEBHOOK_IDENTITY_CLAIMS.claimUsageSubject;\n const defaultUsageSubjectType =\n mapping.usageSubjectType ?? DEFAULT_WEBHOOK_IDENTITY_CLAIMS.usageSubjectType;\n\n let clientId = readClaim(claims, claimClientId);\n if (!clientId) {\n clientId = readClaim(claims, \"azp\");\n }\n\n const usageSubject = readClaim(claims, claimUsageSubject);\n let usageSubjectType = defaultUsageSubjectType;\n const claimUsageSubjectType = readClaim(claims, \"usage_subject_type\");\n if (claimUsageSubjectType) {\n usageSubjectType = claimUsageSubjectType;\n }\n\n const identity: UsageIdentity = {\n issuer: readClaim(claims, \"iss\"),\n client_id: clientId,\n usage_subject: usageSubject,\n usage_subject_type: usageSubjectType,\n };\n\n if (!identity.issuer || !identity.client_id || !identity.usage_subject) {\n throw new PmtHouseError(\"JWT missing required identity claims\", {\n status: 403,\n code: \"invalid_identity\",\n });\n }\n\n return identity;\n}\n\nexport function claimExpirySeconds(\n claims: Record<string, unknown>,\n fallbackTtlSeconds = 300,\n): number {\n const exp = claims.exp;\n if (typeof exp === \"number\" && Number.isFinite(exp)) {\n return Math.trunc(exp);\n }\n if (typeof exp === \"string\" && exp.trim()) {\n const parsed = Number(exp);\n if (Number.isFinite(parsed)) {\n return Math.trunc(parsed);\n }\n }\n return Math.trunc(Date.now() / 1000) + fallbackTtlSeconds;\n}\n","import { loadAuthorizationServer } from \"../../../../discovery.js\";\nimport { verifyJwt } from \"../../../../verify.js\";\nimport type { FetchLike } from \"../../../../types.js\";\nimport { authenticateWebhookCaller } from \"../../authorize.js\";\nimport {\n claimExpirySeconds,\n DEFAULT_WEBHOOK_IDENTITY_CLAIMS,\n identityFromWebhookClaims,\n type WebhookIdentityClaimMapping,\n} from \"../../identity.js\";\nimport { bearerTokenFromAuthorization } from \"../../bearer.js\";\nimport type { EndUserAuthVerifier } from \"../../verifier.js\";\n\nexport type OidcEndUserAuthConfig = {\n jwtIssuer: string;\n jwtAudience: string;\n claimMapping?: Partial<WebhookIdentityClaimMapping>;\n allowInsecureHttp?: boolean;\n fetch?: FetchLike;\n requiredScopes?: string[];\n webhookSecret: string;\n};\n\nexport async function handleRemoteSignerRefreshJwks(\n request: Request,\n config: Pick<\n OidcEndUserAuthConfig,\n \"webhookSecret\" | \"jwtIssuer\" | \"fetch\" | \"allowInsecureHttp\"\n >,\n): Promise<Response> {\n if (!authenticateWebhookCaller(request, config.webhookSecret)) {\n return new Response(\"unauthorized\", { status: 401 });\n }\n\n try {\n await loadAuthorizationServer(config.jwtIssuer, config.fetch ?? fetch, {\n force: true,\n allowInsecureHttp: config.allowInsecureHttp,\n });\n return new Response(JSON.stringify({ status: \"ok\" }), {\n status: 200,\n headers: { \"Content-Type\": \"application/json\" },\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : \"jwks refresh failed\";\n return new Response(message, { status: 500 });\n }\n}\n\nexport function createOidcEndUserVerifier(\n config: OidcEndUserAuthConfig,\n): EndUserAuthVerifier {\n const claimMapping = {\n ...DEFAULT_WEBHOOK_IDENTITY_CLAIMS,\n ...config.claimMapping,\n };\n\n return {\n kind: \"oidc\",\n verify: async ({ authorization }) => {\n const token = bearerTokenFromAuthorization(authorization);\n const audience = config.jwtAudience.trim();\n if (!audience) {\n throw new Error(\"jwt audience is required for webhook verification\");\n }\n\n const claims = await verifyJwt(token, {\n issuerUrl: config.jwtIssuer,\n audience,\n fetch: config.fetch,\n allowInsecureHttp: config.allowInsecureHttp,\n requiredScopes: config.requiredScopes,\n });\n\n const claimsRecord = claims as unknown as Record<string, unknown>;\n const identity = identityFromWebhookClaims(claimsRecord, claimMapping);\n\n return {\n identity,\n expiry: claimExpirySeconds(claimsRecord),\n raw: claimsRecord,\n };\n },\n adminRoutes: [\n {\n method: \"POST\",\n pathname: \"/admin/refresh-jwks\",\n handler: (request) => handleRemoteSignerRefreshJwks(request, config),\n },\n ],\n };\n}\n","import { PmtHouseError } from \"../../../../errors.js\";\nimport type { EndUserAuthVerifier } from \"../../verifier.js\";\n\nexport function createFirstMatchEndUserVerifier(\n verifiers: EndUserAuthVerifier[],\n): EndUserAuthVerifier {\n if (verifiers.length === 0) {\n throw new PmtHouseError(\"at least one verifier is required\", {\n status: 500,\n code: \"invalid_verifier_config\",\n });\n }\n\n return {\n kind: \"custom\",\n verify: async (context) => {\n let lastError: unknown;\n for (const verifier of verifiers) {\n try {\n return await verifier.verify(context);\n } catch (err) {\n lastError = err;\n }\n }\n\n if (lastError instanceof PmtHouseError) {\n throw lastError;\n }\n if (lastError instanceof Error) {\n throw new PmtHouseError(lastError.message, {\n status: 401,\n code: \"invalid_credentials\",\n });\n }\n throw new PmtHouseError(\"invalid credentials\", {\n status: 401,\n code: \"invalid_credentials\",\n });\n },\n adminRoutes: verifiers.flatMap((verifier) => verifier.adminRoutes ?? []),\n };\n}\n","import { PmtHouseError } from \"../../../../errors.js\";\nimport { headerValueFromWebhookPayload } from \"../../payload.js\";\nimport type { EndUserAuthVerifier } from \"../../verifier.js\";\nimport type { UsageIdentity } from \"../../types.js\";\n\nexport const DEFAULT_DMZ_TRUSTED_HEADERS = {\n issuer: \"X-Livepeer-Usage-Issuer\",\n clientId: \"X-Livepeer-Client-ID\",\n usageSubject: \"X-Livepeer-Usage-Subject\",\n usageSubjectType: \"X-Livepeer-Usage-Subject-Type\",\n} as const;\n\nexport type TrustedHeadersEndUserAuthConfig = {\n expectedIssuer: string;\n headerNames?: Partial<typeof DEFAULT_DMZ_TRUSTED_HEADERS>;\n /** Auth cache TTL returned to go-livepeer when headers are trusted. */\n expiryTtlSeconds?: number;\n};\n\nfunction normalizeIssuer(value: string): string {\n let end = value.length;\n while (end > 0 && value[end - 1] === \"/\") {\n end -= 1;\n }\n return value.slice(0, end);\n}\n\nexport function identityFromTrustedHeaders(\n headers: Record<string, string[]> | undefined,\n config: TrustedHeadersEndUserAuthConfig,\n): UsageIdentity {\n const names = {\n ...DEFAULT_DMZ_TRUSTED_HEADERS,\n ...config.headerNames,\n };\n const issuer = headerValueFromWebhookPayload(headers, names.issuer);\n const clientId = headerValueFromWebhookPayload(headers, names.clientId);\n const usageSubject = headerValueFromWebhookPayload(headers, names.usageSubject);\n const usageSubjectType =\n headerValueFromWebhookPayload(headers, names.usageSubjectType) ||\n \"external_user_id\";\n\n if (!issuer || !clientId || !usageSubject) {\n throw new PmtHouseError(\"missing trusted usage identity headers\", {\n status: 403,\n code: \"invalid_identity\",\n });\n }\n\n if (\n normalizeIssuer(issuer) !== normalizeIssuer(config.expectedIssuer.trim())\n ) {\n throw new PmtHouseError(\"trusted usage issuer mismatch\", {\n status: 403,\n code: \"invalid_identity\",\n });\n }\n\n return {\n issuer,\n client_id: clientId,\n usage_subject: usageSubject,\n usage_subject_type: usageSubjectType,\n };\n}\n\nexport function createTrustedHeadersEndUserVerifier(\n config: TrustedHeadersEndUserAuthConfig,\n): EndUserAuthVerifier {\n const expiryTtlSeconds = config.expiryTtlSeconds ?? 300;\n\n return {\n kind: \"trusted_headers\",\n verify: async ({ payload }) => {\n const identity = identityFromTrustedHeaders(payload.headers, config);\n return {\n identity,\n expiry: Math.trunc(Date.now() / 1000) + expiryTtlSeconds,\n };\n },\n };\n}\n","import type {\n RemoteSignerWebhookConfig,\n WebhookAuthorizeContext,\n} from \"../../authorize.js\";\nimport { createFirstMatchEndUserVerifier } from \"../composite/verifier.js\";\nimport {\n createTrustedHeadersEndUserVerifier,\n type TrustedHeadersEndUserAuthConfig,\n} from \"../trusted-headers/verifier.js\";\nimport {\n createOidcEndUserVerifier,\n type OidcEndUserAuthConfig,\n} from \"./verifier.js\";\n\nfunction envTrim(env: NodeJS.ProcessEnv, key: string): string | undefined {\n const value = env[key]?.trim();\n return value || undefined;\n}\n\nexport type OidcRemoteSignerWebhookConfigInput = OidcEndUserAuthConfig & {\n afterVerify?: (context: WebhookAuthorizeContext) => Promise<void>;\n};\n\nexport type SignerDmzRemoteSignerWebhookConfigInput =\n OidcRemoteSignerWebhookConfigInput & {\n /** When true (default), accept Apache DMZ X-Livepeer-* identity headers. */\n dmzTrustedHeaders?: boolean;\n trustedHeaders?: Omit<TrustedHeadersEndUserAuthConfig, \"expectedIssuer\">;\n };\n\nexport function createOidcRemoteSignerWebhookConfig(\n input: OidcRemoteSignerWebhookConfigInput,\n): RemoteSignerWebhookConfig {\n const { afterVerify, ...oidcConfig } = input;\n return {\n webhookSecret: oidcConfig.webhookSecret,\n endUserAuth: createOidcEndUserVerifier(oidcConfig),\n afterVerify,\n };\n}\n\n/**\n * PymtHouse signer-dmz: Apache validates the end-user JWT (iss/aud = issuer), injects\n * X-Livepeer-* headers, and go-livepeer forwards those headers to this webhook per\n * go-livepeer remote-signer.md. Falls back to Bearer JWT verification when present.\n */\nexport function createSignerDmzRemoteSignerWebhookConfig(\n input: SignerDmzRemoteSignerWebhookConfigInput,\n): RemoteSignerWebhookConfig {\n const {\n afterVerify,\n dmzTrustedHeaders = true,\n trustedHeaders,\n ...oidcConfig\n } = input;\n const oidcVerifier = createOidcEndUserVerifier(oidcConfig);\n const endUserAuth =\n dmzTrustedHeaders === false\n ? oidcVerifier\n : createFirstMatchEndUserVerifier([\n createTrustedHeadersEndUserVerifier({\n expectedIssuer: oidcConfig.jwtIssuer,\n ...trustedHeaders,\n }),\n oidcVerifier,\n ]);\n\n return {\n webhookSecret: oidcConfig.webhookSecret,\n endUserAuth,\n afterVerify,\n };\n}\n\nexport function readOidcRemoteSignerWebhookConfigFromEnv(\n env: NodeJS.ProcessEnv = process.env,\n): RemoteSignerWebhookConfig {\n const webhookSecret = envTrim(env, \"WEBHOOK_SECRET\");\n const jwtIssuer = envTrim(env, \"JWT_ISSUER\");\n const jwtAudience = envTrim(env, \"JWT_AUDIENCE\") ?? jwtIssuer;\n\n if (!webhookSecret) {\n throw new Error(\"WEBHOOK_SECRET is required\");\n }\n if (!jwtIssuer) {\n throw new Error(\"JWT_ISSUER is required\");\n }\n if (!jwtAudience) {\n throw new Error(\"JWT_AUDIENCE is required\");\n }\n\n return createSignerDmzRemoteSignerWebhookConfig({\n webhookSecret,\n jwtIssuer,\n jwtAudience,\n claimMapping: {\n claimClientId: envTrim(env, \"CLAIM_CLIENT_ID\") ?? \"client_id\",\n claimUsageSubject: envTrim(env, \"CLAIM_USAGE_SUBJECT\") ?? \"sub\",\n usageSubjectType: envTrim(env, \"USAGE_SUBJECT_TYPE\") ?? \"external_user_id\",\n },\n allowInsecureHttp: envTrim(env, \"ALLOW_INSECURE_HTTP\") === \"1\",\n });\n}\n\n/** @deprecated Use readOidcRemoteSignerWebhookConfigFromEnv */\nexport const readRemoteSignerWebhookConfigFromEnv =\n readOidcRemoteSignerWebhookConfigFromEnv;\n"]}
1
+ {"version":3,"sources":["../../../../src/signer/webhook/bearer.ts","../../../../src/errors.ts","../../../../src/string-utils.ts","../../../../src/discovery.ts","../../../../src/oauth-map.ts","../../../../src/verify.ts","../../../../src/signer/webhook/payload.ts","../../../../src/signer/webhook/authorize.ts","../../../../src/signer/webhook/identity.ts","../../../../src/signer/webhook/adapters/oidc/verifier.ts","../../../../src/signer/webhook/adapters/composite/verifier.ts","../../../../src/signer/webhook/adapters/trusted-headers/verifier.ts","../../../../src/signer/webhook/adapters/oidc/config.ts"],"names":["customFetch","allowInsecureRequests","discoveryRequest","processDiscoveryResponse","ResponseBodyError","OperationProcessingError","validateJwtAccessToken","timingSafeEqual"],"mappings":"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","file":"oidc.cjs","sourcesContent":["const BEARER_PREFIX = \"Bearer \";\n\n/** Returns the token after `Bearer `, or null when the header is missing or not Bearer. */\nexport function optionalBearerToken(authorization: string): string | null {\n const trimmed = authorization.trim();\n if (!trimmed.startsWith(BEARER_PREFIX)) {\n return null;\n }\n const token = trimmed.slice(BEARER_PREFIX.length).trim();\n return token || null;\n}\n\nexport function bearerTokenFromAuthorization(authorization: string): string {\n const token = optionalBearerToken(authorization);\n if (token) {\n return token;\n }\n if (!authorization.trim()) {\n throw new Error(\"missing authorization\");\n }\n throw new Error(\"authorization must be Bearer token\");\n}\n","export class PmtHouseError extends Error {\n readonly status: number;\n readonly code: string;\n readonly details?: unknown;\n\n constructor(\n message: string,\n {\n status = 500,\n code = \"pymthouse_error\",\n details,\n }: {\n status?: number;\n code?: string;\n details?: unknown;\n } = {},\n ) {\n super(message);\n this.name = \"PmtHouseError\";\n this.status = status;\n this.code = code;\n this.details = details;\n }\n}\n\nexport function toPmtHouseError(\n error: unknown,\n fallbackMessage: string,\n): PmtHouseError {\n if (error instanceof PmtHouseError) {\n return error;\n }\n\n if (error instanceof Error) {\n return new PmtHouseError(error.message || fallbackMessage, {\n code: \"unexpected_error\",\n status: 500,\n });\n }\n\n return new PmtHouseError(fallbackMessage, {\n code: \"unexpected_error\",\n status: 500,\n });\n}\n","/** Removes trailing `/` without regex (linear time). */\nexport function stripTrailingSlashes(value: string): string {\n let end = value.length;\n while (end > 0 && (value.codePointAt(end - 1) ?? 0) === 47) {\n end--;\n }\n return value.slice(0, end);\n}\n\nfunction endsWithIgnoreCase(value: string, suffix: string): boolean {\n if (suffix.length > value.length) {\n return false;\n }\n const start = value.length - suffix.length;\n for (let i = 0; i < suffix.length; i++) {\n const a = value.codePointAt(start + i) ?? 0;\n const b = suffix.codePointAt(i) ?? 0;\n if (a !== b && (a | 32) !== (b | 32)) {\n return false;\n }\n }\n return true;\n}\n\nfunction stripSuffixIgnoreCase(value: string, suffix: string): string {\n return endsWithIgnoreCase(value, suffix)\n ? value.slice(0, value.length - suffix.length)\n : value;\n}\n\n/** Issuer URL (`…/oidc`) → Builder API base (`…/api/v1`). Linear-time; no regex. */\nexport function stripOidcPathSuffix(issuerUrl: string): string {\n let base = stripTrailingSlashes(issuerUrl.trim());\n base = stripSuffixIgnoreCase(base, \"/oidc\");\n return stripTrailingSlashes(base);\n}\n\n/** Issuer URL (`…/api/v1/oidc`) → host origin for signer/API-key routes. Linear-time; no regex. */\nexport function stripIssuerOriginFromOidcUrl(issuerUrl: string): string {\n let base = stripTrailingSlashes(issuerUrl.trim());\n base = stripSuffixIgnoreCase(base, \"/api/v1/oidc\");\n base = stripSuffixIgnoreCase(base, \"/oidc\");\n return stripTrailingSlashes(base);\n}\n\n/** Parse and validate an http(s) facade origin (no path). */\nexport function parseHttpOrigin(raw: string | undefined, fallback: string): string {\n const trimmed = (raw ?? fallback).trim();\n let parsed: URL;\n try {\n parsed = new URL(trimmed);\n } catch {\n throw new TypeError(\"Origin must be a valid http(s) URL\");\n }\n if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n throw new TypeError(\"Origin must use http or https\");\n }\n return parsed.origin;\n}\n\n","import {\n allowInsecureRequests,\n customFetch,\n discoveryRequest,\n processDiscoveryResponse,\n type AuthorizationServer,\n} from \"oauth4webapi\";\nimport { PmtHouseError } from \"./errors.js\";\nimport { stripTrailingSlashes } from \"./string-utils.js\";\nimport type { FetchLike, OidcDiscoveryDocument } from \"./types.js\";\n\nexport function authorizationServerToOidcDocument(as: AuthorizationServer): OidcDiscoveryDocument {\n const tokenEndpoint = as.token_endpoint;\n const jwksUri = as.jwks_uri;\n if (!tokenEndpoint || !jwksUri) {\n throw new PmtHouseError(\"OIDC discovery document is missing token_endpoint or jwks_uri\", {\n status: 500,\n code: \"oidc_discovery_invalid\",\n });\n }\n return {\n issuer: as.issuer,\n authorization_endpoint: as.authorization_endpoint ?? \"\",\n token_endpoint: tokenEndpoint,\n jwks_uri: jwksUri,\n userinfo_endpoint: as.userinfo_endpoint,\n device_authorization_endpoint: as.device_authorization_endpoint,\n };\n}\n\nconst CACHE_TTL_MS = 5 * 60 * 1000;\n\ntype CacheEntry = {\n as: AuthorizationServer;\n fetchedAt: number;\n};\n\nconst discoveryCache = new Map<string, CacheEntry>();\n\nfunction normalizedIssuerKey(issuerUrl: string): string {\n return stripTrailingSlashes(issuerUrl);\n}\n\nexport interface LoadAuthorizationServerOptions {\n force?: boolean;\n allowInsecureHttp?: boolean;\n}\n\n/**\n * Loads OIDC discovery metadata via oauth4webapi (RFC 8414 / OIDC Discovery), with a 5-minute cache.\n */\nexport async function loadAuthorizationServer(\n issuerUrl: string,\n fetchImpl: FetchLike,\n options: LoadAuthorizationServerOptions = {},\n): Promise<AuthorizationServer> {\n const key = normalizedIssuerKey(issuerUrl);\n const now = Date.now();\n const cached = discoveryCache.get(key);\n\n if (!options.force && cached && now - cached.fetchedAt < CACHE_TTL_MS) {\n return cached.as;\n }\n\n const issuerIdentifier = new URL(key);\n const discoveryOpts: Parameters<typeof discoveryRequest>[1] = {\n algorithm: \"oidc\",\n [customFetch]: fetchImpl,\n };\n if (options.allowInsecureHttp) {\n discoveryOpts[allowInsecureRequests] = true;\n }\n\n let response: Response;\n try {\n response = await discoveryRequest(issuerIdentifier, discoveryOpts);\n } catch (e) {\n throw mapDiscoveryNetworkError(e);\n }\n\n let as: AuthorizationServer;\n try {\n as = await processDiscoveryResponse(issuerIdentifier, response);\n } catch (e) {\n throw mapOAuthDiscoveryError(e);\n }\n\n discoveryCache.set(key, { as, fetchedAt: now });\n return as;\n}\n\nexport async function fetchDiscoveryDocument(\n issuerUrl: string,\n fetchImpl: FetchLike,\n options: LoadAuthorizationServerOptions = {},\n): Promise<OidcDiscoveryDocument> {\n const as = await loadAuthorizationServer(issuerUrl, fetchImpl, options);\n return authorizationServerToOidcDocument(as);\n}\n\nexport function clearDiscoveryCache(issuerUrl?: string): void {\n if (!issuerUrl) {\n discoveryCache.clear();\n return;\n }\n discoveryCache.delete(normalizedIssuerKey(issuerUrl));\n}\n\nfunction mapOAuthDiscoveryError(error: unknown): PmtHouseError {\n if (error instanceof PmtHouseError) {\n return error;\n }\n if (error instanceof Error) {\n return new PmtHouseError(error.message, {\n status: 500,\n code: \"oidc_discovery_invalid\",\n details: { cause: error.cause },\n });\n }\n return new PmtHouseError(\"OIDC discovery failed\", {\n status: 500,\n code: \"oidc_discovery_invalid\",\n });\n}\n\nfunction mapDiscoveryNetworkError(error: unknown): PmtHouseError {\n if (error instanceof PmtHouseError) {\n return error;\n }\n if (error instanceof Error) {\n return new PmtHouseError(`Failed to load OIDC discovery: ${error.message}`, {\n status: 502,\n code: \"oidc_discovery_failed\",\n });\n }\n return new PmtHouseError(\"Failed to load OIDC discovery\", {\n status: 502,\n code: \"oidc_discovery_failed\",\n });\n}\n","import { type Client, OperationProcessingError, ResponseBodyError } from \"oauth4webapi\";\nimport { PmtHouseError } from \"./errors.js\";\nimport type { ClientCredentialsTokenResponse, TokenExchangeResponse } from \"./types.js\";\n\nconst ACCEPTED_ISSUED_TOKEN_TYPES = new Set([\n \"urn:ietf:params:oauth:token-type:access_token\",\n \"urn:pmth:token-type:remote-signer-session\",\n]);\n\nexport function mapOAuthError(error: unknown): PmtHouseError {\n if (error instanceof PmtHouseError) {\n return error;\n }\n\n if (error instanceof ResponseBodyError) {\n const cause = error.cause as Record<string, unknown>;\n const description =\n typeof error.error_description === \"string\"\n ? error.error_description\n : error.message;\n const details: Record<string, unknown> = { ...cause };\n if (typeof cause.error_uri === \"string\") {\n details.error_uri = cause.error_uri;\n }\n return new PmtHouseError(description, {\n status: error.status,\n code: error.error,\n details,\n });\n }\n\n if (error instanceof OperationProcessingError) {\n return new PmtHouseError(error.message, {\n status: 502,\n code: error.code ?? \"oauth_processing_error\",\n details: { cause: error.cause },\n });\n }\n\n if (error instanceof Error) {\n return new PmtHouseError(error.message, {\n status: 500,\n code: \"unexpected_error\",\n });\n }\n\n return new PmtHouseError(\"Unexpected error\", {\n status: 500,\n code: \"unexpected_error\",\n });\n}\n\nexport function tokenEndpointResponseToExchange(\n tr: import(\"oauth4webapi\").TokenEndpointResponse,\n): TokenExchangeResponse {\n const issued = tr.issued_token_type;\n if (typeof issued !== \"string\" || !ACCEPTED_ISSUED_TOKEN_TYPES.has(issued)) {\n throw new PmtHouseError(\"Token exchange returned an unexpected issued_token_type\", {\n status: 502,\n code: \"invalid_token_response\",\n details: { issued_token_type: issued },\n });\n }\n\n const tt = tr.token_type;\n if (typeof tt !== \"string\" || tt.toLowerCase() !== \"bearer\") {\n throw new PmtHouseError(\"Token endpoint returned a non-Bearer token_type\", {\n status: 502,\n code: \"invalid_token_response\",\n details: { token_type: tt },\n });\n }\n\n const expiresIn = tr.expires_in;\n if (typeof expiresIn !== \"number\") {\n throw new PmtHouseError(\"Token response missing expires_in\", {\n status: 502,\n code: \"invalid_token_response\",\n });\n }\n\n const scope = typeof tr.scope === \"string\" ? tr.scope : \"\";\n\n return {\n access_token: tr.access_token,\n token_type: \"Bearer\",\n expires_in: expiresIn,\n scope,\n issued_token_type: issued,\n };\n}\n\nexport function tokenEndpointResponseToClientCredentials(\n tr: import(\"oauth4webapi\").TokenEndpointResponse,\n): ClientCredentialsTokenResponse {\n const tt = tr.token_type;\n if (typeof tt !== \"string\" || tt.toLowerCase() !== \"bearer\") {\n throw new PmtHouseError(\"Token endpoint returned a non-Bearer token_type\", {\n status: 502,\n code: \"invalid_token_response\",\n details: { token_type: tt },\n });\n }\n\n return {\n access_token: tr.access_token,\n token_type: \"Bearer\",\n expires_in: tr.expires_in,\n scope: typeof tr.scope === \"string\" ? tr.scope : undefined,\n };\n}\n\nexport function m2mClient(clientId: string): Client {\n return { client_id: clientId };\n}\n","import {\n allowInsecureRequests,\n customFetch,\n validateJwtAccessToken,\n type JWTAccessTokenClaims,\n} from \"oauth4webapi\";\nimport { loadAuthorizationServer } from \"./discovery.js\";\nimport { PmtHouseError } from \"./errors.js\";\nimport { mapOAuthError } from \"./oauth-map.js\";\nimport type { FetchLike } from \"./types.js\";\n\nexport interface VerifyJwtOptions {\n issuerUrl: string;\n /** Expected JWT `aud` (resource identifier). */\n audience: string;\n fetch?: FetchLike;\n allowInsecureHttp?: boolean;\n /** If set, every scope here must appear in the token's `scope` claim (space-separated). */\n requiredScopes?: string[];\n}\n\n/**\n * RFC 9068 / RFC 6750: validate a JWT access token using issuer JWKS via oauth4webapi.\n */\nexport async function verifyJwt(\n token: string,\n options: VerifyJwtOptions,\n): Promise<JWTAccessTokenClaims> {\n const fetchImpl = options.fetch ?? fetch;\n const as = await loadAuthorizationServer(options.issuerUrl, fetchImpl, {\n allowInsecureHttp: options.allowInsecureHttp,\n });\n\n const request = new Request(\"https://resource.invalid/\", {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n const httpOpts: Record<symbol, unknown> = {\n [customFetch]: fetchImpl,\n };\n if (options.allowInsecureHttp) {\n httpOpts[allowInsecureRequests] = true;\n }\n\n try {\n const claims = await validateJwtAccessToken(\n as,\n request,\n options.audience,\n httpOpts as import(\"oauth4webapi\").ValidateJWTAccessTokenOptions,\n );\n\n if (options.requiredScopes?.length) {\n const scopeStr = typeof claims.scope === \"string\" ? claims.scope : \"\";\n const have = new Set(scopeStr.split(/\\s+/).filter(Boolean));\n for (const s of options.requiredScopes) {\n if (!have.has(s)) {\n throw new PmtHouseError(`Missing required scope: ${s}`, {\n status: 403,\n code: \"insufficient_scope\",\n });\n }\n }\n }\n\n return claims;\n } catch (e) {\n throw mapOAuthError(e);\n }\n}\n","import type { PaymentWebhookRequest } from \"./types.js\";\n\nfunction firstHeaderValue(values: string[] | undefined): string {\n if (!Array.isArray(values)) {\n return \"\";\n }\n for (const value of values) {\n if (typeof value === \"string\" && value.trim()) {\n return value.trim();\n }\n }\n return \"\";\n}\n\nexport function headerValueFromWebhookPayload(\n headers: Record<string, string[]> | undefined,\n name: string,\n): string {\n if (!headers) {\n return \"\";\n }\n const direct = firstHeaderValue(headers[name]);\n if (direct) {\n return direct;\n }\n const target = name.toLowerCase();\n for (const [key, values] of Object.entries(headers)) {\n if (key.toLowerCase() === target) {\n return firstHeaderValue(values);\n }\n }\n return \"\";\n}\n\n/** End-user Authorization from go-livepeer webhook body (headers map or legacy field). */\nexport function authorizationFromWebhookPayload(\n payload: PaymentWebhookRequest,\n): string {\n const fromHeaders = headerValueFromWebhookPayload(\n payload.headers,\n \"Authorization\",\n );\n if (fromHeaders) {\n return fromHeaders;\n }\n return payload.authorization?.trim() ?? \"\";\n}\n","import { timingSafeEqual } from \"node:crypto\";\nimport { PmtHouseError } from \"../../errors.js\";\nimport { optionalBearerToken } from \"./bearer.js\";\nimport { authorizationFromWebhookPayload } from \"./payload.js\";\nimport type { PaymentWebhookRequest, PaymentWebhookResponse } from \"./types.js\";\nimport type { EndUserAuthVerifier, VerifiedEndUserAuth } from \"./verifier.js\";\n\nexport type {\n EndUserAuthVerifier,\n EndUserAuthVerifyContext,\n VerifiedEndUserAuth,\n WebhookAdminRoute,\n} from \"./verifier.js\";\n\nexport type WebhookAuthorizeContext = {\n authorization: string;\n payload: PaymentWebhookRequest;\n request: Request;\n verified: VerifiedEndUserAuth;\n identity: VerifiedEndUserAuth[\"identity\"];\n};\n\nexport type RemoteSignerWebhookConfig = {\n webhookSecret: string;\n endUserAuth: EndUserAuthVerifier;\n afterVerify?: (context: WebhookAuthorizeContext) => Promise<void>;\n};\n\nfunction authIdFromIdentity(identity: VerifiedEndUserAuth[\"identity\"]): string {\n return `${identity.client_id}:${identity.usage_subject}`;\n}\n\nfunction timingSafeEqualStrings(a: string, b: string): boolean {\n const aBuffer = Buffer.from(a);\n const bBuffer = Buffer.from(b);\n if (aBuffer.length !== bBuffer.length) {\n return false;\n }\n return timingSafeEqual(aBuffer, bBuffer);\n}\n\nexport function authenticateWebhookCaller(request: Request, secret: string): boolean {\n if (!secret.trim()) {\n return false;\n }\n const trimmed = secret.trim();\n const bearer = optionalBearerToken(request.headers.get(\"authorization\") ?? \"\");\n if (bearer && timingSafeEqualStrings(bearer, trimmed)) {\n return true;\n }\n const apiKey = request.headers.get(\"x-api-key\")?.trim() ?? \"\";\n if (apiKey && timingSafeEqualStrings(apiKey, trimmed)) {\n return true;\n }\n const legacySecret = request.headers.get(\"x-webhook-secret\")?.trim() ?? \"\";\n if (legacySecret && timingSafeEqualStrings(legacySecret, trimmed)) {\n return true;\n }\n return false;\n}\n\nfunction paymentWebhookJson(\n httpStatus: number,\n body: PaymentWebhookResponse,\n): Response {\n return new Response(JSON.stringify(body), {\n status: httpStatus,\n headers: { \"Content-Type\": \"application/json\" },\n });\n}\n\nfunction rejectStatusFromError(err: unknown): { status: number; reason: string } {\n if (err instanceof PmtHouseError) {\n return {\n status: err.status >= 400 && err.status < 600 ? err.status : 403,\n reason: err.message,\n };\n }\n const reason = err instanceof Error ? err.message : \"authorization rejected\";\n return { status: 403, reason };\n}\n\nexport async function handleRemoteSignerAuthorize(\n request: Request,\n config: RemoteSignerWebhookConfig,\n): Promise<Response> {\n if (!authenticateWebhookCaller(request, config.webhookSecret)) {\n return paymentWebhookJson(401, {\n status: 401,\n reason: \"unauthorized webhook caller\",\n });\n }\n\n let payload: PaymentWebhookRequest;\n try {\n payload = (await request.json()) as PaymentWebhookRequest;\n } catch {\n return paymentWebhookJson(400, {\n status: 400,\n reason: \"invalid request json\",\n });\n }\n\n const authorization = authorizationFromWebhookPayload(payload) ?? \"\";\n\n try {\n const verified = await config.endUserAuth.verify({\n authorization,\n payload,\n request,\n });\n\n if (config.afterVerify) {\n await config.afterVerify({\n authorization,\n payload,\n request,\n verified,\n identity: verified.identity,\n });\n }\n\n return paymentWebhookJson(200, {\n status: 200,\n expiry: verified.expiry,\n auth_id: authIdFromIdentity(verified.identity),\n identity: verified.identity,\n });\n } catch (err) {\n const { status, reason } = rejectStatusFromError(err);\n return paymentWebhookJson(200, {\n status,\n reason,\n });\n }\n}\n\nexport function createRemoteSignerAuthorizeHandler(\n config: RemoteSignerWebhookConfig,\n): (request: Request) => Promise<Response> {\n return (request) => handleRemoteSignerAuthorize(request, config);\n}\n\nexport async function routeRemoteSignerWebhookRequest(\n request: Request,\n config: RemoteSignerWebhookConfig,\n): Promise<Response | null> {\n const url = new URL(request.url);\n if (request.method === \"POST\" && url.pathname === \"/authorize\") {\n return handleRemoteSignerAuthorize(request, config);\n }\n\n const adminRoutes = config.endUserAuth.adminRoutes ?? [];\n for (const route of adminRoutes) {\n if (request.method === route.method && url.pathname === route.pathname) {\n return route.handler(request);\n }\n }\n\n return null;\n}\n","import { PmtHouseError } from \"../../errors.js\";\nimport type { UsageIdentity } from \"./types.js\";\n\nexport type WebhookIdentityClaimMapping = {\n claimClientId: string;\n claimUsageSubject: string;\n usageSubjectType: string;\n};\n\nexport const DEFAULT_WEBHOOK_IDENTITY_CLAIMS: WebhookIdentityClaimMapping = {\n claimClientId: \"client_id\",\n claimUsageSubject: \"sub\",\n usageSubjectType: \"external_user_id\",\n};\n\nfunction readClaim(payload: Record<string, unknown>, key: string): string {\n const value = payload[key];\n if (typeof value === \"string\" && value.trim()) {\n return value.trim();\n }\n if (\n typeof value === \"number\" ||\n typeof value === \"boolean\" ||\n typeof value === \"bigint\"\n ) {\n return value.toString().trim();\n }\n return \"\";\n}\n\nexport function identityFromWebhookClaims(\n claims: Record<string, unknown>,\n mapping: Partial<WebhookIdentityClaimMapping> = {},\n): UsageIdentity {\n const claimClientId =\n mapping.claimClientId ?? DEFAULT_WEBHOOK_IDENTITY_CLAIMS.claimClientId;\n const claimUsageSubject =\n mapping.claimUsageSubject ?? DEFAULT_WEBHOOK_IDENTITY_CLAIMS.claimUsageSubject;\n const defaultUsageSubjectType =\n mapping.usageSubjectType ?? DEFAULT_WEBHOOK_IDENTITY_CLAIMS.usageSubjectType;\n\n let clientId = readClaim(claims, claimClientId);\n if (!clientId) {\n clientId = readClaim(claims, \"azp\");\n }\n\n const usageSubject = readClaim(claims, claimUsageSubject);\n let usageSubjectType = defaultUsageSubjectType;\n const claimUsageSubjectType = readClaim(claims, \"usage_subject_type\");\n if (claimUsageSubjectType) {\n usageSubjectType = claimUsageSubjectType;\n }\n\n const identity: UsageIdentity = {\n issuer: readClaim(claims, \"iss\"),\n client_id: clientId,\n usage_subject: usageSubject,\n usage_subject_type: usageSubjectType,\n };\n\n if (!identity.issuer || !identity.client_id || !identity.usage_subject) {\n throw new PmtHouseError(\"JWT missing required identity claims\", {\n status: 403,\n code: \"invalid_identity\",\n });\n }\n\n return identity;\n}\n\nexport function claimExpirySeconds(\n claims: Record<string, unknown>,\n fallbackTtlSeconds = 300,\n): number {\n const exp = claims.exp;\n if (typeof exp === \"number\" && Number.isFinite(exp)) {\n return Math.trunc(exp);\n }\n if (typeof exp === \"string\" && exp.trim()) {\n const parsed = Number(exp);\n if (Number.isFinite(parsed)) {\n return Math.trunc(parsed);\n }\n }\n return Math.trunc(Date.now() / 1000) + fallbackTtlSeconds;\n}\n","import { loadAuthorizationServer } from \"../../../../discovery.js\";\nimport { verifyJwt } from \"../../../../verify.js\";\nimport type { FetchLike } from \"../../../../types.js\";\nimport { authenticateWebhookCaller } from \"../../authorize.js\";\nimport {\n claimExpirySeconds,\n DEFAULT_WEBHOOK_IDENTITY_CLAIMS,\n identityFromWebhookClaims,\n type WebhookIdentityClaimMapping,\n} from \"../../identity.js\";\nimport { bearerTokenFromAuthorization } from \"../../bearer.js\";\nimport type { EndUserAuthVerifier } from \"../../verifier.js\";\n\nexport type OidcEndUserAuthConfig = {\n jwtIssuer: string;\n jwtAudience: string;\n claimMapping?: Partial<WebhookIdentityClaimMapping>;\n allowInsecureHttp?: boolean;\n fetch?: FetchLike;\n requiredScopes?: string[];\n webhookSecret: string;\n};\n\nexport async function handleRemoteSignerRefreshJwks(\n request: Request,\n config: Pick<\n OidcEndUserAuthConfig,\n \"webhookSecret\" | \"jwtIssuer\" | \"fetch\" | \"allowInsecureHttp\"\n >,\n): Promise<Response> {\n if (!authenticateWebhookCaller(request, config.webhookSecret)) {\n return new Response(\"unauthorized\", { status: 401 });\n }\n\n try {\n await loadAuthorizationServer(config.jwtIssuer, config.fetch ?? fetch, {\n force: true,\n allowInsecureHttp: config.allowInsecureHttp,\n });\n return new Response(JSON.stringify({ status: \"ok\" }), {\n status: 200,\n headers: { \"Content-Type\": \"application/json\" },\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : \"jwks refresh failed\";\n return new Response(message, { status: 500 });\n }\n}\n\nexport function createOidcEndUserVerifier(\n config: OidcEndUserAuthConfig,\n): EndUserAuthVerifier {\n const claimMapping = {\n ...DEFAULT_WEBHOOK_IDENTITY_CLAIMS,\n ...config.claimMapping,\n };\n\n return {\n kind: \"oidc\",\n verify: async ({ authorization }) => {\n const token = bearerTokenFromAuthorization(authorization);\n const audience = config.jwtAudience.trim();\n if (!audience) {\n throw new Error(\"jwt audience is required for webhook verification\");\n }\n\n const claims = await verifyJwt(token, {\n issuerUrl: config.jwtIssuer,\n audience,\n fetch: config.fetch,\n allowInsecureHttp: config.allowInsecureHttp,\n requiredScopes: config.requiredScopes,\n });\n\n const claimsRecord = claims as unknown as Record<string, unknown>;\n const identity = identityFromWebhookClaims(claimsRecord, claimMapping);\n\n return {\n identity,\n expiry: claimExpirySeconds(claimsRecord),\n raw: claimsRecord,\n };\n },\n adminRoutes: [\n {\n method: \"POST\",\n pathname: \"/admin/refresh-jwks\",\n handler: (request) => handleRemoteSignerRefreshJwks(request, config),\n },\n ],\n };\n}\n","import { PmtHouseError } from \"../../../../errors.js\";\nimport type { EndUserAuthVerifier } from \"../../verifier.js\";\n\nexport function createFirstMatchEndUserVerifier(\n verifiers: EndUserAuthVerifier[],\n): EndUserAuthVerifier {\n if (verifiers.length === 0) {\n throw new PmtHouseError(\"at least one verifier is required\", {\n status: 500,\n code: \"invalid_verifier_config\",\n });\n }\n\n return {\n kind: \"composite\",\n verify: async (context) => {\n let lastError: unknown;\n for (const verifier of verifiers) {\n try {\n return await verifier.verify(context);\n } catch (err) {\n lastError = err;\n }\n }\n\n if (lastError instanceof PmtHouseError) {\n throw lastError;\n }\n if (lastError instanceof Error) {\n throw new PmtHouseError(lastError.message, {\n status: 401,\n code: \"invalid_credentials\",\n });\n }\n throw new PmtHouseError(\"invalid credentials\", {\n status: 401,\n code: \"invalid_credentials\",\n });\n },\n adminRoutes: verifiers.flatMap((verifier) => verifier.adminRoutes ?? []),\n };\n}\n","import { PmtHouseError } from \"../../../../errors.js\";\nimport { headerValueFromWebhookPayload } from \"../../payload.js\";\nimport type { EndUserAuthVerifier } from \"../../verifier.js\";\nimport type { UsageIdentity } from \"../../types.js\";\n\nexport const DEFAULT_DMZ_TRUSTED_HEADERS = {\n issuer: \"X-Livepeer-Usage-Issuer\",\n clientId: \"X-Livepeer-Client-ID\",\n usageSubject: \"X-Livepeer-Usage-Subject\",\n usageSubjectType: \"X-Livepeer-Usage-Subject-Type\",\n} as const;\n\nexport type TrustedHeadersEndUserAuthConfig = {\n expectedIssuer: string;\n headerNames?: Partial<typeof DEFAULT_DMZ_TRUSTED_HEADERS>;\n /** Auth cache TTL returned to go-livepeer when headers are trusted. */\n expiryTtlSeconds?: number;\n};\n\nfunction normalizeIssuer(value: string): string {\n let end = value.length;\n while (end > 0 && value[end - 1] === \"/\") {\n end -= 1;\n }\n return value.slice(0, end);\n}\n\nexport function identityFromTrustedHeaders(\n headers: Record<string, string[]> | undefined,\n config: TrustedHeadersEndUserAuthConfig,\n): UsageIdentity {\n const names = {\n ...DEFAULT_DMZ_TRUSTED_HEADERS,\n ...config.headerNames,\n };\n const issuer = headerValueFromWebhookPayload(headers, names.issuer);\n const clientId = headerValueFromWebhookPayload(headers, names.clientId);\n const usageSubject = headerValueFromWebhookPayload(headers, names.usageSubject);\n const usageSubjectType =\n headerValueFromWebhookPayload(headers, names.usageSubjectType) ||\n \"external_user_id\";\n\n if (!issuer || !clientId || !usageSubject) {\n throw new PmtHouseError(\"missing trusted usage identity headers\", {\n status: 403,\n code: \"invalid_identity\",\n });\n }\n\n if (\n normalizeIssuer(issuer) !== normalizeIssuer(config.expectedIssuer.trim())\n ) {\n throw new PmtHouseError(\"trusted usage issuer mismatch\", {\n status: 403,\n code: \"invalid_identity\",\n });\n }\n\n return {\n issuer: normalizeIssuer(issuer),\n client_id: clientId,\n usage_subject: usageSubject,\n usage_subject_type: usageSubjectType,\n };\n}\n\nexport function createTrustedHeadersEndUserVerifier(\n config: TrustedHeadersEndUserAuthConfig,\n): EndUserAuthVerifier {\n const expiryTtlSeconds = config.expiryTtlSeconds ?? 300;\n\n return {\n kind: \"trusted_headers\",\n verify: async ({ payload }) => {\n const identity = identityFromTrustedHeaders(payload.headers, config);\n return {\n identity,\n expiry: Math.trunc(Date.now() / 1000) + expiryTtlSeconds,\n };\n },\n };\n}\n","import { stripTrailingSlashes } from \"../../../../string-utils.js\";\nimport type {\n RemoteSignerWebhookConfig,\n WebhookAuthorizeContext,\n} from \"../../authorize.js\";\nimport { createFirstMatchEndUserVerifier } from \"../composite/verifier.js\";\nimport {\n createTrustedHeadersEndUserVerifier,\n type TrustedHeadersEndUserAuthConfig,\n} from \"../trusted-headers/verifier.js\";\nimport {\n createOidcEndUserVerifier,\n type OidcEndUserAuthConfig,\n} from \"./verifier.js\";\n\nfunction envTrim(env: NodeJS.ProcessEnv, key: string): string | undefined {\n const value = env[key]?.trim();\n return value || undefined;\n}\n\n/**\n * Default webhook JWT `aud` derived from the OIDC issuer. Signer JWTs are minted\n * with `aud` = issuer URL stripped of trailing slashes (see `signerJwtAudience`),\n * so the webhook must default the audience the same way — otherwise a trailing\n * slash on `JWT_ISSUER` silently breaks verification when `JWT_AUDIENCE` is unset.\n */\nexport function defaultSignerWebhookJwtAudience(jwtIssuer: string): string {\n return stripTrailingSlashes(jwtIssuer);\n}\n\nexport type OidcRemoteSignerWebhookConfigInput = OidcEndUserAuthConfig & {\n afterVerify?: (context: WebhookAuthorizeContext) => Promise<void>;\n};\n\nexport type SignerDmzRemoteSignerWebhookConfigInput =\n OidcRemoteSignerWebhookConfigInput & {\n /** When true (default), accept Apache DMZ X-Livepeer-* identity headers. */\n dmzTrustedHeaders?: boolean;\n trustedHeaders?: Omit<TrustedHeadersEndUserAuthConfig, \"expectedIssuer\">;\n };\n\nexport function createOidcRemoteSignerWebhookConfig(\n input: OidcRemoteSignerWebhookConfigInput,\n): RemoteSignerWebhookConfig {\n const { afterVerify, ...oidcConfig } = input;\n return {\n webhookSecret: oidcConfig.webhookSecret,\n endUserAuth: createOidcEndUserVerifier(oidcConfig),\n afterVerify,\n };\n}\n\n/**\n * PymtHouse signer-dmz: Apache validates the end-user JWT (iss/aud = issuer), injects\n * X-Livepeer-* headers, and go-livepeer forwards those headers to this webhook per\n * go-livepeer remote-signer.md. Falls back to Bearer JWT verification when present.\n */\nexport function createSignerDmzRemoteSignerWebhookConfig(\n input: SignerDmzRemoteSignerWebhookConfigInput,\n): RemoteSignerWebhookConfig {\n const {\n afterVerify,\n dmzTrustedHeaders = true,\n trustedHeaders,\n ...oidcConfig\n } = input;\n const oidcVerifier = createOidcEndUserVerifier(oidcConfig);\n const endUserAuth =\n dmzTrustedHeaders === false\n ? oidcVerifier\n : createFirstMatchEndUserVerifier([\n createTrustedHeadersEndUserVerifier({\n expectedIssuer: oidcConfig.jwtIssuer,\n ...trustedHeaders,\n }),\n oidcVerifier,\n ]);\n\n return {\n webhookSecret: oidcConfig.webhookSecret,\n endUserAuth,\n afterVerify,\n };\n}\n\nexport function readOidcRemoteSignerWebhookConfigFromEnv(\n env: NodeJS.ProcessEnv = process.env,\n): RemoteSignerWebhookConfig {\n const webhookSecret = envTrim(env, \"WEBHOOK_SECRET\");\n const jwtIssuer = envTrim(env, \"JWT_ISSUER\");\n const jwtAudience =\n envTrim(env, \"JWT_AUDIENCE\") ??\n (jwtIssuer ? defaultSignerWebhookJwtAudience(jwtIssuer) : undefined);\n\n if (!webhookSecret) {\n throw new Error(\"WEBHOOK_SECRET is required\");\n }\n if (!jwtIssuer) {\n throw new Error(\"JWT_ISSUER is required\");\n }\n if (!jwtAudience) {\n throw new Error(\"JWT_AUDIENCE is required\");\n }\n\n return createSignerDmzRemoteSignerWebhookConfig({\n webhookSecret,\n jwtIssuer,\n jwtAudience,\n claimMapping: {\n claimClientId: envTrim(env, \"CLAIM_CLIENT_ID\") ?? \"client_id\",\n claimUsageSubject: envTrim(env, \"CLAIM_USAGE_SUBJECT\") ?? \"sub\",\n usageSubjectType: envTrim(env, \"USAGE_SUBJECT_TYPE\") ?? \"external_user_id\",\n },\n allowInsecureHttp: envTrim(env, \"ALLOW_INSECURE_HTTP\") === \"1\",\n });\n}\n\n/** @deprecated Use readOidcRemoteSignerWebhookConfigFromEnv */\nexport const readRemoteSignerWebhookConfigFromEnv =\n readOidcRemoteSignerWebhookConfigFromEnv;\n"]}
@@ -1,4 +1,4 @@
1
- export { a as OidcEndUserAuthConfig, O as OidcRemoteSignerWebhookConfigInput, d as bearerTokenFromAuthorization, f as createOidcEndUserVerifier, g as createOidcRemoteSignerWebhookConfig, k as handleRemoteSignerRefreshJwks, r as readOidcRemoteSignerWebhookConfigFromEnv, m as readRemoteSignerWebhookConfigFromEnv } from '../../../index-BixH4VIG.cjs';
1
+ export { a as OidcEndUserAuthConfig, O as OidcRemoteSignerWebhookConfigInput, d as bearerTokenFromAuthorization, f as createOidcEndUserVerifier, g as createOidcRemoteSignerWebhookConfig, k as handleRemoteSignerRefreshJwks, r as readOidcRemoteSignerWebhookConfigFromEnv, m as readRemoteSignerWebhookConfigFromEnv } from '../../../index-D5wdxNYy.cjs';
2
2
  import '../../../types-BORaHW_x.cjs';
3
- import '../../../verifier-B-WFDMz6.cjs';
3
+ import '../../../verifier-Be9WAjFF.cjs';
4
4
  import './trusted-headers.cjs';
@@ -1,4 +1,4 @@
1
- export { a as OidcEndUserAuthConfig, O as OidcRemoteSignerWebhookConfigInput, d as bearerTokenFromAuthorization, f as createOidcEndUserVerifier, g as createOidcRemoteSignerWebhookConfig, k as handleRemoteSignerRefreshJwks, r as readOidcRemoteSignerWebhookConfigFromEnv, m as readRemoteSignerWebhookConfigFromEnv } from '../../../index-BTDKEorK.js';
1
+ export { a as OidcEndUserAuthConfig, O as OidcRemoteSignerWebhookConfigInput, d as bearerTokenFromAuthorization, f as createOidcEndUserVerifier, g as createOidcRemoteSignerWebhookConfig, k as handleRemoteSignerRefreshJwks, r as readOidcRemoteSignerWebhookConfigFromEnv, m as readRemoteSignerWebhookConfigFromEnv } from '../../../index-DFJ6qcK0.js';
2
2
  import '../../../types-BORaHW_x.js';
3
- import '../../../verifier-B-WFDMz6.js';
3
+ import '../../../verifier-Be9WAjFF.js';
4
4
  import './trusted-headers.js';