@iqauth/sdk 2.6.4 → 2.8.1

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 (117) hide show
  1. package/README.md +173 -1
  2. package/dist/browser-session.d.mts +4 -4
  3. package/dist/browser-session.d.ts +4 -4
  4. package/dist/browser-session.js +212 -46
  5. package/dist/browser-session.mjs +3 -3
  6. package/dist/browser.d.mts +5 -5
  7. package/dist/browser.d.ts +5 -5
  8. package/dist/browser.js +293 -34
  9. package/dist/browser.mjs +5 -5
  10. package/dist/{chunk-BVV54LPI.mjs → chunk-25SSYDIP.mjs} +10 -4
  11. package/dist/{chunk-XAWYUPMO.mjs → chunk-4V7FKOTG.mjs} +242 -22
  12. package/dist/{chunk-6I6RM4MN.mjs → chunk-6PJRLRB4.mjs} +33 -3
  13. package/dist/{chunk-SL3KRS4W.mjs → chunk-CIJORODR.mjs} +23 -1
  14. package/dist/{chunk-LIZYFXH7.mjs → chunk-DFWHSDYQ.mjs} +1 -1
  15. package/dist/chunk-GLXSIGVS.mjs +66 -0
  16. package/dist/{chunk-DJIBN2N7.mjs → chunk-GN37E64I.mjs} +29 -7
  17. package/dist/{chunk-WQWBJSSS.mjs → chunk-HVHNYPDC.mjs} +6 -6
  18. package/dist/chunk-JRDVUWAL.mjs +46 -0
  19. package/dist/{chunk-UNYDG2L4.mjs → chunk-NUO2I65G.mjs} +56 -23
  20. package/dist/{chunk-5T7GHBX6.mjs → chunk-TLET552H.mjs} +36 -0
  21. package/dist/chunk-VYQ3ETCK.mjs +244 -0
  22. package/dist/{chunk-3JULWS6F.mjs → chunk-WCELYTJ3.mjs} +3 -3
  23. package/dist/chunk-WHT6WKTY.mjs +3180 -0
  24. package/dist/{chunk-MKKZULZR.mjs → chunk-WIFG74IK.mjs} +1 -1
  25. package/dist/chunk-WSH4SW7F.mjs +490 -0
  26. package/dist/{chunk-W3F4JYGP.mjs → chunk-ZLJPABB7.mjs} +139 -23
  27. package/dist/cli/index.js +2 -2
  28. package/dist/cli/index.mjs +2 -2
  29. package/dist/{client-BNQe3AgF.d.ts → client-D8L-PaWr.d.mts} +59 -6
  30. package/dist/{client-kYlJFgPv.d.mts → client-DkPL0EPZ.d.ts} +59 -6
  31. package/dist/{doctor-YYNHNMLD.mjs → doctor-JAFXWU3X.mjs} +2 -2
  32. package/dist/errors-Jl1Jtm-6.d.mts +107 -0
  33. package/dist/errors-Jl1Jtm-6.d.ts +107 -0
  34. package/dist/{express-CHpfa7D_.d.ts → express-Budysq4h.d.ts} +2 -2
  35. package/dist/{express-B6_1vBYZ.d.mts → express-DDTA3qV1.d.mts} +2 -2
  36. package/dist/express.d.mts +7 -6
  37. package/dist/express.d.ts +7 -6
  38. package/dist/express.js +563 -85
  39. package/dist/express.mjs +73 -34
  40. package/dist/fastify.d.mts +10 -0
  41. package/dist/fastify.d.ts +10 -0
  42. package/dist/fastify.js +589 -65
  43. package/dist/fastify.mjs +101 -11
  44. package/dist/hono.d.mts +10 -0
  45. package/dist/hono.d.ts +10 -0
  46. package/dist/hono.js +566 -65
  47. package/dist/hono.mjs +78 -11
  48. package/dist/index-Cko-d5po.d.mts +1848 -0
  49. package/dist/index-RNqwEcmY.d.ts +1848 -0
  50. package/dist/index.d.mts +56 -8
  51. package/dist/index.d.ts +56 -8
  52. package/dist/index.js +694 -75
  53. package/dist/index.mjs +30 -10
  54. package/dist/{keys-NLWFAOEM.mjs → keys-6Y776TG2.mjs} +2 -2
  55. package/dist/locales.d.mts +1 -1
  56. package/dist/locales.d.ts +1 -1
  57. package/dist/locales.js +36 -0
  58. package/dist/locales.mjs +1 -1
  59. package/dist/mobile.d.mts +77 -7
  60. package/dist/mobile.d.ts +77 -7
  61. package/dist/mobile.js +307 -46
  62. package/dist/mobile.mjs +98 -3
  63. package/dist/next.d.mts +10 -1
  64. package/dist/next.d.ts +10 -1
  65. package/dist/next.js +596 -205
  66. package/dist/next.mjs +83 -10
  67. package/dist/{provisioningBridge-88xjOS2n.d.mts → provisioningBridge-BXPMZCLe.d.ts} +30 -2
  68. package/dist/{provisioningBridge-DnTfzdZK.d.ts → provisioningBridge-IEycmsgb.d.mts} +30 -2
  69. package/dist/{publishableKey-BaR0HoAH.d.ts → publishableKey-f2kq-rKw.d.mts} +1 -1
  70. package/dist/{publishableKey-BaR0HoAH.d.mts → publishableKey-f2kq-rKw.d.ts} +1 -1
  71. package/dist/react-permissions.d.mts +52 -0
  72. package/dist/react-permissions.d.ts +52 -0
  73. package/dist/react-permissions.js +239 -0
  74. package/dist/react-permissions.mjs +98 -0
  75. package/dist/react.d.mts +9 -1624
  76. package/dist/react.d.ts +9 -1624
  77. package/dist/react.js +882 -73
  78. package/dist/react.mjs +71 -2631
  79. package/dist/{reverify-4UEJXUS6.mjs → reverify-C64QXKJO.mjs} +2 -2
  80. package/dist/server/handlers.d.mts +200 -4
  81. package/dist/server/handlers.d.ts +200 -4
  82. package/dist/server/handlers.js +530 -16
  83. package/dist/server/handlers.mjs +14 -3
  84. package/dist/server.d.mts +171 -8
  85. package/dist/server.d.ts +171 -8
  86. package/dist/server.js +579 -61
  87. package/dist/server.mjs +99 -12
  88. package/dist/service.d.mts +4 -4
  89. package/dist/service.d.ts +4 -4
  90. package/dist/service.js +212 -46
  91. package/dist/service.mjs +3 -3
  92. package/dist/{signIn-CiIBTJIh.d.mts → signIn-CReqfXsh.d.mts} +95 -3
  93. package/dist/{signIn-OCr88Zf8.d.ts → signIn-Cfa1GTpO.d.ts} +95 -3
  94. package/dist/{signIn-4OKLDEIH.mjs → signIn-SHBW6Z4T.mjs} +1 -1
  95. package/dist/test.mjs +3 -3
  96. package/dist/{tokens-DCyzzn8L.d.mts → tokens-9F6ETrzk.d.ts} +9 -2
  97. package/dist/{tokens-aHiGFr_E.d.ts → tokens-B06VtvUi.d.mts} +9 -2
  98. package/dist/{types-DZAflmmq.d.mts → types-Bn8O-OEd.d.mts} +164 -11
  99. package/dist/{types-DZAflmmq.d.ts → types-Bn8O-OEd.d.ts} +164 -11
  100. package/dist/{types-6bNdxesb.d.ts → types-DnU2LhXR.d.mts} +7 -1
  101. package/dist/{types-6bNdxesb.d.mts → types-DnU2LhXR.d.ts} +7 -1
  102. package/dist/webhooks.d.mts +113 -17
  103. package/dist/webhooks.d.ts +113 -17
  104. package/dist/webhooks.js +179 -15
  105. package/dist/webhooks.mjs +7 -1
  106. package/dist/ws.d.mts +2 -2
  107. package/dist/ws.d.ts +2 -2
  108. package/dist/ws.js +80 -30
  109. package/dist/ws.mjs +4 -4
  110. package/docs/error-handling.md +101 -0
  111. package/docs/guides/effective-permissions.md +171 -0
  112. package/docs/guides/invitations.md +65 -0
  113. package/package.json +19 -4
  114. package/dist/chunk-6TDJJER7.mjs +0 -217
  115. package/dist/chunk-UKZLOHZG.mjs +0 -83
  116. package/dist/errors-CDdl24MP.d.mts +0 -52
  117. package/dist/errors-CDdl24MP.d.ts +0 -52
package/dist/fastify.mjs CHANGED
@@ -1,29 +1,37 @@
1
+ import {
2
+ sanitizeReturnTo
3
+ } from "./chunk-JRDVUWAL.mjs";
1
4
  import {
2
5
  handleCallback,
3
6
  handleRefresh,
4
7
  handleSignout,
8
+ handleUserinfo,
5
9
  serializeCookie
6
- } from "./chunk-6TDJJER7.mjs";
10
+ } from "./chunk-WSH4SW7F.mjs";
7
11
  import {
8
12
  assertPublishableKey
9
- } from "./chunk-WQWBJSSS.mjs";
13
+ } from "./chunk-HVHNYPDC.mjs";
10
14
  import {
11
15
  IQAuthClient
12
- } from "./chunk-W3F4JYGP.mjs";
13
- import "./chunk-UNYDG2L4.mjs";
16
+ } from "./chunk-ZLJPABB7.mjs";
17
+ import "./chunk-NUO2I65G.mjs";
14
18
  import {
15
19
  IQAuthError
16
- } from "./chunk-6I6RM4MN.mjs";
20
+ } from "./chunk-6PJRLRB4.mjs";
17
21
  import "./chunk-Y6FXYEAI.mjs";
18
22
 
19
23
  // src/fastify.ts
24
+ var PKCE_COOKIE = "iqauth_pkce";
20
25
  var KNOWN_AUTH_ERRORS = /* @__PURE__ */ new Set([
21
26
  "TOKEN_INVALID",
22
27
  "TOKEN_EXPIRED",
23
28
  "TOKEN_REVOKED",
24
29
  "SESSION_EXPIRED",
25
30
  "SESSION_INVALID",
26
- "AUTH_REQUIRED"
31
+ "AUTH_REQUIRED",
32
+ // Task #127 — typed `IQAuthErrorCode` taxonomy.
33
+ "token_invalid",
34
+ "token_expired"
27
35
  ]);
28
36
  function applyResponse(reply, hr) {
29
37
  for (const c of hr.cookies) {
@@ -35,6 +43,54 @@ function applyResponse(reply, hr) {
35
43
  }
36
44
  reply.code(hr.status).send(hr.body);
37
45
  }
46
+ function applyCallbackResponse(reply, hr, requestOrigin, returnToCookieValue, returnToCookieName) {
47
+ const returnTo = sanitizeReturnTo(
48
+ returnToCookieValue || hr.body?.returnTo,
49
+ { currentOrigin: requestOrigin, fallback: "/" }
50
+ );
51
+ for (const c of hr.cookies) {
52
+ const cookie = serializeCookie(c);
53
+ const existing = reply.getHeader?.("set-cookie") ?? [];
54
+ const list = Array.isArray(existing) ? existing : [existing];
55
+ list.push(cookie);
56
+ reply.header("set-cookie", list);
57
+ }
58
+ if (hr.status < 400) {
59
+ const existing = reply.getHeader?.("set-cookie") ?? [];
60
+ const list = Array.isArray(existing) ? existing : [existing];
61
+ list.push(`${returnToCookieName}=; Path=/; Max-Age=0; SameSite=Lax`);
62
+ reply.header("set-cookie", list);
63
+ }
64
+ reply.code(hr.status).send({ ...hr.body, returnTo });
65
+ }
66
+ function applyCallbackRedirect(reply, hr, requestOrigin, returnToCookieValue, cookieNames) {
67
+ const pushCookie = (value) => {
68
+ const existing = reply.getHeader?.("set-cookie") ?? [];
69
+ const list = Array.isArray(existing) ? existing : [existing];
70
+ list.push(value);
71
+ reply.header("set-cookie", list);
72
+ };
73
+ for (const c of hr.cookies) pushCookie(serializeCookie(c));
74
+ pushCookie(`${cookieNames.state}=; Path=/; Max-Age=0; SameSite=Lax`);
75
+ pushCookie(`${cookieNames.pkce}=; Path=/; Max-Age=0; SameSite=Lax`);
76
+ if (hr.status >= 400) {
77
+ reply.header("location", "/");
78
+ reply.code(302).send();
79
+ return;
80
+ }
81
+ const dest = sanitizeReturnTo(returnToCookieValue, {
82
+ currentOrigin: requestOrigin,
83
+ fallback: "/"
84
+ });
85
+ pushCookie(`${cookieNames.returnTo}=; Path=/; Max-Age=0; SameSite=Lax`);
86
+ reply.header("location", dest);
87
+ reply.code(302).send();
88
+ }
89
+ function requestOriginOf(req) {
90
+ const proto = req.headers?.["x-forwarded-proto"]?.split(",")[0]?.trim() || (typeof req.protocol === "string" ? req.protocol : void 0) || "https";
91
+ const host = req.headers?.["x-forwarded-host"]?.split(",")[0]?.trim() || req.headers?.host || "";
92
+ return host ? `${proto}://${host}` : "";
93
+ }
38
94
  function readCookie(req, name) {
39
95
  if (req.cookies && typeof req.cookies[name] === "string") return req.cookies[name];
40
96
  const raw = req.headers?.cookie;
@@ -68,10 +124,12 @@ async function iqAuth(fastify, options) {
68
124
  } : void 0;
69
125
  const accessCookie = options.accessCookieName ?? "iqauth_at";
70
126
  const refreshCookie = options.refreshCookieName ?? "iqauth_rt";
127
+ const returnToCookie = options.returnToCookieName ?? "iqauth_return_to";
71
128
  const mount = (options.mountPath ?? "/api/iqauth").replace(/\/+$/, "");
72
129
  const mountHelpers = options.mountHelperRoutes !== false;
73
130
  const isPublic = (p) => {
74
131
  if (mountHelpers && p.startsWith(mount + "/")) return true;
132
+ if (options.mountUserinfo && p === `${mount}/me`) return true;
75
133
  if (Array.isArray(options.publicPaths)) return options.publicPaths.includes(p);
76
134
  if (typeof options.publicPaths === "function") return options.publicPaths(p);
77
135
  return false;
@@ -101,22 +159,54 @@ async function iqAuth(fastify, options) {
101
159
  if (mountHelpers) {
102
160
  fastify.post(`${mount}/callback`, async (req, reply) => {
103
161
  const body = req.body || {};
104
- applyResponse(reply, await handleCallback(helperConfig, {
162
+ const hr = await handleCallback(helperConfig, {
105
163
  code: body.code,
106
164
  codeVerifier: body.codeVerifier,
107
- redirectUri: body.redirectUri
108
- }));
165
+ redirectUri: body.redirectUri,
166
+ // M-2: bind callback to this browser; handleCallback fails closed.
167
+ state: body.state,
168
+ expectedState: readCookie(req, helperConfig.stateCookieName ?? "iqauth_state")
169
+ });
170
+ applyCallbackResponse(reply, hr, requestOriginOf(req), readCookie(req, returnToCookie), returnToCookie);
171
+ });
172
+ fastify.get(`${mount}/callback`, async (req, reply) => {
173
+ const stateCookie = helperConfig.stateCookieName ?? "iqauth_state";
174
+ const q = req.query || {};
175
+ const origin = requestOriginOf(req);
176
+ const redirectUri = `${origin}${mount}/callback`;
177
+ const hr = await handleCallback(helperConfig, {
178
+ code: q.code,
179
+ codeVerifier: readCookie(req, PKCE_COOKIE),
180
+ redirectUri,
181
+ state: q.state,
182
+ expectedState: readCookie(req, stateCookie)
183
+ });
184
+ applyCallbackRedirect(reply, hr, origin, readCookie(req, returnToCookie), {
185
+ returnTo: returnToCookie,
186
+ state: stateCookie,
187
+ pkce: PKCE_COOKIE
188
+ });
109
189
  });
110
190
  fastify.post(`${mount}/refresh`, async (req, reply) => {
111
191
  const body = req.body || {};
112
192
  const refreshToken = body.refreshToken || readCookie(req, refreshCookie);
113
- applyResponse(reply, await handleRefresh(helperConfig, { refreshToken }));
193
+ const idempotencyToken = req.headers?.["x-iqauth-idempotency"] || body.idempotencyToken;
194
+ applyResponse(reply, await handleRefresh(helperConfig, { refreshToken, idempotencyToken }));
114
195
  });
115
196
  fastify.post(`${mount}/signout`, async (req, reply) => {
116
197
  const auth = req.headers?.authorization;
117
198
  const accessToken = (typeof auth === "string" ? auth.replace(/^Bearer /i, "") : void 0) || readCookie(req, accessCookie);
199
+ const refreshToken = readCookie(req, refreshCookie);
118
200
  const ssoCookieHeader = typeof req.headers?.cookie === "string" ? req.headers.cookie : void 0;
119
- applyResponse(reply, await handleSignout(helperConfig, { accessToken, ssoCookieHeader }));
201
+ const idempotencyToken = req.headers?.["x-iqauth-idempotency"];
202
+ applyResponse(reply, await handleSignout(helperConfig, { accessToken, refreshToken, idempotencyToken, ssoCookieHeader }));
203
+ });
204
+ }
205
+ if (options.mountUserinfo) {
206
+ fastify.get(`${mount}/me`, async (req, reply) => {
207
+ const auth = req.headers?.authorization;
208
+ const accessToken = (typeof auth === "string" ? auth.replace(/^Bearer /i, "") : void 0) || readCookie(req, accessCookie);
209
+ applyResponse(reply, await handleUserinfo(helperConfig, { accessToken, req }));
120
210
  });
121
211
  }
122
212
  fastify.decorate("iqauth", { client, issuer });
package/dist/hono.d.mts CHANGED
@@ -1,4 +1,6 @@
1
1
  import { IQAuthHelperConfig } from './server/handlers.mjs';
2
+ import './tokens-B06VtvUi.mjs';
3
+ import './types-Bn8O-OEd.mjs';
2
4
 
3
5
  /**
4
6
  * @iqauth/sdk/hono — Hono adapter.
@@ -16,6 +18,14 @@ interface IQAuthHonoOptions extends IQAuthHelperConfig {
16
18
  mountPath?: string;
17
19
  mountHelperRoutes?: boolean;
18
20
  publicPaths?: string[] | ((path: string) => boolean);
21
+ /**
22
+ * Cookie name the browser SDK publishes the post-login destination into
23
+ * before redirect. The callback handler reads it, surfaces it as `returnTo`
24
+ * in the JSON response body after a successful exchange, and clears it on
25
+ * success. Mirrors the express inline-callback adapter. Defaults to
26
+ * `iqauth_return_to`.
27
+ */
28
+ returnToCookieName?: string;
19
29
  }
20
30
  declare function iqAuth(options: IQAuthHonoOptions): (c: any, next: () => Promise<void>) => Promise<any>;
21
31
 
package/dist/hono.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  import { IQAuthHelperConfig } from './server/handlers.js';
2
+ import './tokens-9F6ETrzk.js';
3
+ import './types-Bn8O-OEd.js';
2
4
 
3
5
  /**
4
6
  * @iqauth/sdk/hono — Hono adapter.
@@ -16,6 +18,14 @@ interface IQAuthHonoOptions extends IQAuthHelperConfig {
16
18
  mountPath?: string;
17
19
  mountHelperRoutes?: boolean;
18
20
  publicPaths?: string[] | ((path: string) => boolean);
21
+ /**
22
+ * Cookie name the browser SDK publishes the post-login destination into
23
+ * before redirect. The callback handler reads it, surfaces it as `returnTo`
24
+ * in the JSON response body after a successful exchange, and clears it on
25
+ * success. Mirrors the express inline-callback adapter. Defaults to
26
+ * `iqauth_return_to`.
27
+ */
28
+ returnToCookieName?: string;
19
29
  }
20
30
  declare function iqAuth(options: IQAuthHonoOptions): (c: any, next: () => Promise<void>) => Promise<any>;
21
31