@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.
- package/dist/{index-BixH4VIG.d.cts → index-D5wdxNYy.d.cts} +4 -2
- package/dist/{index-BTDKEorK.d.ts → index-DFJ6qcK0.d.ts} +4 -2
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/{proxy-JrT6raU_.d.cts → proxy-0wa8QZIU.d.cts} +16 -2
- package/dist/{proxy-U32DFNuj.d.ts → proxy-KrA1vEmh.d.ts} +16 -2
- package/dist/signer/server.cjs +90 -67
- package/dist/signer/server.cjs.map +1 -1
- package/dist/signer/server.d.cts +4 -4
- package/dist/signer/server.d.ts +4 -4
- package/dist/signer/server.js +90 -67
- package/dist/signer/server.js.map +1 -1
- package/dist/signer/webhook/adapters/api-key.cjs +15 -11
- package/dist/signer/webhook/adapters/api-key.cjs.map +1 -1
- package/dist/signer/webhook/adapters/api-key.d.cts +1 -1
- package/dist/signer/webhook/adapters/api-key.d.ts +1 -1
- package/dist/signer/webhook/adapters/api-key.js +15 -11
- package/dist/signer/webhook/adapters/api-key.js.map +1 -1
- package/dist/signer/webhook/adapters/composite.cjs +1 -1
- package/dist/signer/webhook/adapters/composite.cjs.map +1 -1
- package/dist/signer/webhook/adapters/composite.d.cts +1 -1
- package/dist/signer/webhook/adapters/composite.d.ts +1 -1
- package/dist/signer/webhook/adapters/composite.js +1 -1
- package/dist/signer/webhook/adapters/composite.js.map +1 -1
- package/dist/signer/webhook/adapters/oauth1.d.cts +1 -1
- package/dist/signer/webhook/adapters/oauth1.d.ts +1 -1
- package/dist/signer/webhook/adapters/oidc.cjs +39 -25
- package/dist/signer/webhook/adapters/oidc.cjs.map +1 -1
- package/dist/signer/webhook/adapters/oidc.d.cts +2 -2
- package/dist/signer/webhook/adapters/oidc.d.ts +2 -2
- package/dist/signer/webhook/adapters/oidc.js +39 -25
- package/dist/signer/webhook/adapters/oidc.js.map +1 -1
- package/dist/signer/webhook/adapters/trusted-headers.cjs +18 -11
- package/dist/signer/webhook/adapters/trusted-headers.cjs.map +1 -1
- package/dist/signer/webhook/adapters/trusted-headers.d.cts +1 -1
- package/dist/signer/webhook/adapters/trusted-headers.d.ts +1 -1
- package/dist/signer/webhook/adapters/trusted-headers.js +18 -11
- package/dist/signer/webhook/adapters/trusted-headers.js.map +1 -1
- package/dist/signer/webhook.cjs +90 -38
- package/dist/signer/webhook.cjs.map +1 -1
- package/dist/signer/webhook.d.cts +6 -4
- package/dist/signer/webhook.d.ts +6 -4
- package/dist/signer/webhook.js +90 -39
- package/dist/signer/webhook.js.map +1 -1
- package/dist/{verifier-B-WFDMz6.d.cts → verifier-Be9WAjFF.d.cts} +3 -2
- package/dist/{verifier-B-WFDMz6.d.ts → verifier-Be9WAjFF.d.ts} +3 -2
- package/package.json +2 -2
package/dist/signer/server.js
CHANGED
|
@@ -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;
|
|
@@ -1011,7 +1019,7 @@ async function forwardToSigner(options) {
|
|
|
1011
1019
|
const headers = { "Content-Type": "application/json" };
|
|
1012
1020
|
const explicitAuth = options.authorization?.trim();
|
|
1013
1021
|
if (explicitAuth) {
|
|
1014
|
-
headers.Authorization = explicitAuth
|
|
1022
|
+
headers.Authorization = explicitAuth;
|
|
1015
1023
|
} else {
|
|
1016
1024
|
const attachJwt = options.forwardJwt ?? true;
|
|
1017
1025
|
if (attachJwt) {
|
|
@@ -1155,15 +1163,30 @@ function toResponse(result) {
|
|
|
1155
1163
|
});
|
|
1156
1164
|
}
|
|
1157
1165
|
function createDirectSignerProxyHandler(config) {
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
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
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
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) {
|
|
@@ -1227,8 +1250,8 @@ function createDirectSignerProxyHandler(config) {
|
|
|
1227
1250
|
return signerHandlerErrorResponse(error);
|
|
1228
1251
|
}
|
|
1229
1252
|
};
|
|
1230
|
-
handler.getCachedUsage = (externalUserId) => tokenManager.peek(
|
|
1231
|
-
handler.invalidateToken = (externalUserId) => tokenManager.invalidate(
|
|
1253
|
+
handler.getCachedUsage = (publicClientId, externalUserId) => tokenManager.peek(publicClientId, externalUserId);
|
|
1254
|
+
handler.invalidateToken = (publicClientId, externalUserId) => tokenManager.invalidate(publicClientId, externalUserId);
|
|
1232
1255
|
return handler;
|
|
1233
1256
|
}
|
|
1234
1257
|
|