@pymthouse/builder-sdk 0.4.1-rc.2 → 0.4.1

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 (60) hide show
  1. package/README.md +10 -10
  2. package/dist/env.cjs +4 -13
  3. package/dist/env.cjs.map +1 -1
  4. package/dist/env.js +4 -13
  5. package/dist/env.js.map +1 -1
  6. package/dist/{index-B0ryx942.d.cts → index-D5wdxNYy.d.cts} +1 -1
  7. package/dist/{index-CvV5syf_.d.ts → index-DFJ6qcK0.d.ts} +1 -1
  8. package/dist/index.cjs +4 -13
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.cts +1 -1
  11. package/dist/index.d.ts +1 -1
  12. package/dist/index.js +4 -13
  13. package/dist/index.js.map +1 -1
  14. package/dist/{proxy-JrT6raU_.d.cts → proxy-0wa8QZIU.d.cts} +16 -2
  15. package/dist/{proxy-U32DFNuj.d.ts → proxy-KrA1vEmh.d.ts} +16 -2
  16. package/dist/signer/server.cjs +89 -72
  17. package/dist/signer/server.cjs.map +1 -1
  18. package/dist/signer/server.d.cts +2 -2
  19. package/dist/signer/server.d.ts +2 -2
  20. package/dist/signer/server.js +89 -72
  21. package/dist/signer/server.js.map +1 -1
  22. package/dist/signer/webhook/adapters/api-key.cjs +1 -1
  23. package/dist/signer/webhook/adapters/api-key.cjs.map +1 -1
  24. package/dist/signer/webhook/adapters/api-key.d.cts +1 -1
  25. package/dist/signer/webhook/adapters/api-key.d.ts +1 -1
  26. package/dist/signer/webhook/adapters/api-key.js +1 -1
  27. package/dist/signer/webhook/adapters/api-key.js.map +1 -1
  28. package/dist/signer/webhook/adapters/composite.cjs +1 -1
  29. package/dist/signer/webhook/adapters/composite.cjs.map +1 -1
  30. package/dist/signer/webhook/adapters/composite.d.cts +1 -1
  31. package/dist/signer/webhook/adapters/composite.d.ts +1 -1
  32. package/dist/signer/webhook/adapters/composite.js +1 -1
  33. package/dist/signer/webhook/adapters/composite.js.map +1 -1
  34. package/dist/signer/webhook/adapters/oidc.cjs +6 -3
  35. package/dist/signer/webhook/adapters/oidc.cjs.map +1 -1
  36. package/dist/signer/webhook/adapters/oidc.d.cts +2 -2
  37. package/dist/signer/webhook/adapters/oidc.d.ts +2 -2
  38. package/dist/signer/webhook/adapters/oidc.js +6 -3
  39. package/dist/signer/webhook/adapters/oidc.js.map +1 -1
  40. package/dist/signer/webhook/adapters/trusted-headers.cjs +1 -1
  41. package/dist/signer/webhook/adapters/trusted-headers.cjs.map +1 -1
  42. package/dist/signer/webhook/adapters/trusted-headers.d.cts +1 -1
  43. package/dist/signer/webhook/adapters/trusted-headers.d.ts +1 -1
  44. package/dist/signer/webhook/adapters/trusted-headers.js +1 -1
  45. package/dist/signer/webhook/adapters/trusted-headers.js.map +1 -1
  46. package/dist/signer/webhook.cjs +7 -71
  47. package/dist/signer/webhook.cjs.map +1 -1
  48. package/dist/signer/webhook.d.cts +5 -14
  49. package/dist/signer/webhook.d.ts +5 -14
  50. package/dist/signer/webhook.js +8 -70
  51. package/dist/signer/webhook.js.map +1 -1
  52. package/dist/{verifier-B-WFDMz6.d.cts → verifier-Be9WAjFF.d.cts} +3 -2
  53. package/dist/{verifier-B-WFDMz6.d.ts → verifier-Be9WAjFF.d.ts} +3 -2
  54. package/package.json +2 -8
  55. package/dist/signer/webhook/adapters/oauth1.cjs +0 -18
  56. package/dist/signer/webhook/adapters/oauth1.cjs.map +0 -1
  57. package/dist/signer/webhook/adapters/oauth1.d.cts +0 -19
  58. package/dist/signer/webhook/adapters/oauth1.d.ts +0 -19
  59. package/dist/signer/webhook/adapters/oauth1.js +0 -16
  60. package/dist/signer/webhook/adapters/oauth1.js.map +0 -1
@@ -19,14 +19,8 @@ var PmtHouseError = class extends Error {
19
19
  };
20
20
 
21
21
  // src/signer/handler-errors.ts
22
- function isPmtHouseError(error) {
23
- if (error instanceof PmtHouseError) {
24
- return true;
25
- }
26
- return error instanceof Error && typeof error.status === "number" && typeof error.code === "string";
27
- }
28
22
  function signerHandlerErrorResponse(error) {
29
- if (isPmtHouseError(error)) {
23
+ if (error instanceof PmtHouseError) {
30
24
  return new Response(
31
25
  JSON.stringify({
32
26
  error: error.code,
@@ -46,62 +40,6 @@ function signerHandlerErrorResponse(error) {
46
40
  });
47
41
  }
48
42
 
49
- // src/signer/token-manager.ts
50
- function cacheKey(clientId, externalUserId) {
51
- return `${clientId}\0${externalUserId}`;
52
- }
53
- function createSignerTokenManager(options) {
54
- const ttlRefreshRatio = options.ttlRefreshRatio ?? 0.8;
55
- const cache = /* @__PURE__ */ new Map();
56
- const inflight = /* @__PURE__ */ new Map();
57
- function isUsable(entry, now, forceRefresh) {
58
- if (forceRefresh) return false;
59
- if (now >= entry.expiresAt) return false;
60
- if (now >= entry.refreshAt) return false;
61
- return true;
62
- }
63
- async function refresh(publicClientId, externalUserId) {
64
- const key = cacheKey(publicClientId, externalUserId);
65
- const existing = inflight.get(key);
66
- if (existing) {
67
- return existing;
68
- }
69
- const promise = options.mint(externalUserId).then((token) => {
70
- const normalized = {
71
- ...token,
72
- refreshAt: token.refreshAt || Date.now() + Math.floor((token.expiresAt - Date.now()) * ttlRefreshRatio)
73
- };
74
- cache.set(key, normalized);
75
- inflight.delete(key);
76
- return normalized;
77
- }).catch((error) => {
78
- inflight.delete(key);
79
- throw error;
80
- });
81
- inflight.set(key, promise);
82
- return promise;
83
- }
84
- return {
85
- peek(publicClientId, externalUserId) {
86
- return cache.get(cacheKey(publicClientId, externalUserId));
87
- },
88
- invalidate(publicClientId, externalUserId) {
89
- const key = cacheKey(publicClientId, externalUserId);
90
- cache.delete(key);
91
- inflight.delete(key);
92
- },
93
- async getToken(publicClientId, externalUserId, getOptions = {}) {
94
- const now = Date.now();
95
- const key = cacheKey(publicClientId, externalUserId);
96
- const cached = cache.get(key);
97
- if (cached && isUsable(cached, now, getOptions.forceRefresh === true)) {
98
- return cached;
99
- }
100
- return refresh(publicClientId, externalUserId);
101
- }
102
- };
103
- }
104
-
105
43
  // src/signer/forward.ts
106
44
  function base64UrlPayloadToUtf8(payloadB64) {
107
45
  const normalized = payloadB64.replaceAll("-", "+").replaceAll("_", "/");
@@ -215,6 +153,70 @@ async function forwardDirectSignerRequest(options) {
215
153
  return fetchImpl(target, init);
216
154
  }
217
155
 
156
+ // src/signer/token-manager.ts
157
+ function cacheKey(clientId, externalUserId) {
158
+ return `${clientId}\0${externalUserId}`;
159
+ }
160
+ function createSignerTokenManager(options) {
161
+ const ttlRefreshRatio = options.ttlRefreshRatio ?? 0.8;
162
+ const cache = /* @__PURE__ */ new Map();
163
+ const inflight = /* @__PURE__ */ new Map();
164
+ function isUsable(entry, now, forceRefresh) {
165
+ if (forceRefresh) return false;
166
+ if (now >= entry.expiresAt) return false;
167
+ if (now >= entry.refreshAt) return false;
168
+ return true;
169
+ }
170
+ async function refresh(publicClientId, externalUserId) {
171
+ const key = cacheKey(publicClientId, externalUserId);
172
+ const existing = inflight.get(key);
173
+ if (existing) {
174
+ return existing;
175
+ }
176
+ const promise = options.mint(publicClientId, externalUserId).then((token) => {
177
+ const identity = identityFromJwtPayload(decodeJwtPayload(token.jwt));
178
+ if (identity.clientId !== publicClientId) {
179
+ throw new PmtHouseError("minted JWT client_id does not match public client id", {
180
+ status: 500,
181
+ code: "invalid_client_id",
182
+ details: { expected: publicClientId, actual: identity.clientId }
183
+ });
184
+ }
185
+ const normalized = {
186
+ ...token,
187
+ refreshAt: token.refreshAt || Date.now() + Math.floor((token.expiresAt - Date.now()) * ttlRefreshRatio)
188
+ };
189
+ cache.set(key, normalized);
190
+ inflight.delete(key);
191
+ return normalized;
192
+ }).catch((error) => {
193
+ inflight.delete(key);
194
+ throw error;
195
+ });
196
+ inflight.set(key, promise);
197
+ return promise;
198
+ }
199
+ return {
200
+ peek(publicClientId, externalUserId) {
201
+ return cache.get(cacheKey(publicClientId, externalUserId));
202
+ },
203
+ invalidate(publicClientId, externalUserId) {
204
+ const key = cacheKey(publicClientId, externalUserId);
205
+ cache.delete(key);
206
+ inflight.delete(key);
207
+ },
208
+ async getToken(publicClientId, externalUserId, getOptions = {}) {
209
+ const now = Date.now();
210
+ const key = cacheKey(publicClientId, externalUserId);
211
+ const cached = cache.get(key);
212
+ if (cached && isUsable(cached, now, getOptions.forceRefresh === true)) {
213
+ return cached;
214
+ }
215
+ return refresh(publicClientId, externalUserId);
216
+ }
217
+ };
218
+ }
219
+
218
220
  // src/string-utils.ts
219
221
  function stripTrailingSlashes(value) {
220
222
  let end = value.length;
@@ -541,7 +543,7 @@ async function mintSignerTokenFromDeviceToken(options) {
541
543
  code: "oidc_discovery_invalid"
542
544
  });
543
545
  }
544
- const audience = options.audience?.trim() || signerJwtAudience(issuerUrl);
546
+ const audience = options.audience?.trim() || LIVEPEER_REMOTE_SIGNER_AUDIENCE;
545
547
  const params = new URLSearchParams({
546
548
  grant_type: TOKEN_EXCHANGE_GRANT,
547
549
  subject_token: options.deviceToken,
@@ -1155,15 +1157,30 @@ function toResponse(result) {
1155
1157
  });
1156
1158
  }
1157
1159
  function createDirectSignerProxyHandler(config) {
1158
- const tokenManager = createSignerTokenManager({
1159
- mint: (externalUserId) => mintUserSignerToken({
1160
- issuerUrl: config.pymthouseIssuerUrl,
1160
+ async function resolveM2MCredentials(publicClientId) {
1161
+ if (config.resolveM2MCredentials) {
1162
+ return config.resolveM2MCredentials(publicClientId);
1163
+ }
1164
+ return {
1161
1165
  m2mClientId: config.pymthouseM2MClientId,
1162
- m2mClientSecret: config.pymthouseM2MClientSecret,
1163
- externalUserId,
1164
- fetch: config.fetch,
1165
- allowInsecureHttp: config.allowInsecureHttp
1166
- })
1166
+ m2mClientSecret: config.pymthouseM2MClientSecret
1167
+ };
1168
+ }
1169
+ const tokenManager = createSignerTokenManager({
1170
+ // `publicClientId` selects the M2M credentials so the minted JWT's
1171
+ // `client_id` matches the cache partition key. The token manager rejects any
1172
+ // minted token whose `client_id` diverges from `publicClientId`.
1173
+ mint: async (publicClientId, externalUserId) => {
1174
+ const { m2mClientId, m2mClientSecret } = await resolveM2MCredentials(publicClientId);
1175
+ return mintUserSignerToken({
1176
+ issuerUrl: config.pymthouseIssuerUrl,
1177
+ m2mClientId,
1178
+ m2mClientSecret,
1179
+ externalUserId,
1180
+ fetch: config.fetch,
1181
+ allowInsecureHttp: config.allowInsecureHttp
1182
+ });
1183
+ }
1167
1184
  });
1168
1185
  async function runBeforeSign(token, externalUserId, request) {
1169
1186
  if (!config.beforeSign) {