@iqauth/sdk 2.2.0 → 2.5.0

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 (96) hide show
  1. package/README.md +134 -0
  2. package/dist/browser-session.d.mts +3 -3
  3. package/dist/browser-session.d.ts +3 -3
  4. package/dist/browser-session.js +89 -68
  5. package/dist/browser-session.mjs +2 -1
  6. package/dist/browser.d.mts +64 -29
  7. package/dist/browser.d.ts +64 -29
  8. package/dist/browser.js +794 -39
  9. package/dist/browser.mjs +44 -4
  10. package/dist/bundle-LUKDQYVQ.mjs +374 -0
  11. package/dist/chunk-3JULWS6F.mjs +106 -0
  12. package/dist/chunk-5T7GHBX6.mjs +1165 -0
  13. package/dist/{chunk-M4J6BPK7.mjs → chunk-6TDJJER7.mjs} +12 -3
  14. package/dist/{chunk-QZB745C2.mjs → chunk-76W5TLQQ.mjs} +264 -211
  15. package/dist/{chunk-D72UL5HL.mjs → chunk-BVV54LPI.mjs} +36 -4
  16. package/dist/chunk-LIZYFXH7.mjs +90 -0
  17. package/dist/chunk-MKKZULZR.mjs +241 -0
  18. package/dist/chunk-SL3KRS4W.mjs +54 -0
  19. package/dist/chunk-TKZTCPEK.mjs +232 -0
  20. package/dist/chunk-UKZLOHZG.mjs +83 -0
  21. package/dist/chunk-UNYDG2L4.mjs +209 -0
  22. package/dist/{chunk-MDUHPQMM.mjs → chunk-W3F4JYGP.mjs} +8 -180
  23. package/dist/{chunk-QEJB7WEQ.mjs → chunk-WQWBJSSS.mjs} +1 -1
  24. package/dist/cli/index.js +144 -36
  25. package/dist/cli/index.mjs +1 -1
  26. package/dist/{client-DXbHb2ul.d.ts → client-BNQe3AgF.d.ts} +3 -67
  27. package/dist/{client-Dv4v92Mj.d.mts → client-kYlJFgPv.d.mts} +3 -67
  28. package/dist/doctor-YYNHNMLD.mjs +198 -0
  29. package/dist/{express-BZmF1llh.d.mts → express-B6_1vBYZ.d.mts} +23 -2
  30. package/dist/{express-B4o3P8vK.d.ts → express-CHpfa7D_.d.ts} +23 -2
  31. package/dist/express.d.mts +77 -6
  32. package/dist/express.d.ts +77 -6
  33. package/dist/express.js +336 -74
  34. package/dist/express.mjs +209 -8
  35. package/dist/fastify.js +103 -72
  36. package/dist/fastify.mjs +6 -4
  37. package/dist/hono.js +102 -72
  38. package/dist/hono.mjs +5 -4
  39. package/dist/index.d.mts +8 -4
  40. package/dist/index.d.ts +8 -4
  41. package/dist/index.js +590 -73
  42. package/dist/index.mjs +30 -8
  43. package/dist/locales.d.mts +53 -0
  44. package/dist/locales.d.ts +53 -0
  45. package/dist/locales.js +1202 -0
  46. package/dist/locales.mjs +29 -0
  47. package/dist/mobile.d.mts +3 -3
  48. package/dist/mobile.d.ts +3 -3
  49. package/dist/mobile.js +89 -68
  50. package/dist/mobile.mjs +2 -1
  51. package/dist/next.d.mts +10 -1
  52. package/dist/next.d.ts +10 -1
  53. package/dist/next.js +101 -1618
  54. package/dist/next.mjs +9 -9
  55. package/dist/provisioningBridge-88xjOS2n.d.mts +86 -0
  56. package/dist/provisioningBridge-DnTfzdZK.d.ts +86 -0
  57. package/dist/react.d.mts +1349 -10
  58. package/dist/react.d.ts +1349 -10
  59. package/dist/react.js +2998 -569
  60. package/dist/react.mjs +1518 -95
  61. package/dist/reverify-4UEJXUS6.mjs +16 -0
  62. package/dist/server/handlers.d.mts +12 -1
  63. package/dist/server/handlers.d.ts +12 -1
  64. package/dist/server/handlers.js +12 -3
  65. package/dist/server/handlers.mjs +2 -2
  66. package/dist/server.d.mts +5 -4
  67. package/dist/server.d.ts +5 -4
  68. package/dist/server.js +188 -73
  69. package/dist/server.mjs +13 -8
  70. package/dist/service.d.mts +3 -3
  71. package/dist/service.d.ts +3 -3
  72. package/dist/service.js +89 -68
  73. package/dist/service.mjs +2 -1
  74. package/dist/signIn-CCY4JE5G.mjs +15 -0
  75. package/dist/{signIn-D_kP3v-c.d.mts → signIn-CiIBTJIh.d.mts} +232 -4
  76. package/dist/{signIn-BVDTIA_t.d.ts → signIn-OCr88Zf8.d.ts} +232 -4
  77. package/dist/test.d.mts +86 -0
  78. package/dist/test.d.ts +86 -0
  79. package/dist/test.js +289 -0
  80. package/dist/test.mjs +9 -0
  81. package/dist/tokens-DCyzzn8L.d.mts +63 -0
  82. package/dist/tokens-aHiGFr_E.d.ts +63 -0
  83. package/dist/types-6bNdxesb.d.mts +196 -0
  84. package/dist/types-6bNdxesb.d.ts +196 -0
  85. package/dist/{types-Cxl3bQHt.d.ts → types-DZAflmmq.d.mts} +6 -0
  86. package/dist/{types-Cxl3bQHt.d.mts → types-DZAflmmq.d.ts} +6 -0
  87. package/dist/webhooks.d.mts +61 -0
  88. package/dist/webhooks.d.ts +61 -0
  89. package/dist/webhooks.js +119 -0
  90. package/dist/webhooks.mjs +11 -0
  91. package/dist/ws.d.mts +73 -0
  92. package/dist/ws.d.ts +73 -0
  93. package/dist/ws.js +397 -0
  94. package/dist/ws.mjs +12 -0
  95. package/package.json +24 -3
  96. package/dist/doctor-XCI77BQS.mjs +0 -90
@@ -0,0 +1,83 @@
1
+ // src/webhooks.ts
2
+ import crypto from "crypto";
3
+ var WebhookSignatureError = class extends Error {
4
+ constructor(code, message) {
5
+ super(message);
6
+ this.name = "WebhookSignatureError";
7
+ this.code = code;
8
+ }
9
+ };
10
+ function toBuffer(p) {
11
+ if (typeof p === "string") return Buffer.from(p, "utf8");
12
+ if (Buffer.isBuffer(p)) return p;
13
+ return Buffer.from(p);
14
+ }
15
+ function parseHeader(header) {
16
+ let t = NaN;
17
+ const v1 = [];
18
+ for (const part of header.split(",")) {
19
+ const [k, v] = part.split("=", 2);
20
+ if (!k || v === void 0) continue;
21
+ const key = k.trim();
22
+ const value = v.trim();
23
+ if (key === "t") t = Number(value);
24
+ else if (key === "v1") v1.push(value);
25
+ }
26
+ return { t, v1 };
27
+ }
28
+ function timingSafeEqualHex(a, b) {
29
+ if (a.length !== b.length) return false;
30
+ try {
31
+ return crypto.timingSafeEqual(Buffer.from(a, "hex"), Buffer.from(b, "hex"));
32
+ } catch {
33
+ return false;
34
+ }
35
+ }
36
+ function verifyWebhookSignature(opts) {
37
+ const headerRaw = Array.isArray(opts.header) ? opts.header[0] : opts.header;
38
+ if (!headerRaw || typeof headerRaw !== "string") {
39
+ throw new WebhookSignatureError("MISSING_HEADER", "Missing X-IQAuth-Signature header");
40
+ }
41
+ if (!opts.secret) {
42
+ throw new WebhookSignatureError("MISSING_SECRET", "secret is required");
43
+ }
44
+ const { t, v1 } = parseHeader(headerRaw);
45
+ if (!Number.isFinite(t) || v1.length === 0) {
46
+ throw new WebhookSignatureError("MALFORMED_HEADER", `Could not parse signature header: ${headerRaw}`);
47
+ }
48
+ const tolerance = opts.toleranceSeconds ?? 300;
49
+ const now = opts.nowSeconds ?? Math.floor(Date.now() / 1e3);
50
+ if (Math.abs(now - t) > tolerance) {
51
+ throw new WebhookSignatureError(
52
+ "TIMESTAMP_OUT_OF_TOLERANCE",
53
+ `Signature timestamp ${t} is outside the ${tolerance}s tolerance window (now=${now})`
54
+ );
55
+ }
56
+ const body = toBuffer(opts.payload);
57
+ const expected = crypto.createHmac("sha256", opts.secret).update(`${t}.`).update(body).digest("hex");
58
+ const matched = v1.some((sig) => timingSafeEqualHex(sig, expected));
59
+ if (!matched) {
60
+ throw new WebhookSignatureError("SIGNATURE_MISMATCH", "Webhook signature does not match expected value");
61
+ }
62
+ let parsed;
63
+ try {
64
+ parsed = JSON.parse(body.toString("utf8"));
65
+ } catch {
66
+ throw new WebhookSignatureError("MALFORMED_BODY", "Webhook body is not valid JSON");
67
+ }
68
+ return parsed;
69
+ }
70
+ function isValidWebhookSignature(opts) {
71
+ try {
72
+ verifyWebhookSignature(opts);
73
+ return true;
74
+ } catch {
75
+ return false;
76
+ }
77
+ }
78
+
79
+ export {
80
+ WebhookSignatureError,
81
+ verifyWebhookSignature,
82
+ isValidWebhookSignature
83
+ };
@@ -0,0 +1,209 @@
1
+ import {
2
+ IQAuthError
3
+ } from "./chunk-6I6RM4MN.mjs";
4
+ import {
5
+ __require
6
+ } from "./chunk-Y6FXYEAI.mjs";
7
+
8
+ // src/modules/tokens.ts
9
+ import {
10
+ createLocalJWKSet,
11
+ jwtVerify,
12
+ errors as joseErrors
13
+ } from "jose";
14
+ var JWKS_CACHE_TTL_MS = 60 * 60 * 1e3;
15
+ var DEFAULT_TOKEN_ISSUER = [
16
+ "https://auth.dispositioniq.com",
17
+ "auth.dispositioniq.com"
18
+ ];
19
+ var DEFAULT_TOKEN_AUDIENCE = [
20
+ "dispositioniq",
21
+ "iqcapture",
22
+ "iqreuse",
23
+ "iqvalidate"
24
+ ];
25
+ var DEFAULT_CLOCK_TOLERANCE_SECONDS = 30;
26
+ function decodeProtectedHeader(token) {
27
+ const parts = token.split(".");
28
+ if (parts.length < 2) return null;
29
+ try {
30
+ const padded = parts[0] + "=".repeat((4 - parts[0].length % 4) % 4);
31
+ const b64 = padded.replace(/-/g, "+").replace(/_/g, "/");
32
+ let json;
33
+ if (typeof atob === "function") {
34
+ json = atob(b64);
35
+ } else {
36
+ const { Buffer } = __require("buffer");
37
+ json = Buffer.from(b64, "base64").toString("utf8");
38
+ }
39
+ return JSON.parse(json);
40
+ } catch {
41
+ return null;
42
+ }
43
+ }
44
+ var TokensModule = class {
45
+ constructor(baseUrl, options = {}) {
46
+ this.jwksCache = null;
47
+ this.inFlightRefresh = null;
48
+ this.baseUrl = baseUrl;
49
+ this.defaultIssuer = options.issuer ?? DEFAULT_TOKEN_ISSUER;
50
+ this.defaultAudience = options.audience ?? DEFAULT_TOKEN_AUDIENCE;
51
+ this.defaultClockTolerance = options.clockTolerance ?? DEFAULT_CLOCK_TOLERANCE_SECONDS;
52
+ }
53
+ /**
54
+ * Verify a JWT access token using RS256/ES256 via JWKS from
55
+ * `/.well-known/jwks.json`. Backed by `jose` (Web Crypto) so it runs on
56
+ * Node, browser, and edge runtimes alike — no `node:crypto` dependency.
57
+ * Caches JWKS for 1 hour and refetches once on unknown `kid`.
58
+ */
59
+ async verify(token, options = {}) {
60
+ const header = decodeProtectedHeader(token);
61
+ if (!header) {
62
+ throw new IQAuthError("TOKEN_INVALID", "Unable to decode token");
63
+ }
64
+ const kid = header.kid;
65
+ if (!kid) {
66
+ throw new IQAuthError("TOKEN_INVALID", "Token missing kid header");
67
+ }
68
+ let cache = await this.ensureCache();
69
+ if (!cache.byKid.has(kid)) {
70
+ this.jwksCache = null;
71
+ cache = await this.ensureCache();
72
+ }
73
+ if (!cache.byKid.has(kid)) {
74
+ throw new IQAuthError("TOKEN_INVALID", `Unknown key ID: ${kid}`);
75
+ }
76
+ const issuer = options.issuer ?? this.defaultIssuer;
77
+ const audience = options.audience ?? this.defaultAudience;
78
+ const clockTolerance = options.clockTolerance ?? this.defaultClockTolerance;
79
+ const algorithms = options.algorithms ?? ["RS256", "ES256"];
80
+ const verifyOptions = {
81
+ algorithms,
82
+ clockTolerance,
83
+ issuer,
84
+ audience
85
+ };
86
+ try {
87
+ const { payload } = await jwtVerify(token, cache.verifier, verifyOptions);
88
+ return payload;
89
+ } catch (err) {
90
+ if (err instanceof joseErrors.JWTExpired) {
91
+ throw new IQAuthError("TOKEN_EXPIRED", "Token has expired");
92
+ }
93
+ if (err instanceof joseErrors.JOSEError) {
94
+ throw new IQAuthError("TOKEN_INVALID", err.message);
95
+ }
96
+ if (err instanceof Error) {
97
+ throw new IQAuthError("TOKEN_INVALID", err.message);
98
+ }
99
+ throw new IQAuthError("TOKEN_INVALID", "Token verification failed");
100
+ }
101
+ }
102
+ /**
103
+ * Decode a JWT without verification. Returns null if malformed.
104
+ */
105
+ decode(token) {
106
+ try {
107
+ const parts = token.split(".");
108
+ if (parts.length < 2) return null;
109
+ const payload = parts[1];
110
+ const padded = payload + "=".repeat((4 - payload.length % 4) % 4);
111
+ const b64 = padded.replace(/-/g, "+").replace(/_/g, "/");
112
+ let json;
113
+ if (typeof atob === "function") {
114
+ json = atob(b64);
115
+ } else {
116
+ const { Buffer } = __require("buffer");
117
+ json = Buffer.from(b64, "base64").toString("utf8");
118
+ }
119
+ try {
120
+ json = decodeURIComponent(escape(json));
121
+ } catch {
122
+ }
123
+ const claims = JSON.parse(json);
124
+ if (!claims || typeof claims !== "object") return null;
125
+ return claims;
126
+ } catch {
127
+ return null;
128
+ }
129
+ }
130
+ /** Check if a token is expired based on the `exp` claim. */
131
+ isExpired(token) {
132
+ const claims = this.decode(token);
133
+ if (!claims?.exp) return true;
134
+ const now = Math.floor(Date.now() / 1e3);
135
+ return claims.exp <= now;
136
+ }
137
+ /** Get the claims from a token without verification. */
138
+ getClaims(token) {
139
+ const claims = this.decode(token);
140
+ if (!claims) {
141
+ throw new IQAuthError("TOKEN_INVALID", "Unable to decode token claims");
142
+ }
143
+ return claims;
144
+ }
145
+ async ensureCache() {
146
+ if (this.jwksCache && Date.now() - this.jwksCache.fetchedAt <= JWKS_CACHE_TTL_MS) {
147
+ return this.jwksCache;
148
+ }
149
+ await this.refreshJwks();
150
+ if (!this.jwksCache) {
151
+ throw new IQAuthError("INTERNAL_ERROR", "JWKS cache unavailable after refresh");
152
+ }
153
+ return this.jwksCache;
154
+ }
155
+ async refreshJwks() {
156
+ if (this.inFlightRefresh) {
157
+ return this.inFlightRefresh;
158
+ }
159
+ this.inFlightRefresh = (async () => {
160
+ try {
161
+ const res = await fetch(`${this.baseUrl}/.well-known/jwks.json`);
162
+ if (!res.ok) {
163
+ throw new IQAuthError(
164
+ "INTERNAL_ERROR",
165
+ `Failed to fetch JWKS: ${res.status}`
166
+ );
167
+ }
168
+ let jwks;
169
+ try {
170
+ jwks = await res.json();
171
+ } catch {
172
+ throw new IQAuthError("INTERNAL_ERROR", "Malformed JWKS response: invalid JSON");
173
+ }
174
+ if (!jwks || !Array.isArray(jwks.keys)) {
175
+ throw new IQAuthError(
176
+ "INTERNAL_ERROR",
177
+ "Malformed JWKS response: expected { keys: [...] }"
178
+ );
179
+ }
180
+ const byKid = /* @__PURE__ */ new Set();
181
+ for (const key of jwks.keys) {
182
+ if (!key || typeof key.kid !== "string" || typeof key.n !== "string" && typeof key.x !== "string" || key.kty === "RSA" && (typeof key.n !== "string" || typeof key.e !== "string")) {
183
+ throw new IQAuthError(
184
+ "INTERNAL_ERROR",
185
+ "Malformed JWKS response: key missing required fields"
186
+ );
187
+ }
188
+ byKid.add(key.kid);
189
+ }
190
+ const verifier = createLocalJWKSet({ keys: jwks.keys });
191
+ this.jwksCache = { raw: jwks.keys, byKid, verifier, fetchedAt: Date.now() };
192
+ } finally {
193
+ this.inFlightRefresh = null;
194
+ }
195
+ })();
196
+ return this.inFlightRefresh;
197
+ }
198
+ /** @internal Exposed for testing — clears JWKS cache */
199
+ clearCache() {
200
+ this.jwksCache = null;
201
+ }
202
+ };
203
+
204
+ export {
205
+ DEFAULT_TOKEN_ISSUER,
206
+ DEFAULT_TOKEN_AUDIENCE,
207
+ DEFAULT_CLOCK_TOLERANCE_SECONDS,
208
+ TokensModule
209
+ };
@@ -1,3 +1,6 @@
1
+ import {
2
+ TokensModule
3
+ } from "./chunk-UNYDG2L4.mjs";
1
4
  import {
2
5
  IQAuthError
3
6
  } from "./chunk-6I6RM4MN.mjs";
@@ -160,177 +163,6 @@ function parseMfaResponse(data, browserSessionMode) {
160
163
  throw new Error("Unexpected MFA response shape");
161
164
  }
162
165
 
163
- // src/modules/tokens.ts
164
- import crypto from "crypto";
165
- import jwt from "jsonwebtoken";
166
- var JWKS_CACHE_TTL_MS = 60 * 60 * 1e3;
167
- var DEFAULT_TOKEN_ISSUER = [
168
- "https://auth.dispositioniq.com",
169
- "auth.dispositioniq.com"
170
- ];
171
- var DEFAULT_TOKEN_AUDIENCE = [
172
- "dispositioniq",
173
- "iqcapture",
174
- "iqreuse",
175
- "iqvalidate"
176
- ];
177
- var DEFAULT_CLOCK_TOLERANCE_SECONDS = 30;
178
- var TokensModule = class {
179
- constructor(baseUrl, options = {}) {
180
- this.jwksCache = null;
181
- this.inFlightRefresh = null;
182
- this.baseUrl = baseUrl;
183
- this.defaultIssuer = options.issuer ?? DEFAULT_TOKEN_ISSUER;
184
- this.defaultAudience = options.audience ?? DEFAULT_TOKEN_AUDIENCE;
185
- this.defaultClockTolerance = options.clockTolerance ?? DEFAULT_CLOCK_TOLERANCE_SECONDS;
186
- }
187
- /**
188
- * Verify a JWT access token using RS256 via JWKS from /.well-known/jwks.json.
189
- * Caches JWKS keys for 1 hour. Retries once on unknown `kid`.
190
- *
191
- * @remarks Validates against /.well-known/jwks.json. Issuer, audience, and
192
- * clock tolerance default to client config but can be overridden per call.
193
- */
194
- async verify(token, options = {}) {
195
- const decoded = jwt.decode(token, { complete: true });
196
- if (!decoded || typeof decoded === "string") {
197
- throw new IQAuthError("TOKEN_INVALID", "Unable to decode token");
198
- }
199
- const kid = decoded.header.kid;
200
- if (!kid) {
201
- throw new IQAuthError("TOKEN_INVALID", "Token missing kid header");
202
- }
203
- let publicKey = await this.getPublicKey(kid);
204
- if (!publicKey) {
205
- await this.refreshJwks();
206
- publicKey = await this.getPublicKey(kid);
207
- }
208
- if (!publicKey) {
209
- throw new IQAuthError("TOKEN_INVALID", `Unknown key ID: ${kid}`);
210
- }
211
- const issuer = options.issuer ?? this.defaultIssuer;
212
- const audience = options.audience ?? this.defaultAudience;
213
- const clockTolerance = options.clockTolerance ?? this.defaultClockTolerance;
214
- const algorithms = options.algorithms ?? ["RS256"];
215
- try {
216
- const verifyOptions = {
217
- algorithms,
218
- clockTolerance,
219
- // The jsonwebtoken types insist on tuple types for arrays; runtime
220
- // accepts plain string[] so we cast to satisfy the compiler.
221
- issuer,
222
- audience
223
- };
224
- const verified = jwt.verify(token, publicKey, verifyOptions);
225
- return verified;
226
- } catch (err) {
227
- if (err instanceof Error) {
228
- if (err.name === "TokenExpiredError") {
229
- throw new IQAuthError("TOKEN_EXPIRED", "Token has expired");
230
- }
231
- throw new IQAuthError("TOKEN_INVALID", err.message);
232
- }
233
- throw new IQAuthError("TOKEN_INVALID", "Token verification failed");
234
- }
235
- }
236
- /**
237
- * Decode a JWT without verification. Returns null if malformed.
238
- *
239
- * @remarks Local decode only — no network call
240
- */
241
- decode(token) {
242
- const decoded = jwt.decode(token);
243
- return decoded;
244
- }
245
- /**
246
- * Check if a token is expired based on the `exp` claim.
247
- *
248
- * @remarks Local check only — no network call
249
- */
250
- isExpired(token) {
251
- const claims = this.decode(token);
252
- if (!claims?.exp) return true;
253
- const now = Math.floor(Date.now() / 1e3);
254
- return claims.exp <= now;
255
- }
256
- /**
257
- * Get the claims from a token without verification.
258
- *
259
- * @remarks Local decode only — no network call
260
- */
261
- getClaims(token) {
262
- const claims = this.decode(token);
263
- if (!claims) {
264
- throw new IQAuthError("TOKEN_INVALID", "Unable to decode token claims");
265
- }
266
- return claims;
267
- }
268
- async getPublicKey(kid) {
269
- if (!this.jwksCache || Date.now() - this.jwksCache.fetchedAt > JWKS_CACHE_TTL_MS) {
270
- await this.refreshJwks();
271
- }
272
- return this.jwksCache?.keys.get(kid) ?? null;
273
- }
274
- async refreshJwks() {
275
- if (this.inFlightRefresh) {
276
- return this.inFlightRefresh;
277
- }
278
- this.inFlightRefresh = (async () => {
279
- try {
280
- const res = await fetch(`${this.baseUrl}/.well-known/jwks.json`);
281
- if (!res.ok) {
282
- throw new IQAuthError(
283
- "INTERNAL_ERROR",
284
- `Failed to fetch JWKS: ${res.status}`
285
- );
286
- }
287
- let jwks;
288
- try {
289
- jwks = await res.json();
290
- } catch {
291
- throw new IQAuthError("INTERNAL_ERROR", "Malformed JWKS response: invalid JSON");
292
- }
293
- if (!jwks || !Array.isArray(jwks.keys)) {
294
- throw new IQAuthError(
295
- "INTERNAL_ERROR",
296
- "Malformed JWKS response: expected { keys: [...] }"
297
- );
298
- }
299
- const keys = /* @__PURE__ */ new Map();
300
- for (const key of jwks.keys) {
301
- if (!key || typeof key.kid !== "string" || typeof key.n !== "string" || typeof key.e !== "string") {
302
- throw new IQAuthError(
303
- "INTERNAL_ERROR",
304
- "Malformed JWKS response: key missing required fields"
305
- );
306
- }
307
- const pem = this.jwkToPem(key);
308
- keys.set(key.kid, pem);
309
- }
310
- this.jwksCache = { keys, fetchedAt: Date.now() };
311
- } finally {
312
- this.inFlightRefresh = null;
313
- }
314
- })();
315
- return this.inFlightRefresh;
316
- }
317
- jwkToPem(jwk) {
318
- const keyObject = crypto.createPublicKey({
319
- key: {
320
- kty: jwk.kty,
321
- n: jwk.n,
322
- e: jwk.e
323
- },
324
- format: "jwk"
325
- });
326
- return keyObject.export({ type: "spki", format: "pem" });
327
- }
328
- /** @internal Exposed for testing — clears JWKS cache */
329
- clearCache() {
330
- this.jwksCache = null;
331
- }
332
- };
333
-
334
166
  // src/modules/sessions.ts
335
167
  var SessionsModule = class {
336
168
  constructor(http) {
@@ -532,7 +364,7 @@ var PermissionsModule = class {
532
364
  };
533
365
 
534
366
  // src/modules/oidc.ts
535
- import crypto2 from "crypto";
367
+ import crypto from "crypto";
536
368
  var InMemoryOidcStateStore = class {
537
369
  constructor() {
538
370
  this.map = /* @__PURE__ */ new Map();
@@ -613,12 +445,12 @@ var OidcModule = class {
613
445
  * ready to redirect the user to.
614
446
  */
615
447
  async createAuthRequest(params) {
616
- const codeVerifier = base64UrlEncode(crypto2.randomBytes(32));
448
+ const codeVerifier = base64UrlEncode(crypto.randomBytes(32));
617
449
  const codeChallenge = base64UrlEncode(
618
- crypto2.createHash("sha256").update(codeVerifier).digest()
450
+ crypto.createHash("sha256").update(codeVerifier).digest()
619
451
  );
620
- const state = base64UrlEncode(crypto2.randomBytes(16));
621
- const nonce = base64UrlEncode(crypto2.randomBytes(16));
452
+ const state = base64UrlEncode(crypto.randomBytes(16));
453
+ const nonce = base64UrlEncode(crypto.randomBytes(16));
622
454
  await this.stateStore.set(state, {
623
455
  codeVerifier,
624
456
  state,
@@ -1712,10 +1544,6 @@ var IQAuthClient = class _IQAuthClient {
1712
1544
 
1713
1545
  export {
1714
1546
  AuthModule,
1715
- DEFAULT_TOKEN_ISSUER,
1716
- DEFAULT_TOKEN_AUDIENCE,
1717
- DEFAULT_CLOCK_TOLERANCE_SECONDS,
1718
- TokensModule,
1719
1547
  SessionsModule,
1720
1548
  UsersModule,
1721
1549
  PermissionsModule,
@@ -93,7 +93,7 @@ function assertPublishableKey(raw, opts) {
93
93
  if (!isValidIssuerUrl(decoded.iss)) {
94
94
  throw new IQAuthError(
95
95
  "CONFIG_INVALID",
96
- `${ctx}IQAuth publishable key encodes an invalid issuer (iss=${JSON.stringify(decoded.iss)}). Expected a fully-qualified URL like "https://auth.example.com" (scheme required). Regenerate the key from the IQAuth admin console, or set IQAUTH_ISSUER to the correct issuer URL as a temporary workaround.`
96
+ `${ctx}IQAuth publishable key encodes an invalid issuer (iss=${JSON.stringify(decoded.iss)}). Expected a fully-qualified URL like "https://auth.example.com" (scheme required). Regenerate the key from the IQAuth admin console \u2014 the new key will encode a valid issuer URL.`
97
97
  );
98
98
  }
99
99
  return { mode: shapeMatch[1], iss: decoded.iss, appId: decoded.appId, tenantId: decoded.tenantId, kid: decoded.kid, raw };