@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
@@ -0,0 +1,178 @@
1
+ # Token Verification
2
+
3
+ ## Purpose
4
+
5
+ Verify JWT access tokens using RS256 with JWKS, decode tokens without verification, and check expiry. This is the recommended approach for server-side token validation.
6
+
7
+ ## Prerequisites
8
+
9
+ - `@iqauth/sdk` installed
10
+ - IQAuthService base URL (JWKS is fetched from `/.well-known/jwks.json`)
11
+ - A valid JWT access token to verify
12
+
13
+ ## SDK Methods
14
+
15
+ | Module | Method | Description |
16
+ |--------|--------|-------------|
17
+ | `tokens` | `verify(token)` | Verify JWT via RS256/JWKS → `JwtClaims` |
18
+ | `tokens` | `decode(token)` | Decode without verification → `JwtClaims \| null` |
19
+ | `tokens` | `getClaims(token)` | Decode or throw → `JwtClaims` |
20
+ | `tokens` | `isExpired(token)` | Check `exp` claim → `boolean` |
21
+ | `tokens` | `clearCache()` | Clear JWKS cache (testing only) |
22
+
23
+ ## Step-by-Step
24
+
25
+ ### 1. Verify a Token (Server-Side)
26
+
27
+ ```typescript
28
+ const claims = await client.tokens.verify(bearerToken);
29
+ ```
30
+
31
+ Verification performs:
32
+ 1. Decodes the JWT header to extract the `kid` (key ID)
33
+ 2. Fetches the public key from JWKS (cached for 1 hour)
34
+ 3. Verifies the signature using RS256
35
+ 4. Validates the issuer (`auth.dispositioniq.com`)
36
+ 5. Validates the audience (`dispositioniq`, `iqcapture`, `iqreuse`, `iqvalidate`)
37
+ 6. Checks expiration
38
+
39
+ ### 2. Decode Without Verification (Client-Side)
40
+
41
+ ```typescript
42
+ const claims = client.tokens.decode(token);
43
+ // Returns JwtClaims | null (null if malformed)
44
+ ```
45
+
46
+ ### 3. Check Expiry
47
+
48
+ ```typescript
49
+ if (client.tokens.isExpired(token)) {
50
+ // Refresh or re-authenticate
51
+ }
52
+ ```
53
+
54
+ ### JWT Claims Structure
55
+
56
+ ```typescript
57
+ interface JwtClaims {
58
+ sub: string; // User ID
59
+ email: string; // User email
60
+ name: string; // Display name
61
+ tenantId: string; // Current tenant
62
+ vendorId: string | null; // Vendor ID (if vendor user)
63
+ roles: string[]; // Flat roles array
64
+ entitlements: string[]; // Product entitlements
65
+ sessionId: string; // Current session ID
66
+ jti: string; // Unique token ID
67
+ iss: string; // "auth.dispositioniq.com"
68
+ aud: string[]; // Audience array
69
+ exp?: number; // Expiration (Unix timestamp)
70
+ iat?: number; // Issued at (Unix timestamp)
71
+ scopeContext?: ScopeContext; // V2 scope context
72
+ loginMethod?: string; // "password" | "pin" | "google"
73
+ }
74
+ ```
75
+
76
+ ### JWKS Caching
77
+
78
+ - Keys are cached for 1 hour (matches server's `Cache-Control: max-age=3600`)
79
+ - On unknown `kid`, the cache is refreshed once and retried (handles key rotation)
80
+
81
+ ## Error Handling
82
+
83
+ | Error Code | Meaning | Recovery |
84
+ |------------|---------|----------|
85
+ | `TOKEN_INVALID` | Malformed, missing `kid`, or signature failure | Re-authenticate |
86
+ | `TOKEN_EXPIRED` | `exp` claim is in the past | Refresh token |
87
+ | `INTERNAL_ERROR` | Failed to fetch JWKS endpoint | Retry or check connectivity |
88
+
89
+ ```typescript
90
+ import { IQAuthError } from "@iqauth/sdk";
91
+
92
+ try {
93
+ const claims = await client.tokens.verify(token);
94
+ } catch (err) {
95
+ if (err instanceof IQAuthError) {
96
+ if (err.code === "TOKEN_EXPIRED") {
97
+ // Attempt refresh
98
+ }
99
+ if (err.code === "TOKEN_INVALID") {
100
+ // Re-authenticate
101
+ }
102
+ }
103
+ }
104
+ ```
105
+
106
+ ### Middleware Setup
107
+
108
+ The recommended way to verify tokens in Express is via `iqAuthMiddleware`, which wraps token verification:
109
+
110
+ ```typescript
111
+ import express from "express";
112
+ import { createServerClient } from "@iqauth/sdk/server";
113
+
114
+ const app = express();
115
+ const client = createServerClient({
116
+ baseUrl: "https://auth.dispositioniq.com",
117
+ });
118
+
119
+ // Protect all /api routes — verifies Bearer token via JWKS
120
+ app.use("/api", client.middleware());
121
+
122
+ // Access verified claims via req.auth
123
+ app.get("/api/me", (req, res) => {
124
+ res.json({
125
+ userId: req.auth!.sub,
126
+ email: req.auth!.email,
127
+ roles: req.auth!.roles,
128
+ });
129
+ });
130
+ ```
131
+
132
+ For more middleware options (optional auth, role/entitlement checks, custom error handlers), see [Middleware Reference](./middleware-reference.md).
133
+
134
+ ## Complete Example
135
+
136
+ ```typescript
137
+ import express from "express";
138
+ import { createServerClient } from "@iqauth/sdk/server";
139
+ import { IQAuthError } from "@iqauth/sdk";
140
+
141
+ const client = createServerClient({
142
+ baseUrl: "https://auth.dispositioniq.com",
143
+ });
144
+
145
+ // Option 1: Middleware (recommended for Express apps)
146
+ const app = express();
147
+ app.use("/api", client.middleware());
148
+ app.get("/api/me", (req, res) => res.json(req.auth));
149
+
150
+ // Option 2: Manual verification (for non-Express or custom flows)
151
+ async function validateRequest(authHeader: string): Promise<{
152
+ valid: boolean;
153
+ claims?: import("@iqauth/sdk").JwtClaims;
154
+ error?: string;
155
+ }> {
156
+ if (!authHeader?.startsWith("Bearer ")) {
157
+ return { valid: false, error: "Missing Bearer token" };
158
+ }
159
+
160
+ const token = authHeader.substring(7);
161
+
162
+ try {
163
+ const claims = await client.tokens.verify(token);
164
+ return { valid: true, claims };
165
+ } catch (err) {
166
+ if (err instanceof IQAuthError) {
167
+ return { valid: false, error: `${err.code}: ${err.message}` };
168
+ }
169
+ return { valid: false, error: "Unknown verification error" };
170
+ }
171
+ }
172
+
173
+ // Option 3: Client-side decode (no verification)
174
+ function getUserIdFromToken(token: string): string | null {
175
+ const claims = client.tokens.decode(token);
176
+ return claims?.sub ?? null;
177
+ }
178
+ ```
@@ -0,0 +1,184 @@
1
+ # User Management
2
+
3
+ ## Purpose
4
+
5
+ Manage user profiles, provision new users, and handle account lifecycle (deactivation, reactivation, unlock).
6
+
7
+ ## Prerequisites
8
+
9
+ - `@iqauth/sdk` installed
10
+ - Authenticated user with appropriate role:
11
+ - Any authenticated user: `getCurrent()`, `update()`, `updatePassword()`
12
+ - `tenant_admin`: `list()`, `deactivate()`, `reactivate()`, `unlock()`
13
+ - `platform_admin` or admin API key: `create()`
14
+
15
+ ## Environment Note
16
+
17
+ The token examples in this guide are for trusted runtimes.
18
+
19
+ If your UI is a first-party browser app, call these operations through your backend session layer instead of storing raw tokens in browser-readable storage.
20
+
21
+ ## SDK Methods
22
+
23
+ | Module | Method | Description |
24
+ |--------|--------|-------------|
25
+ | `users` | `getCurrent()` | Get current user profile |
26
+ | `users` | `getById(userId)` | Get user by ID |
27
+ | `users` | `list(params?)` | List users (filterable) |
28
+ | `users` | `create(tenantId, data)` | Provision a new user |
29
+ | `users` | `update(data)` | Update current user profile |
30
+ | `users` | `deactivate(userId)` | Deactivate a user |
31
+ | `users` | `reactivate(userId)` | Reactivate a user |
32
+ | `users` | `unlock(userId)` | Unlock a locked account |
33
+ | `users` | `getPermissions(userId, product)` | Get effective permissions |
34
+ | `users` | `updatePassword(current, new)` | Change password |
35
+
36
+ ## Step-by-Step
37
+
38
+ ### 1. Get Current User
39
+
40
+ ```typescript
41
+ const me = await client.users.getCurrent();
42
+ ```
43
+
44
+ Returns `UserProfile`:
45
+
46
+ ```typescript
47
+ interface UserProfile {
48
+ id: string;
49
+ email: string;
50
+ name: string;
51
+ picture?: string | null;
52
+ isActive: boolean;
53
+ tenantId?: string;
54
+ vendorId?: string | null;
55
+ roles?: string[];
56
+ isDemoAccount?: boolean;
57
+ createdAt?: string;
58
+ updatedAt?: string;
59
+ mustChangePassword?: boolean;
60
+ passwordExpiresAt?: string | null;
61
+ externalId?: string | null;
62
+ }
63
+ ```
64
+
65
+ ### 2. List Users
66
+
67
+ ```typescript
68
+ const allUsers = await client.users.list();
69
+ const tenantUsers = await client.users.list({ tenantId: "tenant-uuid" });
70
+ const filtered = await client.users.list({ email: "user@example.com" });
71
+ ```
72
+
73
+ ### 3. Provision a New User
74
+
75
+ ```typescript
76
+ const result = await client.users.create("tenant-uuid", {
77
+ email: "newuser@example.com",
78
+ name: "New User",
79
+ role: "user",
80
+ vendorId: "vendor-uuid",
81
+ isActive: true,
82
+ externalId: "ext-123",
83
+ });
84
+ // { userId, email, tenantId, role, vendorId }
85
+ ```
86
+
87
+ Note: `create()` requires a `tenantId` because user provisioning is tenant-scoped. See [DECISION-003](../../DECISIONS.md).
88
+
89
+ ### 4. Update Profile
90
+
91
+ ```typescript
92
+ await client.users.update({ name: "New Name", picture: "https://example.com/avatar.jpg" });
93
+ ```
94
+
95
+ ### 5. Account Lifecycle
96
+
97
+ ```typescript
98
+ await client.users.deactivate("user-uuid"); // Soft disable
99
+ await client.users.reactivate("user-uuid"); // Re-enable
100
+ await client.users.unlock("user-uuid"); // Unlock after lockout
101
+ ```
102
+
103
+ ### 6. Change Password
104
+
105
+ ```typescript
106
+ await client.users.updatePassword("currentPassword", "newPassword");
107
+ ```
108
+
109
+ Note: There is no `users.delete()` method. Use `client.tenants.removeUser()` or `users.deactivate()`. See [DECISION-004](../../DECISIONS.md).
110
+
111
+ ## Error Handling
112
+
113
+ | Error Code | Meaning | Recovery |
114
+ |------------|---------|----------|
115
+ | `NOT_FOUND` | User does not exist | Check user ID |
116
+ | `INSUFFICIENT_PERMISSIONS` | Caller lacks admin role | Requires `tenant_admin` |
117
+ | `ALREADY_EXISTS` | Email already registered | Use different email |
118
+ | `VALIDATION_ERROR` | Invalid request data | Check required fields |
119
+ | `PASSWORD_POLICY_VIOLATION` | Password doesn't meet policy | Strengthen password |
120
+
121
+ ```typescript
122
+ import { IQAuthError, ErrorCodes } from "@iqauth/sdk";
123
+
124
+ try {
125
+ await client.users.create(tenantId, { email, name, role: "user" });
126
+ } catch (err) {
127
+ if (err instanceof IQAuthError && err.code === ErrorCodes.ALREADY_EXISTS) {
128
+ console.log("User already exists with this email");
129
+ }
130
+ }
131
+ ```
132
+
133
+ ## Complete Example
134
+
135
+ ```typescript
136
+ import { IQAuthClient, IQAuthError, ErrorCodes } from "@iqauth/sdk";
137
+
138
+ const client = new IQAuthClient({
139
+ baseUrl: "https://auth.dispositioniq.com",
140
+ // Trusted runtime example
141
+ accessToken: adminAccessToken,
142
+ refreshToken: adminRefreshToken,
143
+ });
144
+
145
+ async function provisionAndSetupUser(tenantId: string, email: string, name: string) {
146
+ try {
147
+ const result = await client.users.create(tenantId, {
148
+ email,
149
+ name,
150
+ role: "user",
151
+ isActive: true,
152
+ });
153
+ console.log("Provisioned user:", result.userId);
154
+
155
+ const user = await client.users.getById(result.userId);
156
+ console.log("User profile:", user.name, user.email, user.isActive);
157
+
158
+ return result;
159
+ } catch (err) {
160
+ if (err instanceof IQAuthError) {
161
+ if (err.code === ErrorCodes.ALREADY_EXISTS) {
162
+ const users = await client.users.list({ email });
163
+ return { userId: users[0].id, email, tenantId, role: "user", vendorId: null };
164
+ }
165
+ }
166
+ throw err;
167
+ }
168
+ }
169
+ ```
170
+
171
+ ## API Reference
172
+
173
+ | Method | HTTP | Path |
174
+ |--------|------|------|
175
+ | `getCurrent()` | GET | `/api/v1/users/me` |
176
+ | `getById(id)` | GET | `/api/v1/users/:id` |
177
+ | `list(params?)` | GET | `/api/v1/users` |
178
+ | `create(tenantId, data)` | POST | `/api/v1/tenants/:tenantId/users/provision` |
179
+ | `update(data)` | PATCH | `/api/v1/users/me` |
180
+ | `deactivate(id)` | PATCH | `/api/v1/users/:id/deactivate` |
181
+ | `reactivate(id)` | PATCH | `/api/v1/users/:id/reactivate` |
182
+ | `unlock(id)` | PATCH | `/api/v1/users/:id/unlock` |
183
+ | `getPermissions(id, product)` | GET | `/api/v1/users/:id/permissions?product=...` |
184
+ | `updatePassword(current, new)` | POST | `/api/v1/auth/password/change` |
@@ -0,0 +1,136 @@
1
+ # Webhooks
2
+
3
+ ## Purpose
4
+
5
+ Subscribe to IQAuth events and receive HTTP callbacks. Manage webhook endpoints, test connectivity, view delivery history, and rotate signing secrets.
6
+
7
+ ## Prerequisites
8
+
9
+ - `@iqauth/sdk` installed
10
+ - `tenant_admin` role for webhook management
11
+ - A publicly accessible HTTPS URL to receive webhook events
12
+
13
+ ## Environment Note
14
+
15
+ The management examples in this guide assume a trusted backend, admin script, or other secure runtime.
16
+
17
+ For first-party browser apps, keep webhook administration behind your backend session model.
18
+
19
+ ## SDK Methods
20
+
21
+ | Module | Method | Description |
22
+ |--------|--------|-------------|
23
+ | `webhooks` | `createEndpoint(data)` | Create endpoint → `{ endpoint, secret }` |
24
+ | `webhooks` | `listEndpoints()` | List endpoints → `WebhookEndpoint[]` |
25
+ | `webhooks` | `deleteEndpoint(id)` | Delete endpoint |
26
+ | `webhooks` | `getDeliveries(endpointId)` | Delivery history → `WebhookDelivery[]` |
27
+ | `webhooks` | `testEndpoint(id)` | Send test event → `WebhookTestResult` |
28
+ | `webhooks` | `rotateSecret(id)` | Rotate signing secret → `{ newSecret }` |
29
+
30
+ ## Step-by-Step
31
+
32
+ ### 1. Create Endpoint
33
+
34
+ ```typescript
35
+ const { endpoint, secret } = await client.webhooks.createEndpoint({
36
+ url: "https://myapp.com/webhooks/iqauth",
37
+ events: ["user.created", "user.deactivated", "session.created"],
38
+ });
39
+ // IMPORTANT: Store secret securely — used to verify webhook signatures
40
+ ```
41
+
42
+ ### 2. Test Endpoint
43
+
44
+ ```typescript
45
+ const result = await client.webhooks.testEndpoint(endpoint.id);
46
+ console.log("Test status:", result.statusCode); // 200
47
+ ```
48
+
49
+ ### 3. View Deliveries
50
+
51
+ ```typescript
52
+ const deliveries = await client.webhooks.getDeliveries(endpoint.id);
53
+ for (const d of deliveries) {
54
+ console.log(`${d.event} → ${d.statusCode} at ${d.deliveredAt}`);
55
+ }
56
+ ```
57
+
58
+ ### 4. Rotate Secret
59
+
60
+ ```typescript
61
+ const { newSecret } = await client.webhooks.rotateSecret(endpoint.id);
62
+ // Update your webhook handler with the new secret
63
+ ```
64
+
65
+ ### 5. List / Delete
66
+
67
+ ```typescript
68
+ const endpoints = await client.webhooks.listEndpoints();
69
+ await client.webhooks.deleteEndpoint(endpoint.id);
70
+ ```
71
+
72
+ ## Error Handling
73
+
74
+ | Error Code | Meaning | Recovery |
75
+ |------------|---------|----------|
76
+ | `NOT_FOUND` | Endpoint doesn't exist | Check endpoint ID |
77
+ | `VALIDATION_ERROR` | Invalid URL or events | Check request format |
78
+ | `INSUFFICIENT_PERMISSIONS` | Caller lacks admin role | Requires `tenant_admin`+ |
79
+
80
+ ```typescript
81
+ import { IQAuthError, ErrorCodes } from "@iqauth/sdk";
82
+
83
+ try {
84
+ await client.webhooks.createEndpoint({ url, events });
85
+ } catch (err) {
86
+ if (err instanceof IQAuthError && err.code === ErrorCodes.VALIDATION_ERROR) {
87
+ console.error("Invalid webhook URL or events:", err.message);
88
+ }
89
+ }
90
+ ```
91
+
92
+ ## Complete Example
93
+
94
+ ```typescript
95
+ import { IQAuthClient } from "@iqauth/sdk";
96
+
97
+ const client = new IQAuthClient({
98
+ baseUrl: "https://auth.dispositioniq.com",
99
+ // Trusted runtime example
100
+ accessToken: adminToken,
101
+ refreshToken: adminRefreshToken,
102
+ });
103
+
104
+ async function setupWebhooks(callbackUrl: string) {
105
+ const { endpoint, secret } = await client.webhooks.createEndpoint({
106
+ url: callbackUrl,
107
+ events: ["user.created", "user.deactivated", "session.created", "session.terminated"],
108
+ });
109
+ console.log("Webhook endpoint:", endpoint.id);
110
+ console.log("Secret:", secret); // Store securely!
111
+
112
+ const testResult = await client.webhooks.testEndpoint(endpoint.id);
113
+ if (testResult.statusCode !== 200) {
114
+ console.error("Webhook test failed:", testResult.statusCode);
115
+ await client.webhooks.deleteEndpoint(endpoint.id);
116
+ throw new Error("Webhook endpoint not responding correctly");
117
+ }
118
+ console.log("Webhook test passed");
119
+
120
+ const deliveries = await client.webhooks.getDeliveries(endpoint.id);
121
+ console.log(`${deliveries.length} deliveries logged`);
122
+
123
+ return { endpointId: endpoint.id, secret };
124
+ }
125
+ ```
126
+
127
+ ## API Reference
128
+
129
+ | Method | HTTP | Path |
130
+ |--------|------|------|
131
+ | `createEndpoint(data)` | POST | `/api/v1/webhooks/endpoints` |
132
+ | `listEndpoints()` | GET | `/api/v1/webhooks/endpoints` |
133
+ | `deleteEndpoint(id)` | DELETE | `/api/v1/webhooks/endpoints/:id` |
134
+ | `getDeliveries(endpointId)` | GET | `/api/v1/webhooks/deliveries?endpointId=...` |
135
+ | `testEndpoint(id)` | POST | `/api/v1/webhooks/endpoints/:id/test` |
136
+ | `rotateSecret(id)` | POST | `/api/v1/webhooks/endpoints/:id/rotate-secret` |
@@ -0,0 +1,20 @@
1
+ # Integration Prompts
2
+
3
+ These prompts are intended for downstream application teams adopting `@iqauth/sdk`.
4
+
5
+ Start here if the SDK is being distributed as a `.tgz`:
6
+
7
+ - [Install from Tarball](./install-from-tarball.md)
8
+ - [Migrate from Local packages/ Source](./migrate-from-local-packages-source.md)
9
+
10
+ Choose the prompt that matches the application environment:
11
+
12
+ - [First-Party Browser App](./first-party-browser-app.md)
13
+ - [Native Mobile App](./native-mobile-app.md)
14
+ - [Server Platform App](./server-platform-app.md)
15
+ - [Service Automation App](./service-automation-app.md)
16
+
17
+ Use these prompts together with:
18
+
19
+ - [App Integration Matrix](../APP_INTEGRATION_MATRIX.md)
20
+ - [Fresh Implementation Guide](../FRESH_IMPLEMENTATION_GUIDE.md)
@@ -0,0 +1,29 @@
1
+ # Prompt: First-Party Browser App
2
+
3
+ Use this prompt when updating a first-party web app that integrates with IQAuth.
4
+
5
+ ```md
6
+ You are integrating a first-party browser application with IQAuth.
7
+
8
+ Requirements:
9
+ - Use a backend-managed cookie session, not browser-owned durable tokens.
10
+ - The browser must not store refresh tokens in localStorage, sessionStorage, or other durable browser-readable storage.
11
+ - The backend must own:
12
+ - POST /auth/login
13
+ - POST /auth/select-tenant
14
+ - POST /auth/mfa/verify
15
+ - POST /auth/mfa/verify-backup
16
+ - POST /auth/refresh
17
+ - POST /auth/logout
18
+ - GET /auth/me
19
+ - On frontend boot, restore auth state from /auth/me.
20
+ - Treat revoked, inactive, and expired sessions as terminal signed-out transitions.
21
+ - If SDK usage is needed in the browser/session-aware layer, use @iqauth/sdk/browser-session.
22
+ - Do not normalize token-owning browser patterns in examples or implementation.
23
+
24
+ Deliverables:
25
+ - backend auth proxy routes
26
+ - frontend auth/session bootstrap
27
+ - logout/session invalidation handling
28
+ - short verification checklist
29
+ ```
@@ -0,0 +1,41 @@
1
+ # Prompt: Install from Tarball
2
+
3
+ Use this prompt when a downstream app needs to install or update `@iqauth/sdk` from a `.tgz` release artifact.
4
+
5
+ ```md
6
+ You are installing @iqauth/sdk into an application from a versioned .tgz tarball.
7
+
8
+ Inputs:
9
+ - tarball path or filename
10
+ - previous installed SDK version, if any
11
+ - app type: first-party browser, native mobile, server platform, or service automation
12
+
13
+ Requirements:
14
+ - Install the tarball as a package dependency, not by copying SDK source files into the app.
15
+ - Preserve a reproducible dependency reference in package.json and/or the lockfile.
16
+ - Determine whether the installed SDK version changed.
17
+
18
+ Install step:
19
+ - use npm install <tarball-path>
20
+
21
+ After install:
22
+ - if the version changed, continue immediately into the environment-specific setup prompt
23
+ - if the app type is first-party browser, use the first-party browser setup prompt
24
+ - if the app type is native mobile, use the native mobile setup prompt
25
+ - if the app type is server platform, use the server platform setup prompt
26
+ - if the app type is service automation, use the service automation setup prompt
27
+
28
+ Do not stop at “package installed” if the version changed.
29
+
30
+ Always verify:
31
+ - the app is using the correct SDK entry point
32
+ - the app still matches the supported auth model for its environment
33
+ - any old browser token-owning patterns are removed if this is a first-party web app
34
+ ```
35
+
36
+ ## Next Prompt by App Type
37
+
38
+ - [First-Party Browser App](./first-party-browser-app.md)
39
+ - [Native Mobile App](./native-mobile-app.md)
40
+ - [Server Platform App](./server-platform-app.md)
41
+ - [Service Automation App](./service-automation-app.md)
@@ -0,0 +1,57 @@
1
+ # Prompt: Migrate from Local `packages/` Source
2
+
3
+ Use this prompt when an application currently consumes `@iqauth/sdk` from a checked-in local `packages/` source folder and needs to move to the tarball-based distribution model.
4
+
5
+ ```md
6
+ You are migrating an application away from a local checked-in `packages/` source dependency for `@iqauth/sdk`.
7
+
8
+ Current state:
9
+ - the app currently resolves the SDK from a local `packages/` folder or copied source tree
10
+
11
+ Target state:
12
+ - the app installs a versioned `.tgz` release artifact instead
13
+ - the tarball lives in a committed repo path such as `vendor/iq-auth-sdk-x.y.z.tgz`
14
+ - the dependency is reproducible in local development, CI, and deployment
15
+
16
+ Requirements:
17
+ - remove the local source-based dependency on `packages/`
18
+ - install the SDK from a `.tgz` artifact instead of copied source files
19
+ - preserve a clean dependency reference in `package.json` and the lockfile
20
+ - do not leave duplicate SDK resolution paths active
21
+ - identify whether the SDK version changed during the migration
22
+
23
+ Recommended target layout:
24
+ - `vendor/iq-auth-sdk-x.y.z.tgz`
25
+
26
+ Install step:
27
+ - use `npm install ./vendor/iq-auth-sdk-x.y.z.tgz`
28
+
29
+ Migration checklist:
30
+ 1. identify how the app currently references the local `packages/` SDK
31
+ 2. remove that reference cleanly
32
+ 3. add the tarball to `vendor/`
33
+ 4. install the tarball dependency
34
+ 5. verify imports still resolve correctly
35
+ 6. verify the app still uses the correct SDK entry point for its environment
36
+
37
+ After install:
38
+ - if the installed version changed, continue immediately into the matching environment-specific setup prompt
39
+ - if the app is first-party browser, use the first-party browser setup prompt
40
+ - if the app is native mobile, use the native mobile setup prompt
41
+ - if the app is a server platform, use the server platform setup prompt
42
+ - if the app is a service automation app, use the service automation setup prompt
43
+
44
+ Do not stop at “dependency swapped” if the SDK version changed.
45
+
46
+ Always verify:
47
+ - only one SDK source remains active
48
+ - the local `packages/` path is no longer part of dependency resolution
49
+ - the app matches the supported auth model for its environment
50
+ ```
51
+
52
+ ## Next Prompt by App Type
53
+
54
+ - [First-Party Browser App](./first-party-browser-app.md)
55
+ - [Native Mobile App](./native-mobile-app.md)
56
+ - [Server Platform App](./server-platform-app.md)
57
+ - [Service Automation App](./service-automation-app.md)
@@ -0,0 +1,24 @@
1
+ # Prompt: Native Mobile App
2
+
3
+ Use this prompt when updating a native mobile application that integrates with IQAuth.
4
+
5
+ ```md
6
+ You are integrating a native mobile application with IQAuth.
7
+
8
+ Requirements:
9
+ - Use authorization code flow with PKCE.
10
+ - Launch authentication in the system browser / ASWebAuthenticationSession / Custom Tabs.
11
+ - Use state, nonce, code_verifier, and S256 code_challenge.
12
+ - Exchange the authorization code securely.
13
+ - Store access and refresh tokens only in secure OS-backed storage such as Keychain or Keystore.
14
+ - If SDK usage is needed, use @iqauth/sdk/mobile.
15
+ - Do not use browser cookie-session assumptions as the primary mobile pattern.
16
+ - Do not store tokens in plaintext async storage or browser-style storage.
17
+
18
+ Deliverables:
19
+ - PKCE login flow
20
+ - secure token storage implementation
21
+ - refresh handling
22
+ - logout and token-clearing flow
23
+ - short verification checklist
24
+ ```
@@ -0,0 +1,20 @@
1
+ # Prompt: Server Platform App
2
+
3
+ Use this prompt when updating a trusted backend platform or resource server that integrates with IQAuth.
4
+
5
+ ```md
6
+ You are integrating a trusted server-side platform application with IQAuth.
7
+
8
+ Requirements:
9
+ - Use @iqauth/sdk/server.
10
+ - If the app accepts bearer tokens, use the SDK middleware by default rather than re-implementing token verification manually.
11
+ - Attach verified auth context to incoming requests.
12
+ - Enforce roles, entitlements, and route authorization on the server.
13
+ - Keep token handling request-scoped or service-scoped; do not share mutable multi-user token state.
14
+
15
+ Deliverables:
16
+ - server client creation
17
+ - middleware integration
18
+ - protected route examples
19
+ - verification checklist showing middleware-backed auth on protected routes
20
+ ```