@frontmcp/plugin-dashboard 1.9.1 → 1.9.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/esm/index.mjs CHANGED
@@ -106,22 +106,22 @@ var require_node = __commonJS({
106
106
  mod
107
107
  ));
108
108
  var __toCommonJS = (mod) => __copyProps2(__defProp3({}, "__esModule", { value: true }), mod);
109
- var node_exports2 = {};
110
- __export2(node_exports2, {
111
- createSignedJwt: () => createSignedJwt2,
112
- cryptoProvider: () => nodeCrypto2,
113
- generateRsaKeyPair: () => generateRsaKeyPair2,
109
+ var node_exports = {};
110
+ __export2(node_exports, {
111
+ createSignedJwt: () => createSignedJwt,
112
+ cryptoProvider: () => nodeCrypto,
113
+ generateRsaKeyPair: () => generateRsaKeyPair3,
114
114
  isRsaPssAlg: () => isRsaPssAlg2,
115
- jwtAlgToNodeAlg: () => jwtAlgToNodeAlg2,
116
- nodeCrypto: () => nodeCrypto2,
117
- pemToPublicJwk: () => pemToPublicJwk2,
118
- rsaSign: () => rsaSign2,
119
- rsaSignBase64Url: () => rsaSignBase64Url2,
120
- rsaVerify: () => rsaVerify2,
121
- rsaVerifySync: () => rsaVerifySync2
115
+ jwtAlgToNodeAlg: () => jwtAlgToNodeAlg,
116
+ nodeCrypto: () => nodeCrypto,
117
+ pemToPublicJwk: () => pemToPublicJwk3,
118
+ rsaSign: () => rsaSign,
119
+ rsaSignBase64Url: () => rsaSignBase64Url3,
120
+ rsaVerify: () => rsaVerify3,
121
+ rsaVerifySync: () => rsaVerifySync3
122
122
  });
123
- module.exports = __toCommonJS(node_exports2);
124
- var import_node_crypto2 = __toESM2(__require("node:crypto"));
123
+ module.exports = __toCommonJS(node_exports);
124
+ var import_node_crypto = __toESM2(__require("node:crypto"));
125
125
  var JWT_ALG_TO_NODE_DIGEST2 = {
126
126
  RS256: "RSA-SHA256",
127
127
  RS384: "RSA-SHA384",
@@ -131,7 +131,7 @@ var require_node = __commonJS({
131
131
  PS384: "RSA-SHA384",
132
132
  PS512: "RSA-SHA512"
133
133
  };
134
- function jwtAlgToNodeAlg2(jwtAlg) {
134
+ function jwtAlgToNodeAlg(jwtAlg) {
135
135
  const nodeAlg = JWT_ALG_TO_NODE_DIGEST2[jwtAlg];
136
136
  if (!nodeAlg) {
137
137
  throw new Error(`Unsupported JWT algorithm: ${jwtAlg}`);
@@ -141,70 +141,70 @@ var require_node = __commonJS({
141
141
  function isRsaPssAlg2(jwtAlg) {
142
142
  return jwtAlg.startsWith("PS");
143
143
  }
144
- function toUint8Array2(buf) {
144
+ function toUint8Array(buf) {
145
145
  return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
146
146
  }
147
- function toBuffer2(data) {
147
+ function toBuffer(data) {
148
148
  if (typeof data === "string") {
149
149
  return Buffer.from(data, "utf8");
150
150
  }
151
151
  return Buffer.from(data);
152
152
  }
153
- var nodeCrypto2 = {
153
+ var nodeCrypto = {
154
154
  randomUUID() {
155
- return import_node_crypto2.default.randomUUID();
155
+ return import_node_crypto.default.randomUUID();
156
156
  },
157
157
  randomBytes(length) {
158
- return toUint8Array2(import_node_crypto2.default.randomBytes(length));
158
+ return toUint8Array(import_node_crypto.default.randomBytes(length));
159
159
  },
160
160
  sha256(data) {
161
- const hash = import_node_crypto2.default.createHash("sha256").update(toBuffer2(data)).digest();
162
- return toUint8Array2(hash);
161
+ const hash = import_node_crypto.default.createHash("sha256").update(toBuffer(data)).digest();
162
+ return toUint8Array(hash);
163
163
  },
164
164
  sha256Hex(data) {
165
- return import_node_crypto2.default.createHash("sha256").update(toBuffer2(data)).digest("hex");
165
+ return import_node_crypto.default.createHash("sha256").update(toBuffer(data)).digest("hex");
166
166
  },
167
167
  hmacSha256(key, data) {
168
- const hmac2 = import_node_crypto2.default.createHmac("sha256", Buffer.from(key)).update(Buffer.from(data)).digest();
169
- return toUint8Array2(hmac2);
168
+ const hmac2 = import_node_crypto.default.createHmac("sha256", Buffer.from(key)).update(Buffer.from(data)).digest();
169
+ return toUint8Array(hmac2);
170
170
  },
171
171
  hkdfSha256(ikm, salt, info, length) {
172
172
  const ikmBuf = Buffer.from(ikm);
173
173
  const saltBuf = salt.length > 0 ? Buffer.from(salt) : Buffer.alloc(32);
174
- const prk = import_node_crypto2.default.createHmac("sha256", saltBuf).update(ikmBuf).digest();
174
+ const prk = import_node_crypto.default.createHmac("sha256", saltBuf).update(ikmBuf).digest();
175
175
  const hashLen = 32;
176
176
  const n = Math.ceil(length / hashLen);
177
177
  const chunks = [];
178
178
  let prev = Buffer.alloc(0);
179
179
  for (let i = 1; i <= n; i++) {
180
- prev = import_node_crypto2.default.createHmac("sha256", prk).update(Buffer.concat([prev, Buffer.from(info), Buffer.from([i])])).digest();
180
+ prev = import_node_crypto.default.createHmac("sha256", prk).update(Buffer.concat([prev, Buffer.from(info), Buffer.from([i])])).digest();
181
181
  chunks.push(prev);
182
182
  }
183
- return toUint8Array2(Buffer.concat(chunks).subarray(0, length));
183
+ return toUint8Array(Buffer.concat(chunks).subarray(0, length));
184
184
  },
185
185
  encryptAesGcm(key, plaintext, iv) {
186
- const cipher = import_node_crypto2.default.createCipheriv("aes-256-gcm", Buffer.from(key), Buffer.from(iv));
186
+ const cipher = import_node_crypto.default.createCipheriv("aes-256-gcm", Buffer.from(key), Buffer.from(iv));
187
187
  const encrypted = Buffer.concat([cipher.update(Buffer.from(plaintext)), cipher.final()]);
188
188
  const tag = cipher.getAuthTag();
189
189
  return {
190
- ciphertext: toUint8Array2(encrypted),
191
- tag: toUint8Array2(tag)
190
+ ciphertext: toUint8Array(encrypted),
191
+ tag: toUint8Array(tag)
192
192
  };
193
193
  },
194
194
  decryptAesGcm(key, ciphertext, iv, tag) {
195
- const decipher = import_node_crypto2.default.createDecipheriv("aes-256-gcm", Buffer.from(key), Buffer.from(iv));
195
+ const decipher = import_node_crypto.default.createDecipheriv("aes-256-gcm", Buffer.from(key), Buffer.from(iv));
196
196
  decipher.setAuthTag(Buffer.from(tag));
197
197
  const decrypted = Buffer.concat([decipher.update(Buffer.from(ciphertext)), decipher.final()]);
198
- return toUint8Array2(decrypted);
198
+ return toUint8Array(decrypted);
199
199
  },
200
200
  timingSafeEqual(a, b) {
201
201
  if (a.length !== b.length) return false;
202
- return import_node_crypto2.default.timingSafeEqual(Buffer.from(a), Buffer.from(b));
202
+ return import_node_crypto.default.timingSafeEqual(Buffer.from(a), Buffer.from(b));
203
203
  }
204
204
  };
205
- function generateRsaKeyPair2(modulusLength = 2048, alg = "RS256") {
206
- const kid = `rsa-key-${Date.now()}-${import_node_crypto2.default.randomBytes(8).toString("hex")}`;
207
- const { privateKey, publicKey } = import_node_crypto2.default.generateKeyPairSync("rsa", {
205
+ function generateRsaKeyPair3(modulusLength = 2048, alg = "RS256") {
206
+ const kid = `rsa-key-${Date.now()}-${import_node_crypto.default.randomBytes(8).toString("hex")}`;
207
+ const { privateKey, publicKey } = import_node_crypto.default.generateKeyPairSync("rsa", {
208
208
  modulusLength
209
209
  });
210
210
  const exported = publicKey.export({ format: "jwk" });
@@ -217,66 +217,66 @@ var require_node = __commonJS({
217
217
  };
218
218
  return { privateKey, publicKey, publicJwk };
219
219
  }
220
- function rsaSign2(algorithm, data, privateKey, options) {
220
+ function rsaSign(algorithm, data, privateKey, options) {
221
221
  const signingKey = options ? { key: privateKey, ...options } : privateKey;
222
- return import_node_crypto2.default.sign(algorithm, data, signingKey);
222
+ return import_node_crypto.default.sign(algorithm, data, signingKey);
223
223
  }
224
- function rsaVerify2(jwtAlg, data, publicJwk, signature) {
225
- const publicKey = import_node_crypto2.default.createPublicKey({ key: publicJwk, format: "jwk" });
226
- const nodeAlgorithm = jwtAlgToNodeAlg2(jwtAlg);
224
+ function rsaVerify3(jwtAlg, data, publicJwk, signature) {
225
+ const publicKey = import_node_crypto.default.createPublicKey({ key: publicJwk, format: "jwk" });
226
+ const nodeAlgorithm = jwtAlgToNodeAlg(jwtAlg);
227
227
  const verifyKey = isRsaPssAlg2(jwtAlg) ? {
228
228
  key: publicKey,
229
- padding: import_node_crypto2.default.constants.RSA_PKCS1_PSS_PADDING,
230
- saltLength: import_node_crypto2.default.constants.RSA_PSS_SALTLEN_DIGEST
229
+ padding: import_node_crypto.default.constants.RSA_PKCS1_PSS_PADDING,
230
+ saltLength: import_node_crypto.default.constants.RSA_PSS_SALTLEN_DIGEST
231
231
  } : publicKey;
232
- return import_node_crypto2.default.verify(nodeAlgorithm, data, verifyKey, signature);
232
+ return import_node_crypto.default.verify(nodeAlgorithm, data, verifyKey, signature);
233
233
  }
234
- function rsaSignBase64Url2(jwtAlg, data, privateJwk) {
235
- const privateKey = import_node_crypto2.default.createPrivateKey({ key: privateJwk, format: "jwk" });
236
- const nodeAlgorithm = jwtAlgToNodeAlg2(jwtAlg);
234
+ function rsaSignBase64Url3(jwtAlg, data, privateJwk) {
235
+ const privateKey = import_node_crypto.default.createPrivateKey({ key: privateJwk, format: "jwk" });
236
+ const nodeAlgorithm = jwtAlgToNodeAlg(jwtAlg);
237
237
  const buf = Buffer.isBuffer(data) ? data : Buffer.from(data);
238
- const sig = isRsaPssAlg2(jwtAlg) ? rsaSign2(nodeAlgorithm, buf, privateKey, {
239
- padding: import_node_crypto2.default.constants.RSA_PKCS1_PSS_PADDING,
240
- saltLength: import_node_crypto2.default.constants.RSA_PSS_SALTLEN_DIGEST
241
- }) : rsaSign2(nodeAlgorithm, buf, privateKey);
238
+ const sig = isRsaPssAlg2(jwtAlg) ? rsaSign(nodeAlgorithm, buf, privateKey, {
239
+ padding: import_node_crypto.default.constants.RSA_PKCS1_PSS_PADDING,
240
+ saltLength: import_node_crypto.default.constants.RSA_PSS_SALTLEN_DIGEST
241
+ }) : rsaSign(nodeAlgorithm, buf, privateKey);
242
242
  return sig.toString("base64url");
243
243
  }
244
- function rsaVerifySync2(jwtAlg, data, publicJwk, signature) {
244
+ function rsaVerifySync3(jwtAlg, data, publicJwk, signature) {
245
245
  try {
246
- const publicKey = import_node_crypto2.default.createPublicKey({ key: publicJwk, format: "jwk" });
246
+ const publicKey = import_node_crypto.default.createPublicKey({ key: publicJwk, format: "jwk" });
247
247
  const dataBuf = Buffer.isBuffer(data) ? data : Buffer.from(data);
248
248
  const sigBuf = Buffer.isBuffer(signature) ? signature : Buffer.from(signature);
249
249
  if (jwtAlg === "EdDSA") {
250
- return import_node_crypto2.default.verify(null, dataBuf, publicKey, sigBuf);
250
+ return import_node_crypto.default.verify(null, dataBuf, publicKey, sigBuf);
251
251
  }
252
- const nodeAlgorithm = jwtAlgToNodeAlg2(jwtAlg);
252
+ const nodeAlgorithm = jwtAlgToNodeAlg(jwtAlg);
253
253
  const verifyKey = isRsaPssAlg2(jwtAlg) ? {
254
254
  key: publicKey,
255
- padding: import_node_crypto2.default.constants.RSA_PKCS1_PSS_PADDING,
256
- saltLength: import_node_crypto2.default.constants.RSA_PSS_SALTLEN_DIGEST
255
+ padding: import_node_crypto.default.constants.RSA_PKCS1_PSS_PADDING,
256
+ saltLength: import_node_crypto.default.constants.RSA_PSS_SALTLEN_DIGEST
257
257
  } : publicKey;
258
- return import_node_crypto2.default.verify(nodeAlgorithm, dataBuf, verifyKey, sigBuf);
258
+ return import_node_crypto.default.verify(nodeAlgorithm, dataBuf, verifyKey, sigBuf);
259
259
  } catch {
260
260
  return false;
261
261
  }
262
262
  }
263
- function pemToPublicJwk2(pem) {
264
- const key = import_node_crypto2.default.createPublicKey({ key: pem, format: "pem" });
263
+ function pemToPublicJwk3(pem) {
264
+ const key = import_node_crypto.default.createPublicKey({ key: pem, format: "pem" });
265
265
  return key.export({ format: "jwk" });
266
266
  }
267
- function createSignedJwt2(payload, privateKey, kid, alg = "RS256") {
267
+ function createSignedJwt(payload, privateKey, kid, alg = "RS256") {
268
268
  const header = { alg, typ: "JWT", kid };
269
269
  const headerB64 = Buffer.from(JSON.stringify(header)).toString("base64url");
270
270
  const payloadB64 = Buffer.from(JSON.stringify(payload)).toString("base64url");
271
271
  const signatureInput = `${headerB64}.${payloadB64}`;
272
- const nodeAlgorithm = jwtAlgToNodeAlg2(alg);
273
- const signature = rsaSign2(
272
+ const nodeAlgorithm = jwtAlgToNodeAlg(alg);
273
+ const signature = rsaSign(
274
274
  nodeAlgorithm,
275
275
  Buffer.from(signatureInput),
276
276
  privateKey,
277
277
  isRsaPssAlg2(alg) ? {
278
- padding: import_node_crypto2.default.constants.RSA_PKCS1_PSS_PADDING,
279
- saltLength: import_node_crypto2.default.constants.RSA_PSS_SALTLEN_DIGEST
278
+ padding: import_node_crypto.default.constants.RSA_PKCS1_PSS_PADDING,
279
+ saltLength: import_node_crypto.default.constants.RSA_PSS_SALTLEN_DIGEST
280
280
  } : void 0
281
281
  );
282
282
  const signatureB64 = signature.toString("base64url");
@@ -438,13 +438,12 @@ import { MCP_ERROR_CODES, PublicMcpError } from "@frontmcp/sdk";
438
438
  import { z as z2 } from "@frontmcp/lazy-zod";
439
439
  var import_event_emitter = __toESM(require_node_event_emitter(), 1);
440
440
  import { z as z22 } from "@frontmcp/lazy-zod";
441
- var import_crypto_provider = __toESM(require_node(), 1);
442
- import crypto2 from "node:crypto";
443
- import { sha256 as sha256Hash } from "@noble/hashes/sha2.js";
444
- import { hmac } from "@noble/hashes/hmac.js";
441
+ var platformCrypto = __toESM(require_node(), 1);
442
+ import { gcm } from "@noble/ciphers/aes.js";
445
443
  import { hkdf } from "@noble/hashes/hkdf.js";
444
+ import { hmac } from "@noble/hashes/hmac.js";
445
+ import { sha256 as sha256Hash } from "@noble/hashes/sha2.js";
446
446
  import { randomBytes as nobleRandomBytes } from "@noble/hashes/utils.js";
447
- import { gcm } from "@noble/ciphers/aes.js";
448
447
  import { analyzeForReDoS, REDOS_THRESHOLDS } from "@enclave-vm/ast";
449
448
  var __frontmcpModule = typeof process !== "undefined" && typeof process.getBuiltinModule === "function" ? process.getBuiltinModule("module") : void 0;
450
449
  var require2 = __frontmcpModule ? __frontmcpModule.createRequire(import.meta.url || "file:///") : void 0;
@@ -550,13 +549,6 @@ var init_fs2 = __esm({
550
549
  init_fs();
551
550
  }
552
551
  });
553
- function jwtAlgToNodeAlg(jwtAlg) {
554
- const nodeAlg = JWT_ALG_TO_NODE_DIGEST[jwtAlg];
555
- if (!nodeAlg) {
556
- throw new Error(`Unsupported JWT algorithm: ${jwtAlg}`);
557
- }
558
- return nodeAlg;
559
- }
560
552
  function isRsaPssAlg(jwtAlg) {
561
553
  return jwtAlg.startsWith("PS");
562
554
  }
@@ -2343,176 +2335,18 @@ var init_key_persistence2 = __esm({
2343
2335
  init_factory();
2344
2336
  }
2345
2337
  });
2346
- var node_exports = {};
2347
- __export(node_exports, {
2348
- createSignedJwt: () => createSignedJwt,
2349
- cryptoProvider: () => nodeCrypto,
2350
- generateRsaKeyPair: () => generateRsaKeyPair,
2351
- isRsaPssAlg: () => isRsaPssAlg,
2352
- jwtAlgToNodeAlg: () => jwtAlgToNodeAlg,
2353
- nodeCrypto: () => nodeCrypto,
2354
- pemToPublicJwk: () => pemToPublicJwk,
2355
- rsaSign: () => rsaSign,
2356
- rsaSignBase64Url: () => rsaSignBase64Url,
2357
- rsaVerify: () => rsaVerify,
2358
- rsaVerifySync: () => rsaVerifySync
2359
- });
2360
- function toUint8Array(buf) {
2361
- return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
2362
- }
2363
- function toBuffer(data) {
2364
- if (typeof data === "string") {
2365
- return Buffer.from(data, "utf8");
2366
- }
2367
- return Buffer.from(data);
2368
- }
2369
- function generateRsaKeyPair(modulusLength = 2048, alg = "RS256") {
2370
- const kid = `rsa-key-${Date.now()}-${crypto2.randomBytes(8).toString("hex")}`;
2371
- const { privateKey, publicKey } = crypto2.generateKeyPairSync("rsa", {
2372
- modulusLength
2373
- });
2374
- const exported = publicKey.export({ format: "jwk" });
2375
- const publicJwk = {
2376
- ...exported,
2377
- kid,
2378
- alg,
2379
- use: "sig",
2380
- kty: "RSA"
2381
- };
2382
- return { privateKey, publicKey, publicJwk };
2383
- }
2384
- function rsaSign(algorithm, data, privateKey, options) {
2385
- const signingKey = options ? { key: privateKey, ...options } : privateKey;
2386
- return crypto2.sign(algorithm, data, signingKey);
2387
- }
2388
- function rsaVerify(jwtAlg, data, publicJwk, signature) {
2389
- const publicKey = crypto2.createPublicKey({ key: publicJwk, format: "jwk" });
2390
- const nodeAlgorithm = jwtAlgToNodeAlg(jwtAlg);
2391
- const verifyKey = isRsaPssAlg(jwtAlg) ? {
2392
- key: publicKey,
2393
- padding: crypto2.constants.RSA_PKCS1_PSS_PADDING,
2394
- saltLength: crypto2.constants.RSA_PSS_SALTLEN_DIGEST
2395
- } : publicKey;
2396
- return crypto2.verify(nodeAlgorithm, data, verifyKey, signature);
2397
- }
2398
- function rsaSignBase64Url(jwtAlg, data, privateJwk) {
2399
- const privateKey = crypto2.createPrivateKey({ key: privateJwk, format: "jwk" });
2400
- const nodeAlgorithm = jwtAlgToNodeAlg(jwtAlg);
2401
- const buf = Buffer.isBuffer(data) ? data : Buffer.from(data);
2402
- const sig = isRsaPssAlg(jwtAlg) ? rsaSign(nodeAlgorithm, buf, privateKey, {
2403
- padding: crypto2.constants.RSA_PKCS1_PSS_PADDING,
2404
- saltLength: crypto2.constants.RSA_PSS_SALTLEN_DIGEST
2405
- }) : rsaSign(nodeAlgorithm, buf, privateKey);
2406
- return sig.toString("base64url");
2407
- }
2408
- function rsaVerifySync(jwtAlg, data, publicJwk, signature) {
2409
- try {
2410
- const publicKey = crypto2.createPublicKey({ key: publicJwk, format: "jwk" });
2411
- const dataBuf = Buffer.isBuffer(data) ? data : Buffer.from(data);
2412
- const sigBuf = Buffer.isBuffer(signature) ? signature : Buffer.from(signature);
2413
- if (jwtAlg === "EdDSA") {
2414
- return crypto2.verify(null, dataBuf, publicKey, sigBuf);
2415
- }
2416
- const nodeAlgorithm = jwtAlgToNodeAlg(jwtAlg);
2417
- const verifyKey = isRsaPssAlg(jwtAlg) ? {
2418
- key: publicKey,
2419
- padding: crypto2.constants.RSA_PKCS1_PSS_PADDING,
2420
- saltLength: crypto2.constants.RSA_PSS_SALTLEN_DIGEST
2421
- } : publicKey;
2422
- return crypto2.verify(nodeAlgorithm, dataBuf, verifyKey, sigBuf);
2423
- } catch {
2424
- return false;
2425
- }
2426
- }
2427
- function pemToPublicJwk(pem) {
2428
- const key = crypto2.createPublicKey({ key: pem, format: "pem" });
2429
- return key.export({ format: "jwk" });
2430
- }
2431
- function createSignedJwt(payload, privateKey, kid, alg = "RS256") {
2432
- const header = { alg, typ: "JWT", kid };
2433
- const headerB64 = Buffer.from(JSON.stringify(header)).toString("base64url");
2434
- const payloadB64 = Buffer.from(JSON.stringify(payload)).toString("base64url");
2435
- const signatureInput = `${headerB64}.${payloadB64}`;
2436
- const nodeAlgorithm = jwtAlgToNodeAlg(alg);
2437
- const signature = rsaSign(
2438
- nodeAlgorithm,
2439
- Buffer.from(signatureInput),
2440
- privateKey,
2441
- isRsaPssAlg(alg) ? {
2442
- padding: crypto2.constants.RSA_PKCS1_PSS_PADDING,
2443
- saltLength: crypto2.constants.RSA_PSS_SALTLEN_DIGEST
2444
- } : void 0
2445
- );
2446
- const signatureB64 = signature.toString("base64url");
2447
- return `${headerB64}.${payloadB64}.${signatureB64}`;
2448
- }
2449
- var nodeCrypto;
2450
- var init_node = __esm({
2451
- "libs/utils/src/crypto/node.ts"() {
2452
- "use strict";
2453
- init_jwt_alg();
2454
- init_jwt_alg();
2455
- nodeCrypto = {
2456
- randomUUID() {
2457
- return crypto2.randomUUID();
2458
- },
2459
- randomBytes(length) {
2460
- return toUint8Array(crypto2.randomBytes(length));
2461
- },
2462
- sha256(data) {
2463
- const hash = crypto2.createHash("sha256").update(toBuffer(data)).digest();
2464
- return toUint8Array(hash);
2465
- },
2466
- sha256Hex(data) {
2467
- return crypto2.createHash("sha256").update(toBuffer(data)).digest("hex");
2468
- },
2469
- hmacSha256(key, data) {
2470
- const hmac2 = crypto2.createHmac("sha256", Buffer.from(key)).update(Buffer.from(data)).digest();
2471
- return toUint8Array(hmac2);
2472
- },
2473
- hkdfSha256(ikm, salt, info, length) {
2474
- const ikmBuf = Buffer.from(ikm);
2475
- const saltBuf = salt.length > 0 ? Buffer.from(salt) : Buffer.alloc(32);
2476
- const prk = crypto2.createHmac("sha256", saltBuf).update(ikmBuf).digest();
2477
- const hashLen = 32;
2478
- const n = Math.ceil(length / hashLen);
2479
- const chunks = [];
2480
- let prev = Buffer.alloc(0);
2481
- for (let i = 1; i <= n; i++) {
2482
- prev = crypto2.createHmac("sha256", prk).update(Buffer.concat([prev, Buffer.from(info), Buffer.from([i])])).digest();
2483
- chunks.push(prev);
2484
- }
2485
- return toUint8Array(Buffer.concat(chunks).subarray(0, length));
2486
- },
2487
- encryptAesGcm(key, plaintext, iv) {
2488
- const cipher = crypto2.createCipheriv("aes-256-gcm", Buffer.from(key), Buffer.from(iv));
2489
- const encrypted = Buffer.concat([cipher.update(Buffer.from(plaintext)), cipher.final()]);
2490
- const tag = cipher.getAuthTag();
2491
- return {
2492
- ciphertext: toUint8Array(encrypted),
2493
- tag: toUint8Array(tag)
2494
- };
2495
- },
2496
- decryptAesGcm(key, ciphertext, iv, tag) {
2497
- const decipher = crypto2.createDecipheriv("aes-256-gcm", Buffer.from(key), Buffer.from(iv));
2498
- decipher.setAuthTag(Buffer.from(tag));
2499
- const decrypted = Buffer.concat([decipher.update(Buffer.from(ciphertext)), decipher.final()]);
2500
- return toUint8Array(decrypted);
2501
- },
2502
- timingSafeEqual(a, b) {
2503
- if (a.length !== b.length) return false;
2504
- return crypto2.timingSafeEqual(Buffer.from(a), Buffer.from(b));
2505
- }
2506
- };
2507
- }
2508
- });
2509
2338
  var browser_exports = {};
2510
2339
  __export(browser_exports, {
2511
2340
  browserCrypto: () => browserCrypto,
2512
2341
  cryptoProvider: () => browserCrypto,
2342
+ generateRsaKeyPair: () => generateRsaKeyPair2,
2513
2343
  isRsaPssAlg: () => isRsaPssAlg,
2514
2344
  jwtAlgToWebCryptoAlg: () => jwtAlgToWebCryptoAlg,
2515
- rsaVerifyBrowser: () => rsaVerifyBrowser
2345
+ pemToPublicJwk: () => pemToPublicJwk2,
2346
+ rsaSignBase64Url: () => rsaSignBase64Url2,
2347
+ rsaVerify: () => rsaVerify2,
2348
+ rsaVerifyBrowser: () => rsaVerifyBrowser,
2349
+ rsaVerifySync: () => rsaVerifySync2
2516
2350
  });
2517
2351
  function toBytes(data) {
2518
2352
  if (typeof data === "string") {
@@ -2541,6 +2375,24 @@ function constantTimeEqual(a, b) {
2541
2375
  }
2542
2376
  return result === 0;
2543
2377
  }
2378
+ function nodeOnly(name) {
2379
+ throw new Error(`${name} is only available in Node.js runtimes`);
2380
+ }
2381
+ function rsaVerify2() {
2382
+ return nodeOnly("rsaVerify");
2383
+ }
2384
+ function rsaSignBase64Url2() {
2385
+ return nodeOnly("rsaSignBase64Url");
2386
+ }
2387
+ function rsaVerifySync2() {
2388
+ return nodeOnly("rsaVerifySync");
2389
+ }
2390
+ function pemToPublicJwk2() {
2391
+ return nodeOnly("pemToPublicJwk");
2392
+ }
2393
+ function generateRsaKeyPair2() {
2394
+ return nodeOnly("generateRsaKeyPair");
2395
+ }
2544
2396
  async function rsaVerifyBrowser(jwtAlg, data, publicJwk, signature) {
2545
2397
  if (typeof globalThis.crypto?.subtle === "undefined") {
2546
2398
  throw new Error("WebCrypto API (crypto.subtle) is not available in this environment");
@@ -2619,7 +2471,7 @@ var init_browser = __esm({
2619
2471
  }
2620
2472
  });
2621
2473
  function getCrypto() {
2622
- return import_crypto_provider.cryptoProvider;
2474
+ return platformCrypto.cryptoProvider;
2623
2475
  }
2624
2476
  function randomBytes(length) {
2625
2477
  if (!Number.isInteger(length) || length <= 0) {
@@ -2739,6 +2591,71 @@ var init_redis_error_listener = __esm({
2739
2591
  DEFAULT_REDIS_ERROR_LOG_INTERVAL_MS = 3e4;
2740
2592
  }
2741
2593
  });
2594
+ function decodeOrRaw(encoded) {
2595
+ try {
2596
+ return decodeURIComponent(encoded);
2597
+ } catch {
2598
+ return encoded;
2599
+ }
2600
+ }
2601
+ function integerOrUndefined(text) {
2602
+ const value = Number.parseInt(text ?? "", 10);
2603
+ return Number.isNaN(value) ? void 0 : value;
2604
+ }
2605
+ function readRedisUrl(rawUrl) {
2606
+ let url;
2607
+ try {
2608
+ url = new URL(rawUrl);
2609
+ } catch {
2610
+ return void 0;
2611
+ }
2612
+ if (url.protocol !== "redis:" && url.protocol !== "rediss:") return void 0;
2613
+ const query = Object.fromEntries(url.searchParams);
2614
+ const { host, port, username, password, db, ...otherOptions } = query;
2615
+ const queryOptions = {};
2616
+ for (const [name, value = ""] of Object.entries(otherOptions)) {
2617
+ queryOptions[name] = name === "family" ? integerOrUndefined(value) ?? value : value;
2618
+ }
2619
+ return {
2620
+ host: url.hostname.replace(/^\[(.*)\]$/, "$1") || host,
2621
+ port: integerOrUndefined(url.port || port),
2622
+ username: decodeOrRaw(url.username) || username || void 0,
2623
+ password: decodeOrRaw(url.password) || password || void 0,
2624
+ db: integerOrUndefined(url.pathname.replace(/^\/+/, "") || db),
2625
+ tls: url.protocol === "rediss:",
2626
+ queryOptions
2627
+ };
2628
+ }
2629
+ function mergeRedisUrlFields(rawUrl, fields) {
2630
+ const connection = readRedisUrl(rawUrl);
2631
+ if (!connection) return void 0;
2632
+ const fillIns = {};
2633
+ const conflicts = [];
2634
+ if (fields.host !== void 0 && fields.host !== connection.host) conflicts.push("host");
2635
+ if (fields.port !== void 0) {
2636
+ if (connection.port === void 0) fillIns.port = fields.port;
2637
+ else if (fields.port !== connection.port) conflicts.push("port");
2638
+ }
2639
+ if (fields.password !== void 0) {
2640
+ if (connection.password === void 0) fillIns.password = fields.password;
2641
+ else if (fields.password !== connection.password) conflicts.push("password");
2642
+ }
2643
+ if (fields.db !== void 0) {
2644
+ if (connection.db === void 0) fillIns.db = fields.db;
2645
+ else if (fields.db !== connection.db) conflicts.push("db");
2646
+ }
2647
+ if (fields.tls === true && !connection.tls) fillIns.tls = true;
2648
+ if (fields.tls === false && connection.tls) conflicts.push("tls");
2649
+ return { connection, fillIns, conflicts };
2650
+ }
2651
+ function describeRedisUrlConflicts(conflicts) {
2652
+ return `redis ${conflicts.join(", ")} contradict${conflicts.length === 1 ? "s" : ""} redis.url. Fields beside a url only fill in what the URL leaves out (port, password, db, tls); put the value in the URL or drop the field.`;
2653
+ }
2654
+ var init_redis_url = __esm({
2655
+ "libs/utils/src/storage/redis-url.ts"() {
2656
+ "use strict";
2657
+ }
2658
+ });
2742
2659
  var init_utils = __esm({
2743
2660
  "libs/utils/src/storage/utils/index.ts"() {
2744
2661
  "use strict";
@@ -2773,17 +2690,49 @@ function getRedisClass() {
2773
2690
  });
2774
2691
  }
2775
2692
  }
2693
+ function resolveUrlOptions(connectionUrl, options) {
2694
+ const { url: configUrl, ...siblingFields } = { url: void 0, ...options.config };
2695
+ if (options.url && configUrl && configUrl !== options.url) {
2696
+ throw new StorageConfigError("redis", "redis.url and redis.config.url name different servers; set one of them.");
2697
+ }
2698
+ return urlConnectionOptions(connectionUrl, siblingFields);
2699
+ }
2700
+ function urlConnectionOptions(url, fields) {
2701
+ const merge = mergeRedisUrlFields(url, fields);
2702
+ if (!merge) return void 0;
2703
+ if (merge.conflicts.length > 0) {
2704
+ throw new StorageConfigError("redis", describeRedisUrlConflicts(merge.conflicts));
2705
+ }
2706
+ const { queryOptions, tls, ...stated } = merge.connection;
2707
+ return { ...queryOptions, ...stated, ...toFillInOptions(merge.fillIns), ...tls ? { tls: {} } : {} };
2708
+ }
2709
+ function toFillInOptions({ port, password, db, tls }) {
2710
+ return {
2711
+ ...port !== void 0 ? { port } : {},
2712
+ ...password !== void 0 ? { password } : {},
2713
+ ...db !== void 0 ? { db } : {},
2714
+ ...tls ? { tls: {} } : {}
2715
+ };
2716
+ }
2776
2717
  function createRedisClient(options) {
2718
+ const urlOptions = options.url ? urlConnectionOptions(options.url, options) : void 0;
2777
2719
  const RedisClass = getRedisClass();
2778
2720
  const baseOptions = { lazyConnect: false, maxRetriesPerRequest: 3 };
2779
- const client = options.url ? new RedisClass(options.url, baseOptions) : new RedisClass({
2780
- ...baseOptions,
2781
- host: options.host ?? "localhost",
2782
- port: options.port ?? 6379,
2783
- password: options.password,
2784
- db: options.db ?? 0,
2785
- tls: options.tls ? {} : void 0
2786
- });
2721
+ let client;
2722
+ if (urlOptions) {
2723
+ client = new RedisClass({ ...baseOptions, ...urlOptions });
2724
+ } else if (options.url) {
2725
+ client = new RedisClass(options.url, baseOptions);
2726
+ } else {
2727
+ client = new RedisClass({
2728
+ ...baseOptions,
2729
+ host: options.host ?? "localhost",
2730
+ port: options.port ?? 6379,
2731
+ password: options.password,
2732
+ db: options.db ?? 0,
2733
+ tls: options.tls ? {} : void 0
2734
+ });
2735
+ }
2787
2736
  attachRedisErrorListener(client, { label: options.label ?? "redis", logger: options.logger });
2788
2737
  return client;
2789
2738
  }
@@ -2793,6 +2742,7 @@ var init_redis = __esm({
2793
2742
  "use strict";
2794
2743
  init_errors();
2795
2744
  init_redis_error_listener();
2745
+ init_redis_url();
2796
2746
  init_utils();
2797
2747
  init_compare_and_delete();
2798
2748
  init_base();
@@ -2806,6 +2756,9 @@ var init_redis = __esm({
2806
2756
  connecting;
2807
2757
  keyPrefix;
2808
2758
  subscriptionHandlers = /* @__PURE__ */ new Map();
2759
+ connectionUrl;
2760
+ /** The connection options of a URL this adapter reads itself; undefined for one only ioredis reads. */
2761
+ urlOptions;
2809
2762
  constructor(options = {}) {
2810
2763
  super();
2811
2764
  const hasClient = options.client !== void 0;
@@ -2827,6 +2780,9 @@ var init_redis = __esm({
2827
2780
  this.options = options;
2828
2781
  this.ownsClient = !hasClient;
2829
2782
  this.keyPrefix = options.keyPrefix ?? "";
2783
+ const configUrl = options.config?.url;
2784
+ this.connectionUrl = options.url ?? (typeof configUrl === "string" ? configUrl : void 0);
2785
+ this.urlOptions = this.connectionUrl ? resolveUrlOptions(this.connectionUrl, options) : void 0;
2830
2786
  }
2831
2787
  // ============================================
2832
2788
  // Connection Lifecycle
@@ -2848,12 +2804,7 @@ var init_redis = __esm({
2848
2804
  if (this.options.client) {
2849
2805
  client = this.options.client;
2850
2806
  } else {
2851
- const RedisClass = getRedisClass();
2852
- if (this.options.url) {
2853
- client = new RedisClass(this.options.url, this.buildRedisOptions());
2854
- } else {
2855
- client = new RedisClass(this.buildRedisOptions());
2856
- }
2807
+ client = this.newClient();
2857
2808
  client.on("error", recordSocketError);
2858
2809
  }
2859
2810
  await client.ping();
@@ -3086,14 +3037,11 @@ var init_redis = __esm({
3086
3037
  * Build Redis options from config.
3087
3038
  */
3088
3039
  buildRedisOptions() {
3089
- if (this.options.url) {
3090
- return {
3091
- lazyConnect: false,
3092
- maxRetriesPerRequest: 3
3093
- };
3040
+ if (this.connectionUrl) {
3041
+ return { lazyConnect: false, maxRetriesPerRequest: 3, ...this.urlOptions };
3094
3042
  }
3095
3043
  const config = this.options.config;
3096
- if (!config) {
3044
+ if (!config || typeof config.url === "string" || config.host === void 0) {
3097
3045
  throw new StorageConfigError("redis", "Redis config is required when URL is not provided");
3098
3046
  }
3099
3047
  return {
@@ -3106,16 +3054,23 @@ var init_redis = __esm({
3106
3054
  maxRetriesPerRequest: 3
3107
3055
  };
3108
3056
  }
3057
+ /**
3058
+ * Create a client this adapter owns. A URL only ioredis reads goes to it as is.
3059
+ */
3060
+ newClient() {
3061
+ const RedisClass = getRedisClass();
3062
+ if (this.connectionUrl && !this.urlOptions) {
3063
+ return new RedisClass(this.connectionUrl, this.buildRedisOptions());
3064
+ }
3065
+ return new RedisClass(this.buildRedisOptions());
3066
+ }
3109
3067
  /**
3110
3068
  * Create subscriber connection.
3111
3069
  */
3112
3070
  async createSubscriber() {
3113
- const RedisClass = getRedisClass();
3114
3071
  let subscriber;
3115
- if (this.options.url) {
3116
- subscriber = new RedisClass(this.options.url);
3117
- } else if (this.options.config) {
3118
- subscriber = new RedisClass(this.buildRedisOptions());
3072
+ if (this.connectionUrl || this.options.config) {
3073
+ subscriber = this.newClient();
3119
3074
  } else if (this.options.client) {
3120
3075
  subscriber = this.options.client.duplicate();
3121
3076
  } else {
@@ -3162,7 +3117,8 @@ var init_redis = __esm({
3162
3117
  });
3163
3118
  var vercel_kv_exports = {};
3164
3119
  __export(vercel_kv_exports, {
3165
- VercelKvStorageAdapter: () => VercelKvStorageAdapter
3120
+ VercelKvStorageAdapter: () => VercelKvStorageAdapter,
3121
+ createVercelKvClient: () => createVercelKvClient
3166
3122
  });
3167
3123
  async function loadVercelKv() {
3168
3124
  try {
@@ -3174,6 +3130,15 @@ async function loadVercelKv() {
3174
3130
  throw new Error("@vercel/kv is required for Vercel KV storage adapter. Install it with: npm install @vercel/kv");
3175
3131
  }
3176
3132
  }
3133
+ async function createVercelKvClient(connection = {}) {
3134
+ const url = connection.url ?? process.env["KV_REST_API_URL"];
3135
+ const token = connection.token ?? process.env["KV_REST_API_TOKEN"];
3136
+ if (!url || !token) {
3137
+ throw new StorageConfigError("vercel-kv", "Pass url and token, or set KV_REST_API_URL and KV_REST_API_TOKEN.");
3138
+ }
3139
+ const { createClient } = await loadVercelKv();
3140
+ return createClient({ url, token, cache: void 0, automaticDeserialization: false });
3141
+ }
3177
3142
  var VercelKvStorageAdapter;
3178
3143
  var init_vercel_kv = __esm({
3179
3144
  "libs/utils/src/storage/adapters/vercel-kv.ts"() {
@@ -3206,13 +3171,7 @@ var init_vercel_kv = __esm({
3206
3171
  async connect() {
3207
3172
  if (this.connected) return;
3208
3173
  try {
3209
- const { createClient } = await loadVercelKv();
3210
- const url = this.options.url;
3211
- const token = this.options.token;
3212
- if (!url || !token) {
3213
- throw new StorageConfigError("vercel-kv", "URL and token are required");
3214
- }
3215
- this.client = createClient({ url, token, cache: void 0, automaticDeserialization: false });
3174
+ this.client = await createVercelKvClient({ url: this.options.url, token: this.options.token });
3216
3175
  await this.client.exists("__healthcheck__");
3217
3176
  this.connected = true;
3218
3177
  } catch (e) {
@@ -3383,9 +3342,12 @@ var upstash_exports = {};
3383
3342
  __export(upstash_exports, {
3384
3343
  UpstashStorageAdapter: () => UpstashStorageAdapter
3385
3344
  });
3386
- function getUpstashRedis() {
3345
+ async function loadUpstashRedis() {
3387
3346
  try {
3388
- return __require2("@upstash/redis");
3347
+ const mod = await import("@upstash/redis");
3348
+ const resolved = typeof mod.Redis === "function" ? mod : mod.default;
3349
+ if (!resolved || typeof resolved.Redis !== "function") throw new Error("Redis missing");
3350
+ return resolved;
3389
3351
  } catch {
3390
3352
  throw new Error(
3391
3353
  "@upstash/redis is required for Upstash storage adapter. Install it with: npm install @upstash/redis"
@@ -3431,7 +3393,7 @@ var init_upstash = __esm({
3431
3393
  async connect() {
3432
3394
  if (this.connected) return;
3433
3395
  try {
3434
- const { Redis } = getUpstashRedis();
3396
+ const { Redis } = await loadUpstashRedis();
3435
3397
  const url = this.options.url;
3436
3398
  const token = this.options.token;
3437
3399
  if (!url || !token) {
@@ -3920,6 +3882,7 @@ init_errors();
3920
3882
  init_errors();
3921
3883
  init_memory();
3922
3884
  init_redis_error_listener();
3885
+ init_redis_url();
3923
3886
  init_errors();
3924
3887
  init_crypto();
3925
3888
  init_errors();