@iqauth/sdk 2.3.0 → 2.6.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 (87) hide show
  1. package/README.md +110 -0
  2. package/dist/browser-session.d.mts +3 -2
  3. package/dist/browser-session.d.ts +3 -2
  4. package/dist/browser.d.mts +64 -29
  5. package/dist/browser.d.ts +64 -29
  6. package/dist/browser.js +782 -38
  7. package/dist/browser.mjs +43 -3
  8. package/dist/bundle-LUKDQYVQ.mjs +374 -0
  9. package/dist/chunk-3JULWS6F.mjs +106 -0
  10. package/dist/chunk-5T7GHBX6.mjs +1165 -0
  11. package/dist/{chunk-KGEPDXHU.mjs → chunk-6TDJJER7.mjs} +2 -2
  12. package/dist/{chunk-RACIPVLD.mjs → chunk-76W5TLQQ.mjs} +262 -220
  13. package/dist/{chunk-EKTNEZIH.mjs → chunk-BVV54LPI.mjs} +37 -5
  14. package/dist/chunk-LIZYFXH7.mjs +90 -0
  15. package/dist/chunk-MKKZULZR.mjs +241 -0
  16. package/dist/chunk-SL3KRS4W.mjs +54 -0
  17. package/dist/chunk-TKZTCPEK.mjs +232 -0
  18. package/dist/chunk-UKZLOHZG.mjs +83 -0
  19. package/dist/cli/index.js +144 -36
  20. package/dist/cli/index.mjs +1 -1
  21. package/dist/{client-DTX4hNdS.d.ts → client-BNQe3AgF.d.ts} +3 -62
  22. package/dist/{client-vdh2a9fJ.d.mts → client-kYlJFgPv.d.mts} +3 -62
  23. package/dist/doctor-YYNHNMLD.mjs +198 -0
  24. package/dist/{express-A0-dWEMy.d.mts → express-B6_1vBYZ.d.mts} +23 -2
  25. package/dist/{express-Bo_pJKHN.d.ts → express-CHpfa7D_.d.ts} +23 -2
  26. package/dist/express.d.mts +5 -4
  27. package/dist/express.d.ts +5 -4
  28. package/dist/express.js +36 -4
  29. package/dist/express.mjs +8 -8
  30. package/dist/fastify.js +2 -2
  31. package/dist/fastify.mjs +4 -4
  32. package/dist/hono.js +2 -2
  33. package/dist/hono.mjs +4 -4
  34. package/dist/index.d.mts +8 -3
  35. package/dist/index.d.ts +8 -3
  36. package/dist/index.js +500 -4
  37. package/dist/index.mjs +29 -9
  38. package/dist/locales.d.mts +53 -0
  39. package/dist/locales.d.ts +53 -0
  40. package/dist/locales.js +1202 -0
  41. package/dist/locales.mjs +29 -0
  42. package/dist/mobile.d.mts +3 -2
  43. package/dist/mobile.d.ts +3 -2
  44. package/dist/next.d.mts +1 -1
  45. package/dist/next.d.ts +1 -1
  46. package/dist/next.js +2 -2
  47. package/dist/next.mjs +1 -1
  48. package/dist/provisioningBridge-88xjOS2n.d.mts +86 -0
  49. package/dist/provisioningBridge-DnTfzdZK.d.ts +86 -0
  50. package/dist/react.d.mts +1349 -10
  51. package/dist/react.d.ts +1349 -10
  52. package/dist/react.js +3006 -568
  53. package/dist/react.mjs +1540 -97
  54. package/dist/reverify-4UEJXUS6.mjs +16 -0
  55. package/dist/server/handlers.d.mts +10 -1
  56. package/dist/server/handlers.d.ts +10 -1
  57. package/dist/server/handlers.js +2 -2
  58. package/dist/server/handlers.mjs +1 -1
  59. package/dist/server.d.mts +5 -3
  60. package/dist/server.d.ts +5 -3
  61. package/dist/server.js +89 -4
  62. package/dist/server.mjs +12 -8
  63. package/dist/service.d.mts +3 -2
  64. package/dist/service.d.ts +3 -2
  65. package/dist/signIn-CCY4JE5G.mjs +15 -0
  66. package/dist/{signIn-Cd0P4y9d.d.mts → signIn-CiIBTJIh.d.mts} +224 -4
  67. package/dist/{signIn-DKakyzeu.d.ts → signIn-OCr88Zf8.d.ts} +224 -4
  68. package/dist/test.d.mts +86 -0
  69. package/dist/test.d.ts +86 -0
  70. package/dist/test.js +289 -0
  71. package/dist/test.mjs +9 -0
  72. package/dist/tokens-DCyzzn8L.d.mts +63 -0
  73. package/dist/tokens-aHiGFr_E.d.ts +63 -0
  74. package/dist/types-6bNdxesb.d.mts +196 -0
  75. package/dist/types-6bNdxesb.d.ts +196 -0
  76. package/dist/{types-Cxl3bQHt.d.mts → types-DZAflmmq.d.mts} +6 -0
  77. package/dist/{types-Cxl3bQHt.d.ts → types-DZAflmmq.d.ts} +6 -0
  78. package/dist/webhooks.d.mts +61 -0
  79. package/dist/webhooks.d.ts +61 -0
  80. package/dist/webhooks.js +119 -0
  81. package/dist/webhooks.mjs +11 -0
  82. package/dist/ws.d.mts +73 -0
  83. package/dist/ws.d.ts +73 -0
  84. package/dist/ws.js +397 -0
  85. package/dist/ws.mjs +12 -0
  86. package/package.json +22 -2
  87. package/dist/doctor-A5E7LSFW.mjs +0 -90
package/dist/ws.js ADDED
@@ -0,0 +1,397 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/ws.ts
21
+ var ws_exports = {};
22
+ __export(ws_exports, {
23
+ _resetWsVerifierCache: () => _resetWsVerifierCache,
24
+ verifyWsUpgrade: () => verifyWsUpgrade
25
+ });
26
+ module.exports = __toCommonJS(ws_exports);
27
+
28
+ // src/modules/tokens.ts
29
+ var import_jose = require("jose");
30
+
31
+ // src/errors.ts
32
+ var IQAuthError = class extends Error {
33
+ constructor(code, message, status, raw) {
34
+ super(message);
35
+ this.name = "IQAuthError";
36
+ this.code = code;
37
+ this.status = status;
38
+ this.raw = raw;
39
+ }
40
+ };
41
+
42
+ // src/modules/tokens.ts
43
+ var JWKS_CACHE_TTL_MS = 60 * 60 * 1e3;
44
+ var DEFAULT_TOKEN_ISSUER = [
45
+ "https://auth.dispositioniq.com",
46
+ "auth.dispositioniq.com"
47
+ ];
48
+ var DEFAULT_TOKEN_AUDIENCE = [
49
+ "dispositioniq",
50
+ "iqcapture",
51
+ "iqreuse",
52
+ "iqvalidate"
53
+ ];
54
+ var DEFAULT_CLOCK_TOLERANCE_SECONDS = 30;
55
+ function decodeProtectedHeader(token) {
56
+ const parts = token.split(".");
57
+ if (parts.length < 2) return null;
58
+ try {
59
+ const padded = parts[0] + "=".repeat((4 - parts[0].length % 4) % 4);
60
+ const b64 = padded.replace(/-/g, "+").replace(/_/g, "/");
61
+ let json;
62
+ if (typeof atob === "function") {
63
+ json = atob(b64);
64
+ } else {
65
+ const { Buffer: Buffer2 } = require("buffer");
66
+ json = Buffer2.from(b64, "base64").toString("utf8");
67
+ }
68
+ return JSON.parse(json);
69
+ } catch {
70
+ return null;
71
+ }
72
+ }
73
+ var TokensModule = class {
74
+ constructor(baseUrl, options = {}) {
75
+ this.jwksCache = null;
76
+ this.inFlightRefresh = null;
77
+ this.baseUrl = baseUrl;
78
+ this.defaultIssuer = options.issuer ?? DEFAULT_TOKEN_ISSUER;
79
+ this.defaultAudience = options.audience ?? DEFAULT_TOKEN_AUDIENCE;
80
+ this.defaultClockTolerance = options.clockTolerance ?? DEFAULT_CLOCK_TOLERANCE_SECONDS;
81
+ }
82
+ /**
83
+ * Verify a JWT access token using RS256/ES256 via JWKS from
84
+ * `/.well-known/jwks.json`. Backed by `jose` (Web Crypto) so it runs on
85
+ * Node, browser, and edge runtimes alike — no `node:crypto` dependency.
86
+ * Caches JWKS for 1 hour and refetches once on unknown `kid`.
87
+ */
88
+ async verify(token, options = {}) {
89
+ const header = decodeProtectedHeader(token);
90
+ if (!header) {
91
+ throw new IQAuthError("TOKEN_INVALID", "Unable to decode token");
92
+ }
93
+ const kid = header.kid;
94
+ if (!kid) {
95
+ throw new IQAuthError("TOKEN_INVALID", "Token missing kid header");
96
+ }
97
+ let cache = await this.ensureCache();
98
+ if (!cache.byKid.has(kid)) {
99
+ this.jwksCache = null;
100
+ cache = await this.ensureCache();
101
+ }
102
+ if (!cache.byKid.has(kid)) {
103
+ throw new IQAuthError("TOKEN_INVALID", `Unknown key ID: ${kid}`);
104
+ }
105
+ const issuer = options.issuer ?? this.defaultIssuer;
106
+ const audience = options.audience ?? this.defaultAudience;
107
+ const clockTolerance = options.clockTolerance ?? this.defaultClockTolerance;
108
+ const algorithms = options.algorithms ?? ["RS256", "ES256"];
109
+ const verifyOptions = {
110
+ algorithms,
111
+ clockTolerance,
112
+ issuer,
113
+ audience
114
+ };
115
+ try {
116
+ const { payload } = await (0, import_jose.jwtVerify)(token, cache.verifier, verifyOptions);
117
+ return payload;
118
+ } catch (err) {
119
+ if (err instanceof import_jose.errors.JWTExpired) {
120
+ throw new IQAuthError("TOKEN_EXPIRED", "Token has expired");
121
+ }
122
+ if (err instanceof import_jose.errors.JOSEError) {
123
+ throw new IQAuthError("TOKEN_INVALID", err.message);
124
+ }
125
+ if (err instanceof Error) {
126
+ throw new IQAuthError("TOKEN_INVALID", err.message);
127
+ }
128
+ throw new IQAuthError("TOKEN_INVALID", "Token verification failed");
129
+ }
130
+ }
131
+ /**
132
+ * Decode a JWT without verification. Returns null if malformed.
133
+ */
134
+ decode(token) {
135
+ try {
136
+ const parts = token.split(".");
137
+ if (parts.length < 2) return null;
138
+ const payload = parts[1];
139
+ const padded = payload + "=".repeat((4 - payload.length % 4) % 4);
140
+ const b64 = padded.replace(/-/g, "+").replace(/_/g, "/");
141
+ let json;
142
+ if (typeof atob === "function") {
143
+ json = atob(b64);
144
+ } else {
145
+ const { Buffer: Buffer2 } = require("buffer");
146
+ json = Buffer2.from(b64, "base64").toString("utf8");
147
+ }
148
+ try {
149
+ json = decodeURIComponent(escape(json));
150
+ } catch {
151
+ }
152
+ const claims = JSON.parse(json);
153
+ if (!claims || typeof claims !== "object") return null;
154
+ return claims;
155
+ } catch {
156
+ return null;
157
+ }
158
+ }
159
+ /** Check if a token is expired based on the `exp` claim. */
160
+ isExpired(token) {
161
+ const claims = this.decode(token);
162
+ if (!claims?.exp) return true;
163
+ const now = Math.floor(Date.now() / 1e3);
164
+ return claims.exp <= now;
165
+ }
166
+ /** Get the claims from a token without verification. */
167
+ getClaims(token) {
168
+ const claims = this.decode(token);
169
+ if (!claims) {
170
+ throw new IQAuthError("TOKEN_INVALID", "Unable to decode token claims");
171
+ }
172
+ return claims;
173
+ }
174
+ async ensureCache() {
175
+ if (this.jwksCache && Date.now() - this.jwksCache.fetchedAt <= JWKS_CACHE_TTL_MS) {
176
+ return this.jwksCache;
177
+ }
178
+ await this.refreshJwks();
179
+ if (!this.jwksCache) {
180
+ throw new IQAuthError("INTERNAL_ERROR", "JWKS cache unavailable after refresh");
181
+ }
182
+ return this.jwksCache;
183
+ }
184
+ async refreshJwks() {
185
+ if (this.inFlightRefresh) {
186
+ return this.inFlightRefresh;
187
+ }
188
+ this.inFlightRefresh = (async () => {
189
+ try {
190
+ const res = await fetch(`${this.baseUrl}/.well-known/jwks.json`);
191
+ if (!res.ok) {
192
+ throw new IQAuthError(
193
+ "INTERNAL_ERROR",
194
+ `Failed to fetch JWKS: ${res.status}`
195
+ );
196
+ }
197
+ let jwks;
198
+ try {
199
+ jwks = await res.json();
200
+ } catch {
201
+ throw new IQAuthError("INTERNAL_ERROR", "Malformed JWKS response: invalid JSON");
202
+ }
203
+ if (!jwks || !Array.isArray(jwks.keys)) {
204
+ throw new IQAuthError(
205
+ "INTERNAL_ERROR",
206
+ "Malformed JWKS response: expected { keys: [...] }"
207
+ );
208
+ }
209
+ const byKid = /* @__PURE__ */ new Set();
210
+ for (const key of jwks.keys) {
211
+ 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")) {
212
+ throw new IQAuthError(
213
+ "INTERNAL_ERROR",
214
+ "Malformed JWKS response: key missing required fields"
215
+ );
216
+ }
217
+ byKid.add(key.kid);
218
+ }
219
+ const verifier = (0, import_jose.createLocalJWKSet)({ keys: jwks.keys });
220
+ this.jwksCache = { raw: jwks.keys, byKid, verifier, fetchedAt: Date.now() };
221
+ } finally {
222
+ this.inFlightRefresh = null;
223
+ }
224
+ })();
225
+ return this.inFlightRefresh;
226
+ }
227
+ /** @internal Exposed for testing — clears JWKS cache */
228
+ clearCache() {
229
+ this.jwksCache = null;
230
+ }
231
+ };
232
+
233
+ // src/publishableKey.ts
234
+ function b64urlDecode(input) {
235
+ const pad = input.length % 4 === 0 ? "" : "=".repeat(4 - input.length % 4);
236
+ const normalized = input.replace(/-/g, "+").replace(/_/g, "/") + pad;
237
+ if (typeof atob === "function") {
238
+ const bin = atob(normalized);
239
+ const bytes = new Uint8Array(bin.length);
240
+ for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);
241
+ return new TextDecoder().decode(bytes);
242
+ }
243
+ const { Buffer: Buffer2 } = require("buffer");
244
+ return Buffer2.from(normalized, "base64").toString("utf8");
245
+ }
246
+ function isValidIssuerUrl(iss) {
247
+ if (typeof iss !== "string" || iss.length === 0) return false;
248
+ if (!iss.startsWith("http://") && !iss.startsWith("https://")) return false;
249
+ try {
250
+ const u = new URL(iss);
251
+ if (u.protocol !== "http:" && u.protocol !== "https:") return false;
252
+ if (!u.hostname) return false;
253
+ return true;
254
+ } catch {
255
+ return false;
256
+ }
257
+ }
258
+ function assertPublishableKey(raw, opts) {
259
+ const ctx = opts?.context ? `${opts.context}: ` : "";
260
+ if (typeof raw !== "string" || raw.length === 0) {
261
+ throw new IQAuthError(
262
+ "CONFIG_INVALID",
263
+ `${ctx}IQAuth publishable key is missing. Set IQAUTH_PUBLISHABLE_KEY (or pass publishableKey) to a pk_test_\u2026 or pk_live_\u2026 value from the IQAuth admin console.`
264
+ );
265
+ }
266
+ const shapeMatch = raw.match(/^pk_(test|live)_([A-Za-z0-9_-]+)$/);
267
+ if (!shapeMatch) {
268
+ throw new IQAuthError(
269
+ "CONFIG_INVALID",
270
+ `${ctx}IQAuth publishable key is malformed (got ${raw.slice(0, 12)}\u2026). Expected pk_test_\u2026 or pk_live_\u2026; regenerate the key from the IQAuth admin console.`
271
+ );
272
+ }
273
+ let decoded;
274
+ try {
275
+ decoded = JSON.parse(b64urlDecode(shapeMatch[2]));
276
+ } catch {
277
+ throw new IQAuthError(
278
+ "CONFIG_INVALID",
279
+ `${ctx}IQAuth publishable key payload is not valid base64url JSON. Regenerate the key from the IQAuth admin console.`
280
+ );
281
+ }
282
+ if (!isPublishableKeyPayload(decoded)) {
283
+ throw new IQAuthError(
284
+ "CONFIG_INVALID",
285
+ `${ctx}IQAuth publishable key payload is missing required fields {iss, appId, tenantId, kid}. Regenerate the key from the IQAuth admin console.`
286
+ );
287
+ }
288
+ if (!isValidIssuerUrl(decoded.iss)) {
289
+ throw new IQAuthError(
290
+ "CONFIG_INVALID",
291
+ `${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.`
292
+ );
293
+ }
294
+ return { mode: shapeMatch[1], iss: decoded.iss, appId: decoded.appId, tenantId: decoded.tenantId, kid: decoded.kid, raw };
295
+ }
296
+ function isPublishableKeyPayload(value) {
297
+ if (!value || typeof value !== "object") return false;
298
+ const v = value;
299
+ return typeof v.iss === "string" && typeof v.appId === "string" && typeof v.tenantId === "string" && typeof v.kid === "string";
300
+ }
301
+
302
+ // src/ws.ts
303
+ var DEFAULT_COOKIE = "iqauth_at";
304
+ var DEFAULT_SUBPROTOCOL_PREFIX = "iqauth.bearer.";
305
+ var JWT_SHAPE = /^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/;
306
+ var tokensByIssuer = /* @__PURE__ */ new Map();
307
+ function getTokens(issuer) {
308
+ let mod = tokensByIssuer.get(issuer);
309
+ if (!mod) {
310
+ mod = new TokensModule(issuer);
311
+ tokensByIssuer.set(issuer, mod);
312
+ }
313
+ return mod;
314
+ }
315
+ function firstHeader(value) {
316
+ if (Array.isArray(value)) return value[0];
317
+ return value;
318
+ }
319
+ function readCookie(cookieHeader, name) {
320
+ if (!cookieHeader) return void 0;
321
+ const target = `${name}=`;
322
+ for (const seg of cookieHeader.split(";")) {
323
+ const t = seg.trim();
324
+ if (t.startsWith(target)) {
325
+ try {
326
+ return decodeURIComponent(t.slice(target.length));
327
+ } catch {
328
+ return t.slice(target.length);
329
+ }
330
+ }
331
+ }
332
+ return void 0;
333
+ }
334
+ function extractToken(req, cookieName, subprotocolPrefix) {
335
+ let authHeader;
336
+ let cookieHeader;
337
+ let subprotoHeader;
338
+ if ("headers" in req && req.headers && typeof req.headers === "object") {
339
+ authHeader = firstHeader(req.headers.authorization);
340
+ cookieHeader = firstHeader(req.headers.cookie);
341
+ subprotoHeader = firstHeader(req.headers["sec-websocket-protocol"]);
342
+ } else {
343
+ const r = req;
344
+ authHeader = r.authorization;
345
+ cookieHeader = r.cookie;
346
+ subprotoHeader = r.secWebSocketProtocol;
347
+ }
348
+ if (authHeader && /^Bearer /i.test(authHeader)) {
349
+ return authHeader.slice(7).trim();
350
+ }
351
+ if (cookieName && cookieHeader) {
352
+ const fromCookie = readCookie(cookieHeader, cookieName);
353
+ if (fromCookie) return fromCookie;
354
+ }
355
+ if (subprotocolPrefix !== null && subprotoHeader) {
356
+ const protos = subprotoHeader.split(",").map((s) => s.trim()).filter(Boolean);
357
+ for (const proto of protos) {
358
+ if (subprotocolPrefix && proto.startsWith(subprotocolPrefix)) {
359
+ return proto.slice(subprotocolPrefix.length);
360
+ }
361
+ if (JWT_SHAPE.test(proto)) return proto;
362
+ }
363
+ }
364
+ return void 0;
365
+ }
366
+ async function verifyWsUpgrade(req, options) {
367
+ const parsed = assertPublishableKey(options.publishableKey, {
368
+ context: "@iqauth/sdk/ws"
369
+ });
370
+ const issuer = (options.issuer && typeof options.issuer === "string" ? options.issuer : parsed.iss.startsWith("http") ? parsed.iss : `https://${parsed.iss}`).replace(/\/+$/, "");
371
+ const cookieName = options.cookieName === void 0 ? DEFAULT_COOKIE : options.cookieName;
372
+ const subprotocolPrefix = options.subprotocolPrefix === void 0 ? DEFAULT_SUBPROTOCOL_PREFIX : options.subprotocolPrefix;
373
+ const token = extractToken(req, cookieName, subprotocolPrefix);
374
+ if (!token) return null;
375
+ const tokens = getTokens(issuer);
376
+ try {
377
+ const verifyOpts = {};
378
+ if (options.audience !== void 0) verifyOpts.audience = options.audience;
379
+ verifyOpts.issuer = options.issuer ?? issuer;
380
+ if (options.clockTolerance !== void 0)
381
+ verifyOpts.clockTolerance = options.clockTolerance;
382
+ if (options.algorithms !== void 0) verifyOpts.algorithms = options.algorithms;
383
+ const claims = await tokens.verify(token, verifyOpts);
384
+ return { claims };
385
+ } catch (err) {
386
+ if (err instanceof IQAuthError) return null;
387
+ return null;
388
+ }
389
+ }
390
+ function _resetWsVerifierCache() {
391
+ tokensByIssuer.clear();
392
+ }
393
+ // Annotate the CommonJS export names for ESM import in node:
394
+ 0 && (module.exports = {
395
+ _resetWsVerifierCache,
396
+ verifyWsUpgrade
397
+ });
package/dist/ws.mjs ADDED
@@ -0,0 +1,12 @@
1
+ import {
2
+ _resetWsVerifierCache,
3
+ verifyWsUpgrade
4
+ } from "./chunk-3JULWS6F.mjs";
5
+ import "./chunk-WQWBJSSS.mjs";
6
+ import "./chunk-UNYDG2L4.mjs";
7
+ import "./chunk-6I6RM4MN.mjs";
8
+ import "./chunk-Y6FXYEAI.mjs";
9
+ export {
10
+ _resetWsVerifierCache,
11
+ verifyWsUpgrade
12
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iqauth/sdk",
3
- "version": "2.3.0",
3
+ "version": "2.6.0",
4
4
  "description": "TypeScript SDK for IQAuth — the canonical way for all IQ projects to integrate with IQAuthService",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -68,6 +68,26 @@
68
68
  "types": "./dist/service.d.ts",
69
69
  "import": "./dist/service.mjs",
70
70
  "require": "./dist/service.js"
71
+ },
72
+ "./ws": {
73
+ "types": "./dist/ws.d.ts",
74
+ "import": "./dist/ws.mjs",
75
+ "require": "./dist/ws.js"
76
+ },
77
+ "./test": {
78
+ "types": "./dist/test.d.ts",
79
+ "import": "./dist/test.mjs",
80
+ "require": "./dist/test.js"
81
+ },
82
+ "./webhooks": {
83
+ "types": "./dist/webhooks.d.ts",
84
+ "import": "./dist/webhooks.mjs",
85
+ "require": "./dist/webhooks.js"
86
+ },
87
+ "./locales": {
88
+ "types": "./dist/locales.d.ts",
89
+ "import": "./dist/locales.mjs",
90
+ "require": "./dist/locales.js"
71
91
  }
72
92
  },
73
93
  "files": [
@@ -76,7 +96,7 @@
76
96
  "docs"
77
97
  ],
78
98
  "scripts": {
79
- "build": "tsup src/index.ts src/browser-session.ts src/browser.ts src/react.ts src/server.ts src/server/handlers.ts src/express.ts src/fastify.ts src/hono.ts src/next.ts src/mobile.ts src/service.ts src/cli/index.ts --format cjs,esm --dts --clean --external react --external react-dom --external next/headers",
99
+ "build": "tsup src/index.ts src/browser-session.ts src/browser.ts src/react.ts src/server.ts src/server/handlers.ts src/express.ts src/fastify.ts src/hono.ts src/next.ts src/mobile.ts src/service.ts src/ws.ts src/test.ts src/webhooks.ts src/locales.ts src/cli/index.ts --format cjs,esm --dts --clean --external react --external react-dom --external next/headers",
80
100
  "test": "vitest run",
81
101
  "test:watch": "vitest",
82
102
  "test:coverage": "vitest run --coverage",
@@ -1,90 +0,0 @@
1
- import {
2
- loadEnv,
3
- parseFlags,
4
- symbol
5
- } from "./chunk-X3K3WOBR.mjs";
6
- import {
7
- parsePublishableKey
8
- } from "./chunk-WQWBJSSS.mjs";
9
- import "./chunk-6I6RM4MN.mjs";
10
- import "./chunk-Y6FXYEAI.mjs";
11
-
12
- // src/cli/doctor.ts
13
- async function runDoctor(argv) {
14
- const { flags } = parseFlags(argv);
15
- const envFile = flags.get("env-file") || ".env";
16
- const env = await loadEnv(envFile);
17
- const probes = [];
18
- const pkRaw = env.IQAUTH_PUBLISHABLE_KEY;
19
- const issuerEnv = env.IQAUTH_ISSUER;
20
- const redirect = env.IQAUTH_REDIRECT_URI;
21
- probes.push({
22
- name: ".env present",
23
- ok: !!pkRaw,
24
- detail: pkRaw ? `${envFile} loaded; IQAUTH_PUBLISHABLE_KEY=${pkRaw.slice(0, 10)}\u2026` : `IQAUTH_PUBLISHABLE_KEY missing in ${envFile}`
25
- });
26
- const parsed = pkRaw ? parsePublishableKey(pkRaw) : null;
27
- probes.push({
28
- name: "publishable key parses",
29
- ok: !!parsed,
30
- detail: parsed ? `mode=${parsed.mode} appId=${parsed.appId} tenantId=${parsed.tenantId} kid=${parsed.kid}` : "key did not match pk_<test|live>_<base64> format"
31
- });
32
- const issuer = (issuerEnv || (parsed?.iss.startsWith("http") ? parsed.iss : parsed ? `https://${parsed.iss}` : "")).replace(/\/+$/, "");
33
- if (issuer) {
34
- try {
35
- const res = await fetch(`${issuer}/.well-known/openid-configuration`);
36
- probes.push({
37
- name: "issuer reachable",
38
- ok: res.ok,
39
- detail: `${issuer}/.well-known/openid-configuration \u2192 ${res.status}`
40
- });
41
- } catch (err) {
42
- probes.push({
43
- name: "issuer reachable",
44
- ok: false,
45
- detail: `fetch failed: ${err.message}`
46
- });
47
- }
48
- } else {
49
- probes.push({ name: "issuer reachable", ok: false, detail: "issuer URL unknown (no IQAUTH_ISSUER and no key)" });
50
- }
51
- if (issuer) {
52
- try {
53
- const res = await fetch(`${issuer}/.well-known/jwks.json`);
54
- const json = await res.json().catch(() => ({}));
55
- const keys = json.keys;
56
- probes.push({
57
- name: "JWKS reachable",
58
- ok: res.ok && Array.isArray(keys) && keys.length > 0,
59
- detail: `${issuer}/.well-known/jwks.json \u2192 ${res.status} (${Array.isArray(keys) ? keys.length : 0} keys)`
60
- });
61
- } catch (err) {
62
- probes.push({ name: "JWKS reachable", ok: false, detail: `fetch failed: ${err.message}` });
63
- }
64
- }
65
- if (redirect) {
66
- try {
67
- const res = await fetch(redirect, { method: "GET" });
68
- probes.push({
69
- name: "redirect URI reachable",
70
- ok: res.status > 0 && res.status < 500,
71
- detail: `${redirect} \u2192 ${res.status}`
72
- });
73
- } catch (err) {
74
- probes.push({ name: "redirect URI reachable", ok: false, detail: `fetch failed: ${err.message}` });
75
- }
76
- } else {
77
- probes.push({ name: "redirect URI reachable", ok: false, detail: "IQAUTH_REDIRECT_URI not set" });
78
- }
79
- let allOk = true;
80
- for (const p of probes) {
81
- console.log(`${symbol(p.ok)} ${p.name.padEnd(28)} ${p.detail}`);
82
- if (!p.ok) allOk = false;
83
- }
84
- console.log("");
85
- console.log(allOk ? "\u2705 All checks passed." : "\u274C One or more checks failed \u2014 see above.");
86
- process.exit(allOk ? 0 : 1);
87
- }
88
- export {
89
- runDoctor
90
- };