@iqauth/sdk 2.0.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 (112) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +287 -0
  3. package/dist/browser-session.d.mts +12 -0
  4. package/dist/browser-session.d.ts +12 -0
  5. package/dist/browser-session.js +1812 -0
  6. package/dist/browser-session.mjs +28 -0
  7. package/dist/browser.d.mts +46 -0
  8. package/dist/browser.d.ts +46 -0
  9. package/dist/browser.js +768 -0
  10. package/dist/browser.mjs +47 -0
  11. package/dist/chunk-5HF3OBNO.mjs +189 -0
  12. package/dist/chunk-5WFR6Y33.mjs +59 -0
  13. package/dist/chunk-6I6RM4MN.mjs +51 -0
  14. package/dist/chunk-73R6BEGO.mjs +176 -0
  15. package/dist/chunk-E46DKOVI.mjs +632 -0
  16. package/dist/chunk-JQWYIIIS.mjs +1740 -0
  17. package/dist/chunk-X3K3WOBR.mjs +64 -0
  18. package/dist/chunk-Y6FXYEAI.mjs +10 -0
  19. package/dist/cli/index.d.mts +1 -0
  20. package/dist/cli/index.d.ts +1 -0
  21. package/dist/cli/index.js +581 -0
  22. package/dist/cli/index.mjs +57 -0
  23. package/dist/client-C1DXfB8Z.d.mts +911 -0
  24. package/dist/client-CggvJmmm.d.ts +911 -0
  25. package/dist/dev-FUTJZSWN.mjs +56 -0
  26. package/dist/doctor-OHJRZBBT.mjs +89 -0
  27. package/dist/errors-CDdl24MP.d.mts +52 -0
  28. package/dist/errors-CDdl24MP.d.ts +52 -0
  29. package/dist/express-BKAXB5Nl.d.ts +61 -0
  30. package/dist/express-CpfyYTmw.d.mts +61 -0
  31. package/dist/express.d.mts +45 -0
  32. package/dist/express.d.ts +45 -0
  33. package/dist/express.js +2252 -0
  34. package/dist/express.mjs +122 -0
  35. package/dist/fastify.d.mts +23 -0
  36. package/dist/fastify.d.ts +23 -0
  37. package/dist/fastify.js +2062 -0
  38. package/dist/fastify.mjs +118 -0
  39. package/dist/hono.d.mts +22 -0
  40. package/dist/hono.d.ts +22 -0
  41. package/dist/hono.js +2051 -0
  42. package/dist/hono.mjs +107 -0
  43. package/dist/index.d.mts +6 -0
  44. package/dist/index.d.ts +6 -0
  45. package/dist/index.js +2070 -0
  46. package/dist/index.mjs +83 -0
  47. package/dist/init-LLCSQGNL.mjs +198 -0
  48. package/dist/keys-NLWFAOEM.mjs +63 -0
  49. package/dist/mobile.d.mts +11 -0
  50. package/dist/mobile.d.ts +11 -0
  51. package/dist/mobile.js +1809 -0
  52. package/dist/mobile.mjs +25 -0
  53. package/dist/next.d.mts +37 -0
  54. package/dist/next.d.ts +37 -0
  55. package/dist/next.js +2078 -0
  56. package/dist/next.mjs +130 -0
  57. package/dist/publishableKey-B5DIK81A.d.mts +24 -0
  58. package/dist/publishableKey-B5DIK81A.d.ts +24 -0
  59. package/dist/react.d.mts +196 -0
  60. package/dist/react.d.ts +196 -0
  61. package/dist/react.js +1457 -0
  62. package/dist/react.mjs +787 -0
  63. package/dist/server/handlers.d.mts +96 -0
  64. package/dist/server/handlers.d.ts +96 -0
  65. package/dist/server/handlers.js +243 -0
  66. package/dist/server/handlers.mjs +14 -0
  67. package/dist/server.d.mts +14 -0
  68. package/dist/server.d.ts +14 -0
  69. package/dist/server.js +2195 -0
  70. package/dist/server.mjs +47 -0
  71. package/dist/service.d.mts +11 -0
  72. package/dist/service.d.ts +11 -0
  73. package/dist/service.js +1809 -0
  74. package/dist/service.mjs +25 -0
  75. package/dist/signIn-C8f6qVjD.d.mts +238 -0
  76. package/dist/signIn-Cy2lbEXb.d.ts +238 -0
  77. package/dist/types-Cxl3bQHt.d.mts +900 -0
  78. package/dist/types-Cxl3bQHt.d.ts +900 -0
  79. package/docs/APP_INTEGRATION_MATRIX.md +59 -0
  80. package/docs/BROWSER_SESSION_MIGRATION.md +69 -0
  81. package/docs/FRESH_IMPLEMENTATION_GUIDE.md +188 -0
  82. package/docs/TARBALL_RELEASE_WORKFLOW.md +98 -0
  83. package/docs/V1_TO_V2_UPGRADE_GUIDE.md +318 -0
  84. package/docs/guides/api-keys.md +130 -0
  85. package/docs/guides/app-registration.md +149 -0
  86. package/docs/guides/auth-flows.md +168 -0
  87. package/docs/guides/branding.md +160 -0
  88. package/docs/guides/entitlements.md +115 -0
  89. package/docs/guides/entity-hierarchy.md +200 -0
  90. package/docs/guides/error-handling.md +251 -0
  91. package/docs/guides/gdpr-compliance.md +123 -0
  92. package/docs/guides/invitations.md +143 -0
  93. package/docs/guides/mfa-enrollment.md +170 -0
  94. package/docs/guides/middleware-reference.md +205 -0
  95. package/docs/guides/mobile-native.md +110 -0
  96. package/docs/guides/roles-and-permissions.md +220 -0
  97. package/docs/guides/scoped-authorization.md +247 -0
  98. package/docs/guides/server-platform-integration.md +52 -0
  99. package/docs/guides/service-automation-integration.md +36 -0
  100. package/docs/guides/session-management.md +97 -0
  101. package/docs/guides/tenant-management.md +216 -0
  102. package/docs/guides/token-verification.md +178 -0
  103. package/docs/guides/user-management.md +184 -0
  104. package/docs/guides/webhooks.md +136 -0
  105. package/docs/integration-prompts/README.md +20 -0
  106. package/docs/integration-prompts/first-party-browser-app.md +29 -0
  107. package/docs/integration-prompts/install-from-tarball.md +41 -0
  108. package/docs/integration-prompts/migrate-from-local-packages-source.md +57 -0
  109. package/docs/integration-prompts/native-mobile-app.md +24 -0
  110. package/docs/integration-prompts/server-platform-app.md +20 -0
  111. package/docs/integration-prompts/service-automation-app.md +20 -0
  112. package/package.json +115 -0
package/dist/index.mjs ADDED
@@ -0,0 +1,83 @@
1
+ import {
2
+ iqAuthMiddleware
3
+ } from "./chunk-73R6BEGO.mjs";
4
+ import {
5
+ encodePublishableKey,
6
+ isPublishableKey,
7
+ isSecretKey,
8
+ parsePublishableKey
9
+ } from "./chunk-5WFR6Y33.mjs";
10
+ import {
11
+ ApiKeysModule,
12
+ AppsModule,
13
+ AuthModule,
14
+ BrandingModule,
15
+ ClientsModule,
16
+ DEFAULT_CLOCK_TOLERANCE_SECONDS,
17
+ DEFAULT_TOKEN_AUDIENCE,
18
+ DEFAULT_TOKEN_ISSUER,
19
+ EntitlementsModule,
20
+ GdprModule,
21
+ HierarchyModule,
22
+ IQAuthClient,
23
+ InMemoryOidcStateStore,
24
+ InvitesModule,
25
+ MembershipsModule,
26
+ MfaModule,
27
+ OidcModule,
28
+ PermissionGroupsModule,
29
+ PermissionsModule,
30
+ PinModule,
31
+ RolesModule,
32
+ ScopeModule,
33
+ SessionsModule,
34
+ SourcesModule,
35
+ TenantsModule,
36
+ TokensModule,
37
+ UsersModule,
38
+ VendorsModule,
39
+ WebhooksModule
40
+ } from "./chunk-JQWYIIIS.mjs";
41
+ import {
42
+ ErrorCodes,
43
+ IQAuthError
44
+ } from "./chunk-6I6RM4MN.mjs";
45
+ import "./chunk-Y6FXYEAI.mjs";
46
+ export {
47
+ ApiKeysModule,
48
+ AppsModule,
49
+ AuthModule,
50
+ BrandingModule,
51
+ ClientsModule,
52
+ DEFAULT_CLOCK_TOLERANCE_SECONDS,
53
+ DEFAULT_TOKEN_AUDIENCE,
54
+ DEFAULT_TOKEN_ISSUER,
55
+ EntitlementsModule,
56
+ ErrorCodes,
57
+ GdprModule,
58
+ HierarchyModule,
59
+ IQAuthClient,
60
+ IQAuthError,
61
+ InMemoryOidcStateStore,
62
+ InvitesModule,
63
+ MembershipsModule,
64
+ MfaModule,
65
+ OidcModule,
66
+ PermissionGroupsModule,
67
+ PermissionsModule,
68
+ PinModule,
69
+ RolesModule,
70
+ ScopeModule,
71
+ SessionsModule,
72
+ SourcesModule,
73
+ TenantsModule,
74
+ TokensModule,
75
+ UsersModule,
76
+ VendorsModule,
77
+ WebhooksModule,
78
+ encodePublishableKey,
79
+ iqAuthMiddleware,
80
+ isPublishableKey,
81
+ isSecretKey,
82
+ parsePublishableKey
83
+ };
@@ -0,0 +1,198 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/cli/init.ts
4
+ import { readFile, writeFile, access } from "fs/promises";
5
+ import { createInterface } from "readline";
6
+ function parseArgs(argv) {
7
+ const get = (key, def) => {
8
+ const idx = argv.indexOf(`--${key}`);
9
+ if (idx >= 0 && argv[idx + 1] && !argv[idx + 1].startsWith("--")) return argv[idx + 1];
10
+ return def;
11
+ };
12
+ const has = (key) => argv.includes(`--${key}`);
13
+ const baseUrl = get("base-url") || process.env.IQAUTH_BASE_URL;
14
+ const email = get("email");
15
+ const password = get("password");
16
+ const appName = get("app");
17
+ const redirect = get("redirect");
18
+ const origin = get("origin");
19
+ if (!baseUrl || !email || !password || !appName || !redirect || !origin) {
20
+ console.error("Usage: iqauth init --base-url URL --email EMAIL --password PW --app NAME --redirect URL --origin URL [--org NAME] [--mode test|live] [--env-file .env] [--rotate] [--yes]");
21
+ process.exit(1);
22
+ }
23
+ return {
24
+ baseUrl: baseUrl.replace(/\/$/, ""),
25
+ email,
26
+ password,
27
+ org: get("org"),
28
+ appName,
29
+ redirect,
30
+ origin,
31
+ mode: get("mode", "test") || "test",
32
+ envFile: get("env-file", ".env"),
33
+ rotate: has("rotate"),
34
+ yes: has("yes") || has("y")
35
+ };
36
+ }
37
+ async function http(url, init) {
38
+ const headers = { "Content-Type": "application/json", ...init.headers };
39
+ if (init.token) headers["Authorization"] = `Bearer ${init.token}`;
40
+ const res = await fetch(url, { ...init, headers });
41
+ const json = await res.json().catch(() => ({}));
42
+ if (!res.ok || json?.success === false) {
43
+ const code = json?.error?.code || res.status;
44
+ const msg = json?.error?.message || res.statusText;
45
+ throw new Error(`${url} \u2192 ${code}: ${msg}`);
46
+ }
47
+ return json.data;
48
+ }
49
+ async function confirm(question) {
50
+ if (!process.stdin.isTTY) return false;
51
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
52
+ return new Promise((resolve) => {
53
+ rl.question(`${question} [y/N] `, (answer) => {
54
+ rl.close();
55
+ resolve(/^y(es)?$/i.test(answer.trim()));
56
+ });
57
+ });
58
+ }
59
+ var ENV_KEYS = [
60
+ "IQAUTH_ISSUER",
61
+ "IQAUTH_APP_ID",
62
+ "IQAUTH_APP_KEY",
63
+ "IQAUTH_TENANT_ID",
64
+ "IQAUTH_CLIENT_ID",
65
+ "IQAUTH_CLIENT_SECRET",
66
+ "IQAUTH_PUBLISHABLE_KEY",
67
+ "IQAUTH_SECRET_KEY",
68
+ "IQAUTH_REDIRECT_URI"
69
+ ];
70
+ async function mergeEnv(path, updates) {
71
+ let existing = "";
72
+ try {
73
+ await access(path);
74
+ existing = await readFile(path, "utf8");
75
+ } catch {
76
+ }
77
+ const lines = existing.split(/\r?\n/);
78
+ const seen = /* @__PURE__ */ new Set();
79
+ const out = lines.map((line) => {
80
+ const m = line.match(/^([A-Z_][A-Z0-9_]*)=/);
81
+ if (!m) return line;
82
+ const key = m[1];
83
+ if (Object.prototype.hasOwnProperty.call(updates, key)) {
84
+ seen.add(key);
85
+ return `${key}=${updates[key]}`;
86
+ }
87
+ return line;
88
+ });
89
+ for (const [k, v] of Object.entries(updates)) {
90
+ if (!seen.has(k)) out.push(`${k}=${v}`);
91
+ }
92
+ while (out.length && out[out.length - 1] === "") out.pop();
93
+ await writeFile(path, out.join("\n") + "\n", "utf8");
94
+ }
95
+ async function main() {
96
+ const args = parseArgs(process.argv.slice(2));
97
+ console.log(`\u2192 Signing in / creating account at ${args.baseUrl} ...`);
98
+ const signup = await http(
99
+ `${args.baseUrl}/api/v1/signup`,
100
+ { method: "POST", body: JSON.stringify({ email: args.email, password: args.password, name: args.email.split("@")[0], organizationName: args.org }) }
101
+ ).catch(async (err) => {
102
+ if (String(err.message).includes("EMAIL_IN_USE")) {
103
+ console.log(" account exists, signing in instead ...");
104
+ const login = await http(
105
+ `${args.baseUrl}/api/v1/auth/login`,
106
+ { method: "POST", body: JSON.stringify({ email: args.email, password: args.password }) }
107
+ );
108
+ return { accessToken: login.accessToken, tenant: login.tenants?.[0] || { id: "", slug: "" }, user: login.user };
109
+ }
110
+ throw err;
111
+ });
112
+ console.log(` \u2713 signed in as ${signup.user.email}`);
113
+ const existing = await http(
114
+ `${args.baseUrl}/api/v1/apps`,
115
+ { method: "GET", token: signup.accessToken }
116
+ ).catch(() => []);
117
+ const match = existing.find((a) => a.name === args.appName);
118
+ let appOut;
119
+ let clientOut;
120
+ let pkOut;
121
+ let skOut;
122
+ if (match) {
123
+ console.log(` \u26A0 app "${args.appName}" already exists (id=${match.id}, mode=${match.mode}).`);
124
+ if (!args.rotate) {
125
+ console.log(" re-using its existing keys is not possible (raw keys are only shown once).");
126
+ console.log(" pass --rotate to rotate the publishable + secret keys (24h grace window).");
127
+ process.exit(2);
128
+ }
129
+ const ok = args.yes || await confirm(" rotate publishable + secret keys for this app?");
130
+ if (!ok) {
131
+ console.log(" aborted.");
132
+ process.exit(2);
133
+ }
134
+ const keys = await http(
135
+ `${args.baseUrl}/api/v1/apps/${match.id}/keys`,
136
+ { method: "GET", token: signup.accessToken }
137
+ );
138
+ const pkKey = keys.find((k) => k.kind === "publishable" && k.mode === args.mode);
139
+ const skKey = keys.find((k) => k.kind === "secret" && k.mode === args.mode);
140
+ if (!pkKey || !skKey) {
141
+ console.error(" no existing pk_/sk_ pair found for this mode; cannot rotate.");
142
+ process.exit(3);
143
+ }
144
+ const pkRot = await http(
145
+ `${args.baseUrl}/api/v1/apps/${match.id}/keys/${pkKey.id}/rotate`,
146
+ { method: "POST", token: signup.accessToken }
147
+ );
148
+ const skRot = await http(
149
+ `${args.baseUrl}/api/v1/apps/${match.id}/keys/${skKey.id}/rotate`,
150
+ { method: "POST", token: signup.accessToken }
151
+ );
152
+ pkOut = pkRot.rawKey;
153
+ skOut = skRot.rawKey;
154
+ appOut = match;
155
+ clientOut = { clientId: "" };
156
+ console.log(" \u2713 rotated keys (previous values valid for 24h)");
157
+ } else {
158
+ console.log(`\u2192 Creating app "${args.appName}" (${args.mode} mode) ...`);
159
+ const created = await http(`${args.baseUrl}/api/v1/apps`, {
160
+ method: "POST",
161
+ token: signup.accessToken,
162
+ body: JSON.stringify({
163
+ name: args.appName,
164
+ mode: args.mode,
165
+ redirectUris: [args.redirect],
166
+ allowedOrigins: [args.origin]
167
+ })
168
+ });
169
+ appOut = created.app;
170
+ clientOut = created.client;
171
+ pkOut = created.publishableKey.rawKey;
172
+ skOut = created.secretKey.rawKey;
173
+ console.log(` \u2713 app ${created.app.key} created`);
174
+ }
175
+ const updates = {
176
+ IQAUTH_ISSUER: args.baseUrl,
177
+ IQAUTH_APP_ID: appOut.id,
178
+ IQAUTH_APP_KEY: appOut.key,
179
+ IQAUTH_TENANT_ID: signup.tenant.id || "",
180
+ IQAUTH_CLIENT_ID: clientOut.clientId || "",
181
+ IQAUTH_PUBLISHABLE_KEY: pkOut,
182
+ IQAUTH_SECRET_KEY: skOut,
183
+ IQAUTH_REDIRECT_URI: args.redirect
184
+ };
185
+ if (clientOut.clientSecret) updates.IQAUTH_CLIENT_SECRET = clientOut.clientSecret;
186
+ for (const k of Object.keys(updates)) if (!updates[k]) delete updates[k];
187
+ await mergeEnv(args.envFile, updates);
188
+ console.log(`
189
+ \u2705 Wrote ${Object.keys(updates).length} IQAUTH_* variables to ${args.envFile}`);
190
+ console.log(` Add ${args.envFile} to .gitignore \u2014 it contains your secret key.`);
191
+ console.log(` Use IQAUTH_PUBLISHABLE_KEY in your front-end and IQAUTH_SECRET_KEY in your back-end.
192
+ `);
193
+ void ENV_KEYS;
194
+ }
195
+ main().catch((err) => {
196
+ console.error("\n\u2717", err.message);
197
+ process.exit(1);
198
+ });
@@ -0,0 +1,63 @@
1
+ import {
2
+ callApi,
3
+ loadEnv,
4
+ parseFlags
5
+ } from "./chunk-X3K3WOBR.mjs";
6
+ import "./chunk-Y6FXYEAI.mjs";
7
+
8
+ // src/cli/keys.ts
9
+ async function getCtx(flags) {
10
+ const env = await loadEnv(flags.get("env-file") || ".env");
11
+ const baseUrl = flags.get("base-url") || env.IQAUTH_ISSUER;
12
+ const token = flags.get("token") || env.IQAUTH_ADMIN_TOKEN || env.IQAUTH_SECRET_KEY;
13
+ const app = flags.get("app") || env.IQAUTH_APP_ID || env.IQAUTH_APP_KEY;
14
+ if (!baseUrl) throw new Error("Missing --base-url (or IQAUTH_ISSUER in env).");
15
+ if (!token) throw new Error("Missing --token (or IQAUTH_ADMIN_TOKEN / IQAUTH_SECRET_KEY in env).");
16
+ if (!app) throw new Error("Missing --app <appId|appKey> (or IQAUTH_APP_ID in env).");
17
+ return { baseUrl, token, app };
18
+ }
19
+ async function runKeys(argv) {
20
+ const action = argv[0];
21
+ const { flags, bools } = parseFlags(argv.slice(1));
22
+ if (action === "list") {
23
+ const ctx = await getCtx(flags);
24
+ const keys = await callApi(ctx.baseUrl, `/api/v1/apps/${ctx.app}/keys`, { method: "GET", token: ctx.token });
25
+ const header = ["KIND", "MODE", "ID", "PREFIX", "CREATED", "REVOKED"].join(" ");
26
+ console.log(header);
27
+ for (const k of keys) {
28
+ console.log([k.kind, k.mode, k.id, k.prefix || "", k.createdAt || "", k.revokedAt || "-"].join(" "));
29
+ }
30
+ return;
31
+ }
32
+ if (action === "rotate") {
33
+ const ctx = await getCtx(flags);
34
+ const keyId = flags.get("key-id");
35
+ if (!keyId) throw new Error("Missing --key-id <id>");
36
+ if (!bools.has("yes")) {
37
+ console.log(`Rotate key ${keyId} for app ${ctx.app}? Previous value valid 24h. Re-run with --yes to proceed.`);
38
+ process.exit(2);
39
+ }
40
+ const out = await callApi(ctx.baseUrl, `/api/v1/apps/${ctx.app}/keys/${keyId}/rotate`, { method: "POST", token: ctx.token });
41
+ console.log(`\u2713 rotated. New value:
42
+ ${out.rawKey}`);
43
+ console.log(" Old value remains valid for 24h.");
44
+ return;
45
+ }
46
+ if (action === "revoke") {
47
+ const ctx = await getCtx(flags);
48
+ const keyId = flags.get("key-id");
49
+ if (!keyId) throw new Error("Missing --key-id <id>");
50
+ if (!bools.has("yes")) {
51
+ console.log(`Revoke key ${keyId} for app ${ctx.app}? IMMEDIATE \u2014 there is no grace window. Re-run with --yes.`);
52
+ process.exit(2);
53
+ }
54
+ await callApi(ctx.baseUrl, `/api/v1/apps/${ctx.app}/keys/${keyId}`, { method: "DELETE", token: ctx.token });
55
+ console.log("\u2713 revoked.");
56
+ return;
57
+ }
58
+ console.error("Usage: iqauth keys <list|rotate|revoke> [--app <id>] [--key-id <id>] [--yes]");
59
+ process.exit(1);
60
+ }
61
+ export {
62
+ runKeys
63
+ };
@@ -0,0 +1,11 @@
1
+ import { I as IQAuthClient } from './client-C1DXfB8Z.mjs';
2
+ import { b as IQAuthTokenClientConfig } from './types-Cxl3bQHt.mjs';
3
+ export { E as ErrorCodes, I as IQAuthError } from './errors-CDdl24MP.mjs';
4
+ import 'jsonwebtoken';
5
+
6
+ declare class MobileIQAuthClient extends IQAuthClient {
7
+ constructor(config: IQAuthTokenClientConfig);
8
+ }
9
+ declare function createMobileClient(config: IQAuthTokenClientConfig): MobileIQAuthClient;
10
+
11
+ export { IQAuthClient, IQAuthTokenClientConfig, MobileIQAuthClient, createMobileClient };
@@ -0,0 +1,11 @@
1
+ import { I as IQAuthClient } from './client-CggvJmmm.js';
2
+ import { b as IQAuthTokenClientConfig } from './types-Cxl3bQHt.js';
3
+ export { E as ErrorCodes, I as IQAuthError } from './errors-CDdl24MP.js';
4
+ import 'jsonwebtoken';
5
+
6
+ declare class MobileIQAuthClient extends IQAuthClient {
7
+ constructor(config: IQAuthTokenClientConfig);
8
+ }
9
+ declare function createMobileClient(config: IQAuthTokenClientConfig): MobileIQAuthClient;
10
+
11
+ export { IQAuthClient, IQAuthTokenClientConfig, MobileIQAuthClient, createMobileClient };