@pymthouse/builder-sdk 0.4.1-rc.2 → 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-B0ryx942.d.cts → index-D5wdxNYy.d.cts} +1 -1
  2. package/dist/{index-CvV5syf_.d.ts → index-DFJ6qcK0.d.ts} +1 -1
  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 +87 -64
  8. package/dist/signer/server.cjs.map +1 -1
  9. package/dist/signer/server.d.cts +2 -2
  10. package/dist/signer/server.d.ts +2 -2
  11. package/dist/signer/server.js +87 -64
  12. package/dist/signer/server.js.map +1 -1
  13. package/dist/signer/webhook/adapters/api-key.cjs +1 -1
  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 +1 -1
  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 +6 -3
  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 +6 -3
  32. package/dist/signer/webhook/adapters/oidc.js.map +1 -1
  33. package/dist/signer/webhook/adapters/trusted-headers.cjs +1 -1
  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 +1 -1
  38. package/dist/signer/webhook/adapters/trusted-headers.js.map +1 -1
  39. package/dist/signer/webhook.cjs +49 -9
  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 +49 -9
  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
@@ -46,62 +46,6 @@ function signerHandlerErrorResponse(error) {
46
46
  });
47
47
  }
48
48
 
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
49
  // src/signer/forward.ts
106
50
  function base64UrlPayloadToUtf8(payloadB64) {
107
51
  const normalized = payloadB64.replaceAll("-", "+").replaceAll("_", "/");
@@ -215,6 +159,70 @@ async function forwardDirectSignerRequest(options) {
215
159
  return fetchImpl(target, init);
216
160
  }
217
161
 
162
+ // src/signer/token-manager.ts
163
+ function cacheKey(clientId, externalUserId) {
164
+ return `${clientId}\0${externalUserId}`;
165
+ }
166
+ function createSignerTokenManager(options) {
167
+ const ttlRefreshRatio = options.ttlRefreshRatio ?? 0.8;
168
+ const cache = /* @__PURE__ */ new Map();
169
+ const inflight = /* @__PURE__ */ new Map();
170
+ function isUsable(entry, now, forceRefresh) {
171
+ if (forceRefresh) return false;
172
+ if (now >= entry.expiresAt) return false;
173
+ if (now >= entry.refreshAt) return false;
174
+ return true;
175
+ }
176
+ async function refresh(publicClientId, externalUserId) {
177
+ const key = cacheKey(publicClientId, externalUserId);
178
+ const existing = inflight.get(key);
179
+ if (existing) {
180
+ return existing;
181
+ }
182
+ const promise = options.mint(publicClientId, externalUserId).then((token) => {
183
+ const identity = identityFromJwtPayload(decodeJwtPayload(token.jwt));
184
+ if (identity.clientId !== publicClientId) {
185
+ throw new PmtHouseError("minted JWT client_id does not match public client id", {
186
+ status: 500,
187
+ code: "invalid_client_id",
188
+ details: { expected: publicClientId, actual: identity.clientId }
189
+ });
190
+ }
191
+ const normalized = {
192
+ ...token,
193
+ refreshAt: token.refreshAt || Date.now() + Math.floor((token.expiresAt - Date.now()) * ttlRefreshRatio)
194
+ };
195
+ cache.set(key, normalized);
196
+ inflight.delete(key);
197
+ return normalized;
198
+ }).catch((error) => {
199
+ inflight.delete(key);
200
+ throw error;
201
+ });
202
+ inflight.set(key, promise);
203
+ return promise;
204
+ }
205
+ return {
206
+ peek(publicClientId, externalUserId) {
207
+ return cache.get(cacheKey(publicClientId, externalUserId));
208
+ },
209
+ invalidate(publicClientId, externalUserId) {
210
+ const key = cacheKey(publicClientId, externalUserId);
211
+ cache.delete(key);
212
+ inflight.delete(key);
213
+ },
214
+ async getToken(publicClientId, externalUserId, getOptions = {}) {
215
+ const now = Date.now();
216
+ const key = cacheKey(publicClientId, externalUserId);
217
+ const cached = cache.get(key);
218
+ if (cached && isUsable(cached, now, getOptions.forceRefresh === true)) {
219
+ return cached;
220
+ }
221
+ return refresh(publicClientId, externalUserId);
222
+ }
223
+ };
224
+ }
225
+
218
226
  // src/string-utils.ts
219
227
  function stripTrailingSlashes(value) {
220
228
  let end = value.length;
@@ -1155,15 +1163,30 @@ function toResponse(result) {
1155
1163
  });
1156
1164
  }
1157
1165
  function createDirectSignerProxyHandler(config) {
1158
- const tokenManager = createSignerTokenManager({
1159
- mint: (externalUserId) => mintUserSignerToken({
1160
- issuerUrl: config.pymthouseIssuerUrl,
1166
+ async function resolveM2MCredentials(publicClientId) {
1167
+ if (config.resolveM2MCredentials) {
1168
+ return config.resolveM2MCredentials(publicClientId);
1169
+ }
1170
+ return {
1161
1171
  m2mClientId: config.pymthouseM2MClientId,
1162
- m2mClientSecret: config.pymthouseM2MClientSecret,
1163
- externalUserId,
1164
- fetch: config.fetch,
1165
- allowInsecureHttp: config.allowInsecureHttp
1166
- })
1172
+ m2mClientSecret: config.pymthouseM2MClientSecret
1173
+ };
1174
+ }
1175
+ const tokenManager = createSignerTokenManager({
1176
+ // `publicClientId` selects the M2M credentials so the minted JWT's
1177
+ // `client_id` matches the cache partition key. The token manager rejects any
1178
+ // minted token whose `client_id` diverges from `publicClientId`.
1179
+ mint: async (publicClientId, externalUserId) => {
1180
+ const { m2mClientId, m2mClientSecret } = await resolveM2MCredentials(publicClientId);
1181
+ return mintUserSignerToken({
1182
+ issuerUrl: config.pymthouseIssuerUrl,
1183
+ m2mClientId,
1184
+ m2mClientSecret,
1185
+ externalUserId,
1186
+ fetch: config.fetch,
1187
+ allowInsecureHttp: config.allowInsecureHttp
1188
+ });
1189
+ }
1167
1190
  });
1168
1191
  async function runBeforeSign(token, externalUserId, request) {
1169
1192
  if (!config.beforeSign) {