@authsome/ui-core 0.1.9 → 1.1.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.
package/dist/index.js CHANGED
@@ -1,1863 +1,2088 @@
1
- 'use strict';
2
-
3
- // src/types/auth.ts
4
- var AuthState = /* @__PURE__ */ ((AuthState2) => {
5
- AuthState2["AUTHENTICATED"] = "authenticated";
6
- AuthState2["UNAUTHENTICATED"] = "unauthenticated";
7
- AuthState2["LOADING"] = "loading";
8
- AuthState2["ERROR"] = "error";
9
- return AuthState2;
10
- })(AuthState || {});
11
- var AuthErrorType = /* @__PURE__ */ ((AuthErrorType2) => {
12
- AuthErrorType2["INVALID_CREDENTIALS"] = "invalid_credentials";
13
- AuthErrorType2["USER_NOT_FOUND"] = "user_not_found";
14
- AuthErrorType2["USER_ALREADY_EXISTS"] = "user_already_exists";
15
- AuthErrorType2["INVALID_TOKEN"] = "invalid_token";
16
- AuthErrorType2["TOKEN_EXPIRED"] = "token_expired";
17
- AuthErrorType2["NETWORK_ERROR"] = "network_error";
18
- AuthErrorType2["VALIDATION_ERROR"] = "validation_error";
19
- AuthErrorType2["MFA_REQUIRED"] = "mfa_required";
20
- AuthErrorType2["EMAIL_NOT_VERIFIED"] = "email_not_verified";
21
- AuthErrorType2["PHONE_NOT_VERIFIED"] = "phone_not_verified";
22
- AuthErrorType2["RATE_LIMIT_EXCEEDED"] = "rate_limit_exceeded";
23
- AuthErrorType2["UNKNOWN_ERROR"] = "unknown_error";
24
- return AuthErrorType2;
25
- })(AuthErrorType || {});
26
- var AuthError = class _AuthError extends Error {
27
- constructor(message, type = "unknown_error" /* UNKNOWN_ERROR */, options) {
28
- super(message);
29
- this.name = "AuthError";
30
- this.type = type;
31
- this.details = options?.details;
32
- this.code = options?.code;
33
- this.originalError = options?.originalError;
34
- if (Error.captureStackTrace) {
35
- Error.captureStackTrace(this, _AuthError);
36
- }
1
+ // src/generated/api-client.ts
2
+ var AuthClient = class {
3
+ baseURL;
4
+ fetchFn;
5
+ constructor(config) {
6
+ this.baseURL = config.baseURL.replace(/\/+$/, "");
7
+ this.fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);
8
+ }
9
+ // ──────────────────────────────────────────────────
10
+ // Generated methods
11
+ // ──────────────────────────────────────────────────
12
+ /**
13
+ * Get AuthSome manifest
14
+ * GET /.well-known/authsome/manifest
15
+ */
16
+ async getManifest() {
17
+ const path = "/.well-known/authsome/manifest";
18
+ return this.request(
19
+ "GET",
20
+ path,
21
+ void 0
22
+ );
37
23
  }
38
- };
39
- var OAuthProvider = /* @__PURE__ */ ((OAuthProvider2) => {
40
- OAuthProvider2["GOOGLE"] = "google";
41
- OAuthProvider2["GITHUB"] = "github";
42
- OAuthProvider2["FACEBOOK"] = "facebook";
43
- OAuthProvider2["TWITTER"] = "twitter";
44
- OAuthProvider2["MICROSOFT"] = "microsoft";
45
- OAuthProvider2["APPLE"] = "apple";
46
- OAuthProvider2["LINKEDIN"] = "linkedin";
47
- OAuthProvider2["DISCORD"] = "discord";
48
- return OAuthProvider2;
49
- })(OAuthProvider || {});
50
- var TwoFactorMethod = /* @__PURE__ */ ((TwoFactorMethod2) => {
51
- TwoFactorMethod2["TOTP"] = "totp";
52
- TwoFactorMethod2["SMS"] = "sms";
53
- TwoFactorMethod2["EMAIL"] = "email";
54
- TwoFactorMethod2["BACKUP_CODE"] = "backup_code";
55
- return TwoFactorMethod2;
56
- })(TwoFactorMethod || {});
57
-
58
- // src/types/storage.ts
59
- var LocalStorageAdapter = class {
60
- getItem(key) {
61
- if (typeof window === "undefined") return null;
62
- return window.localStorage.getItem(key);
24
+ /**
25
+ * Get OpenAPI specification
26
+ * GET /.well-known/authsome/openapi
27
+ */
28
+ async getOpenAPI() {
29
+ const path = "/.well-known/authsome/openapi";
30
+ return this.request(
31
+ "GET",
32
+ path,
33
+ void 0
34
+ );
63
35
  }
64
- setItem(key, value) {
65
- if (typeof window === "undefined") return;
66
- window.localStorage.setItem(key, value);
36
+ /**
37
+ * Get per-app client config overrides
38
+ * GET /v1/admin/apps/{appId}/client-config
39
+ */
40
+ async getAppClientConfig(appId, token) {
41
+ const path = `/v1/admin/apps/${appId}/client-config`;
42
+ return this.request(
43
+ "GET",
44
+ path,
45
+ void 0,
46
+ token
47
+ );
67
48
  }
68
- removeItem(key) {
69
- if (typeof window === "undefined") return;
70
- window.localStorage.removeItem(key);
49
+ /**
50
+ * Set per-app client config overrides
51
+ * PUT /v1/admin/apps/{appId}/client-config
52
+ */
53
+ async setAppClientConfig(appId, body, token) {
54
+ const path = `/v1/admin/apps/${appId}/client-config`;
55
+ return this.request(
56
+ "PUT",
57
+ path,
58
+ body,
59
+ token
60
+ );
71
61
  }
72
- clear() {
73
- if (typeof window === "undefined") return;
74
- window.localStorage.clear();
62
+ /**
63
+ * Delete per-app client config overrides
64
+ * DELETE /v1/admin/apps/{appId}/client-config
65
+ */
66
+ async deleteAppClientConfig(appId, body, token) {
67
+ const path = `/v1/admin/apps/${appId}/client-config`;
68
+ return this.request(
69
+ "DELETE",
70
+ path,
71
+ body,
72
+ token
73
+ );
75
74
  }
76
- };
77
- var SessionStorageAdapter = class {
78
- getItem(key) {
79
- if (typeof window === "undefined") return null;
80
- return window.sessionStorage.getItem(key);
75
+ /**
76
+ * Get per-app session config
77
+ * GET /v1/admin/apps/{appId}/session-config
78
+ */
79
+ async getAppSessionConfig(appId, token) {
80
+ const path = `/v1/admin/apps/${appId}/session-config`;
81
+ return this.request(
82
+ "GET",
83
+ path,
84
+ void 0,
85
+ token
86
+ );
81
87
  }
82
- setItem(key, value) {
83
- if (typeof window === "undefined") return;
84
- window.sessionStorage.setItem(key, value);
88
+ /**
89
+ * Set per-app session config
90
+ * PUT /v1/admin/apps/{appId}/session-config
91
+ */
92
+ async setAppSessionConfig(appId, body, token) {
93
+ const path = `/v1/admin/apps/${appId}/session-config`;
94
+ return this.request(
95
+ "PUT",
96
+ path,
97
+ body,
98
+ token
99
+ );
85
100
  }
86
- removeItem(key) {
87
- if (typeof window === "undefined") return;
88
- window.sessionStorage.removeItem(key);
101
+ /**
102
+ * Delete per-app session config
103
+ * DELETE /v1/admin/apps/{appId}/session-config
104
+ */
105
+ async deleteAppSessionConfig(appId, body, token) {
106
+ const path = `/v1/admin/apps/${appId}/session-config`;
107
+ return this.request(
108
+ "DELETE",
109
+ path,
110
+ body,
111
+ token
112
+ );
89
113
  }
90
- clear() {
91
- if (typeof window === "undefined") return;
92
- window.sessionStorage.clear();
114
+ /**
115
+ * Bulk revoke sessions (admin)
116
+ * DELETE /v1/admin/bulk/sessions
117
+ */
118
+ async adminBulkRevokeSessions(body, token) {
119
+ const path = "/v1/admin/bulk/sessions";
120
+ return this.request(
121
+ "DELETE",
122
+ path,
123
+ body,
124
+ token
125
+ );
93
126
  }
94
- };
95
- var MemoryStorageAdapter = class {
96
- constructor() {
97
- this.store = /* @__PURE__ */ new Map();
127
+ /**
128
+ * Bulk import users (admin)
129
+ * POST /v1/admin/bulk/users/import
130
+ */
131
+ async adminBulkImportUsers(body, token) {
132
+ const path = "/v1/admin/bulk/users/import";
133
+ return this.request(
134
+ "POST",
135
+ path,
136
+ body,
137
+ token
138
+ );
98
139
  }
99
- getItem(key) {
100
- return this.store.get(key) ?? null;
140
+ /**
141
+ * Stop impersonation (admin)
142
+ * POST /v1/admin/impersonate/stop
143
+ */
144
+ async adminStopImpersonation(body, token) {
145
+ const path = "/v1/admin/impersonate/stop";
146
+ return this.request(
147
+ "POST",
148
+ path,
149
+ body,
150
+ token
151
+ );
101
152
  }
102
- setItem(key, value) {
103
- this.store.set(key, value);
153
+ /**
154
+ * Impersonate user (admin)
155
+ * POST /v1/admin/impersonate/{userId}
156
+ */
157
+ async adminImpersonate(userId, body, token) {
158
+ const path = `/v1/admin/impersonate/${userId}`;
159
+ return this.request(
160
+ "POST",
161
+ path,
162
+ body,
163
+ token
164
+ );
104
165
  }
105
- removeItem(key) {
106
- this.store.delete(key);
166
+ /**
167
+ * List organizations (admin)
168
+ * GET /v1/admin/orgs
169
+ */
170
+ async adminListOrgs(token) {
171
+ const path = "/v1/admin/orgs";
172
+ return this.request(
173
+ "GET",
174
+ path,
175
+ void 0,
176
+ token
177
+ );
107
178
  }
108
- clear() {
109
- this.store.clear();
179
+ /**
180
+ * List all setting definitions
181
+ * GET /v1/admin/settings/definitions
182
+ */
183
+ async listSettingsDefinitions(token) {
184
+ const path = "/v1/admin/settings/definitions";
185
+ return this.request(
186
+ "GET",
187
+ path,
188
+ void 0,
189
+ token
190
+ );
110
191
  }
111
- };
112
-
113
- // src/types/observable.ts
114
- var Observable = class {
115
- constructor(initialValue) {
116
- this.listeners = /* @__PURE__ */ new Set();
117
- this.value = initialValue;
192
+ /**
193
+ * List definitions for a namespace
194
+ * GET /v1/admin/settings/definitions/{namespace}
195
+ */
196
+ async listNamespaceSettingsDefinitions(namespace, token) {
197
+ const path = `/v1/admin/settings/definitions/${namespace}`;
198
+ return this.request(
199
+ "GET",
200
+ path,
201
+ void 0,
202
+ token
203
+ );
118
204
  }
119
205
  /**
120
- * Get current value
206
+ * Enforce a setting value at a scope
207
+ * PUT /v1/admin/settings/enforce/{key}
121
208
  */
122
- getValue() {
123
- return this.value;
209
+ async enforceSetting(key, body, token) {
210
+ const path = `/v1/admin/settings/enforce/${key}`;
211
+ return this.request(
212
+ "PUT",
213
+ path,
214
+ body,
215
+ token
216
+ );
124
217
  }
125
218
  /**
126
- * Set new value and notify listeners
219
+ * Remove enforcement from a setting
220
+ * DELETE /v1/admin/settings/enforce/{key}
127
221
  */
128
- setValue(newValue) {
129
- if (this.value !== newValue) {
130
- this.value = newValue;
131
- this.notify();
132
- }
222
+ async unenforceSetting(key, body, token) {
223
+ const path = `/v1/admin/settings/enforce/${key}`;
224
+ return this.request(
225
+ "DELETE",
226
+ path,
227
+ body,
228
+ token
229
+ );
133
230
  }
134
231
  /**
135
- * Update value with a function
232
+ * Resolve all settings at a scope
233
+ * GET /v1/admin/settings/resolve
136
234
  */
137
- update(updater) {
138
- this.setValue(updater(this.value));
235
+ async resolveSettings(token) {
236
+ const path = "/v1/admin/settings/resolve";
237
+ return this.request(
238
+ "GET",
239
+ path,
240
+ void 0,
241
+ token
242
+ );
139
243
  }
140
244
  /**
141
- * Subscribe to value changes
245
+ * Resolve one setting with cascade details
246
+ * GET /v1/admin/settings/resolve/{key}
142
247
  */
143
- subscribe(listener) {
144
- this.listeners.add(listener);
145
- listener(this.value);
146
- return () => {
147
- this.listeners.delete(listener);
148
- };
248
+ async resolveSetting(key, token) {
249
+ const path = `/v1/admin/settings/resolve/${key}`;
250
+ return this.request(
251
+ "GET",
252
+ path,
253
+ void 0,
254
+ token
255
+ );
149
256
  }
150
257
  /**
151
- * Notify all listeners
258
+ * Set a setting value at a scope
259
+ * PUT /v1/admin/settings/values/{key}
152
260
  */
153
- notify() {
154
- this.listeners.forEach((listener) => listener(this.value));
261
+ async setSetting(key, body, token) {
262
+ const path = `/v1/admin/settings/values/${key}`;
263
+ return this.request(
264
+ "PUT",
265
+ path,
266
+ body,
267
+ token
268
+ );
155
269
  }
156
270
  /**
157
- * Clear all listeners
271
+ * Delete a setting override at a scope
272
+ * DELETE /v1/admin/settings/values/{key}
158
273
  */
159
- clearListeners() {
160
- this.listeners.clear();
274
+ async deleteSetting(key, body, token) {
275
+ const path = `/v1/admin/settings/values/${key}`;
276
+ return this.request(
277
+ "DELETE",
278
+ path,
279
+ body,
280
+ token
281
+ );
161
282
  }
162
283
  /**
163
- * Get number of listeners
284
+ * Get stats (admin)
285
+ * GET /v1/admin/stats
164
286
  */
165
- getListenerCount() {
166
- return this.listeners.size;
287
+ async adminGetStats(token) {
288
+ const path = "/v1/admin/stats";
289
+ return this.request(
290
+ "GET",
291
+ path,
292
+ void 0,
293
+ token
294
+ );
167
295
  }
168
- };
169
-
170
- // src/utils/errors.ts
171
- function createAuthError(type, message, details, code) {
172
- return new AuthError(message, type, { details, code });
173
- }
174
- function isAuthError(error) {
175
- return error instanceof AuthError;
176
- }
177
- function toAuthError(error) {
178
- if (isAuthError(error)) {
179
- return error;
180
- }
181
- if (error instanceof Error) {
182
- return new AuthError(error.message, "unknown_error" /* UNKNOWN_ERROR */, {
183
- details: {
184
- originalError: error.name,
185
- stack: error.stack
186
- }
187
- });
296
+ /**
297
+ * List users (admin)
298
+ * GET /v1/admin/users
299
+ */
300
+ async adminListUsers(token) {
301
+ const path = "/v1/admin/users";
302
+ return this.request(
303
+ "GET",
304
+ path,
305
+ void 0,
306
+ token
307
+ );
188
308
  }
189
- if (typeof error === "string") {
190
- return new AuthError(error, "unknown_error" /* UNKNOWN_ERROR */);
309
+ /**
310
+ * Get user (admin)
311
+ * GET /v1/admin/users/{userId}
312
+ */
313
+ async adminGetUser(userId, token) {
314
+ const path = `/v1/admin/users/${userId}`;
315
+ return this.request(
316
+ "GET",
317
+ path,
318
+ void 0,
319
+ token
320
+ );
191
321
  }
192
- return new AuthError(
193
- "An unknown error occurred",
194
- "unknown_error" /* UNKNOWN_ERROR */,
195
- { details: { error } }
196
- );
197
- }
198
- function isNetworkError(error) {
199
- if (error instanceof Error) {
200
- return error.name === "NetworkError" || error.message.includes("network") || error.message.includes("fetch");
322
+ /**
323
+ * Delete user (admin)
324
+ * DELETE /v1/admin/users/{userId}
325
+ */
326
+ async adminDeleteUser(userId, body, token) {
327
+ const path = `/v1/admin/users/${userId}`;
328
+ return this.request(
329
+ "DELETE",
330
+ path,
331
+ body,
332
+ token
333
+ );
201
334
  }
202
- return false;
203
- }
204
- function isUnauthenticatedError(error) {
205
- if (isAuthError(error)) {
206
- return error.type === "invalid_token" /* INVALID_TOKEN */ || error.type === "token_expired" /* TOKEN_EXPIRED */;
335
+ /**
336
+ * Ban user (admin)
337
+ * POST /v1/admin/users/{userId}/ban
338
+ */
339
+ async adminBanUser(userId, body, token) {
340
+ const path = `/v1/admin/users/${userId}/ban`;
341
+ return this.request(
342
+ "POST",
343
+ path,
344
+ body,
345
+ token
346
+ );
207
347
  }
208
- return false;
209
- }
210
- function isMFARequiredError(error) {
211
- if (isAuthError(error)) {
212
- return error.type === "mfa_required" /* MFA_REQUIRED */;
348
+ /**
349
+ * Unban user (admin)
350
+ * POST /v1/admin/users/{userId}/unban
351
+ */
352
+ async adminUnbanUser(userId, body, token) {
353
+ const path = `/v1/admin/users/${userId}/unban`;
354
+ return this.request(
355
+ "POST",
356
+ path,
357
+ body,
358
+ token
359
+ );
213
360
  }
214
- return false;
215
- }
216
-
217
- // src/locale/en.ts
218
- var enLocale = {
219
- common: {
220
- loading: "Loading...",
221
- submit: "Submit",
222
- cancel: "Cancel",
223
- continue: "Continue",
224
- back: "Back",
225
- or: "or",
226
- optional: "optional"
227
- },
228
- auth: {
229
- signIn: "Sign In",
230
- signUp: "Sign Up",
231
- signOut: "Sign Out",
232
- email: "Email",
233
- password: "Password",
234
- confirmPassword: "Confirm Password",
235
- username: "Username",
236
- phone: "Phone",
237
- rememberMe: "Remember me",
238
- forgotPassword: "Forgot password?",
239
- continueWith: "Continue with {provider}",
240
- orContinueWith: "Or continue with"
241
- },
242
- oauth: {
243
- google: "Google",
244
- github: "GitHub",
245
- microsoft: "Microsoft",
246
- facebook: "Facebook",
247
- apple: "Apple",
248
- discord: "Discord",
249
- twitter: "Twitter",
250
- linkedin: "LinkedIn",
251
- chooseProvider: "Choose Your Provider",
252
- signInPreferred: "Sign in with your preferred account"
253
- },
254
- magicLink: {
255
- sendLink: "Send magic link",
256
- checkEmail: "Check your email",
257
- linkSent: "Magic link sent! Check your email to continue.",
258
- enterEmail: "Enter your email to receive a magic link"
259
- },
260
- phone: {
261
- enterPhone: "Enter your phone number",
262
- sendCode: "Send code",
263
- enterCode: "Enter verification code",
264
- verifyPhone: "Verify phone number",
265
- codeLabel: "Verification code"
266
- },
267
- mfa: {
268
- required: "Two-factor authentication required",
269
- selectMethod: "Select verification method",
270
- verify: "Verify",
271
- enterCode: "Enter verification code",
272
- sms: "SMS",
273
- authenticator: "Authenticator app",
274
- email: "Email"
275
- },
276
- passkey: {
277
- signInWith: "Sign in with passkey",
278
- register: "Register passkey",
279
- usePasskey: "Use passkey"
280
- },
281
- deviceFlow: {
282
- title: "Authorize Device",
283
- subtitle: "Enter the code displayed on your device",
284
- enterCode: "Authorize Device",
285
- enterCodeDescription: "Enter the code displayed on your device or CLI",
286
- codeLabel: "Device Code",
287
- codePlaceholder: "XXXX-XXXX",
288
- codeHint: "Enter the 8-character code shown on your device",
289
- verify: "Verify Code",
290
- verifyCode: "Verify Code",
291
- invalidCode: "Invalid code. Please check and try again.",
292
- noCode: "Don't have a code?",
293
- getCodeHelp: "Get help",
294
- authorizationTitle: "Authorize Application",
295
- authorizationSubtitle: "An application is requesting access to your account",
296
- authorizeTitle: "Authorize Device",
297
- authorizeDescription: "An application is requesting access to your account",
298
- requestingAccess: "is requesting access to:",
299
- codeConfirm: "Confirm this is your code:",
300
- requestedPermissions: "Requested permissions:",
301
- securityWarning: "Only approve this request if you initiated it",
302
- scopes: "Requested permissions",
303
- approve: "Approve",
304
- deny: "Deny",
305
- authorizedTitle: "Device Authorized",
306
- authorizedMessage: "You can now return to your device to continue",
307
- authorizedDescription: "Your device has been successfully authorized",
308
- authorizedHint: "You can close this window and return to your CLI or device",
309
- returnToCli: "Return to CLI",
310
- deniedTitle: "Access Denied",
311
- deniedMessage: "You have denied access to this device",
312
- deniedDescription: "The device authorization request has been denied",
313
- deniedHint: "You can close this window"
314
- },
315
- signUp: {
316
- title: "Create Account",
317
- subtitle: "Get started with your account",
318
- haveAccount: "Already have an account?",
319
- signInLink: "Sign in",
320
- agreeToTerms: "I agree to the {terms}",
321
- terms: "terms and conditions"
322
- },
323
- signIn: {
324
- title: "Sign In",
325
- subtitle: "Enter your email to continue",
326
- noAccount: "Don't have an account?",
327
- signUpLink: "Sign up",
328
- enterEmail: "Enter your email to continue"
329
- },
330
- validation: {
331
- emailRequired: "Email is required",
332
- emailInvalid: "Invalid email address",
333
- passwordRequired: "Password is required",
334
- passwordTooShort: "Password must be at least {min} characters",
335
- passwordRequireUppercase: "Password must contain an uppercase letter",
336
- passwordRequireLowercase: "Password must contain a lowercase letter",
337
- passwordRequireNumber: "Password must contain a number",
338
- passwordRequireSpecial: "Password must contain a special character",
339
- passwordMismatch: "Passwords do not match",
340
- usernameRequired: "Username is required",
341
- usernameInvalid: "Username must be 3-30 characters and contain only letters, numbers, underscores, and hyphens",
342
- phoneRequired: "Phone number is required",
343
- phoneInvalid: "Invalid phone number",
344
- codeRequired: "Verification code is required",
345
- codeInvalid: "Invalid verification code",
346
- fieldRequired: "{field} is required",
347
- termsRequired: "You must agree to the terms and conditions"
348
- },
349
- errors: {
350
- invalidCredentials: "Invalid email or password",
351
- userNotFound: "User not found",
352
- userExists: "User already exists",
353
- invalidToken: "Invalid or expired token",
354
- tokenExpired: "Token has expired",
355
- networkError: "Network error. Please try again.",
356
- mfaRequired: "Two-factor authentication required",
357
- emailNotVerified: "Email not verified",
358
- phoneNotVerified: "Phone number not verified",
359
- rateLimitExceeded: "Too many attempts. Please try again later.",
360
- unknownError: "An unknown error occurred",
361
- generic: "Something went wrong. Please try again."
362
- },
363
- success: {
364
- signedIn: "Successfully signed in",
365
- signedUp: "Account created successfully",
366
- signedOut: "Successfully signed out",
367
- linkSent: "Link sent successfully",
368
- codeSent: "Verification code sent",
369
- verified: "Successfully verified",
370
- welcome: "Welcome, {name}!"
371
- },
372
- placeholders: {
373
- email: "john@example.com",
374
- password: "Enter your password",
375
- confirmPassword: "Confirm your password",
376
- username: "johndoe",
377
- phone: "+1234567890",
378
- code: "123456",
379
- fullName: "John Doe"
361
+ /**
362
+ * Change password
363
+ * POST /v1/change-password
364
+ */
365
+ async changePassword(body, token) {
366
+ const path = "/v1/change-password";
367
+ return this.request(
368
+ "POST",
369
+ path,
370
+ body,
371
+ token
372
+ );
380
373
  }
381
- };
382
-
383
- // src/locale/utils.ts
384
- var defaultLocale = enLocale;
385
- function deepMerge(target, source) {
386
- const result = { ...target };
387
- for (const key in source) {
388
- if (source[key] !== void 0) {
389
- if (typeof source[key] === "object" && source[key] !== null && !Array.isArray(source[key]) && typeof result[key] === "object" && result[key] !== null) {
390
- result[key] = deepMerge(result[key], source[key]);
391
- } else {
392
- result[key] = source[key];
393
- }
394
- }
374
+ /**
375
+ * Get client configuration
376
+ * GET /v1/client-config
377
+ */
378
+ async getClientConfig(token) {
379
+ const path = "/v1/client-config";
380
+ return this.request(
381
+ "GET",
382
+ path,
383
+ void 0,
384
+ token
385
+ );
395
386
  }
396
- return result;
397
- }
398
- function createLocale(overrides) {
399
- if (!overrides) {
400
- return defaultLocale;
387
+ /**
388
+ * List devices
389
+ * GET /v1/devices
390
+ */
391
+ async listDevices(token) {
392
+ const path = "/v1/devices";
393
+ return this.request(
394
+ "GET",
395
+ path,
396
+ void 0,
397
+ token
398
+ );
401
399
  }
402
- return deepMerge(defaultLocale, overrides);
403
- }
404
- function interpolate(template, values) {
405
- return template.replace(/\{(\w+)\}/g, (match, key) => {
406
- return values[key] !== void 0 ? String(values[key]) : match;
407
- });
408
- }
409
-
410
- // src/utils/validation.ts
411
- var EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
412
- var PHONE_REGEX = /^\+?[1-9]\d{1,14}$/;
413
- var USERNAME_REGEX = /^[a-zA-Z0-9_-]{3,30}$/;
414
- function validateEmail(email, locale) {
415
- const messages = locale?.validation || defaultLocale.validation;
416
- if (!email) {
417
- return { field: "email", message: messages.emailRequired };
418
- }
419
- if (!EMAIL_REGEX.test(email)) {
420
- return { field: "email", message: messages.emailInvalid };
421
- }
422
- return null;
423
- }
424
- function validatePassword(password, options = {}) {
425
- const {
426
- minLength = 8,
427
- requireUppercase = true,
428
- requireLowercase = true,
429
- requireNumber = true,
430
- requireSpecial = false,
431
- locale
432
- } = options;
433
- const messages = locale?.validation || defaultLocale.validation;
434
- if (!password) {
435
- return { field: "password", message: messages.passwordRequired };
436
- }
437
- if (password.length < minLength) {
438
- return {
439
- field: "password",
440
- message: interpolate(messages.passwordTooShort, { min: minLength.toString() })
441
- };
400
+ /**
401
+ * Get device
402
+ * GET /v1/devices/{deviceId}
403
+ */
404
+ async getDevice(deviceId, token) {
405
+ const path = `/v1/devices/${deviceId}`;
406
+ return this.request(
407
+ "GET",
408
+ path,
409
+ void 0,
410
+ token
411
+ );
442
412
  }
443
- if (requireUppercase && !/[A-Z]/.test(password)) {
444
- return {
445
- field: "password",
446
- message: messages.passwordRequireUppercase
447
- };
413
+ /**
414
+ * Delete device
415
+ * DELETE /v1/devices/{deviceId}
416
+ */
417
+ async deleteDevice(deviceId, body, token) {
418
+ const path = `/v1/devices/${deviceId}`;
419
+ return this.request(
420
+ "DELETE",
421
+ path,
422
+ body,
423
+ token
424
+ );
448
425
  }
449
- if (requireLowercase && !/[a-z]/.test(password)) {
450
- return {
451
- field: "password",
452
- message: messages.passwordRequireLowercase
453
- };
426
+ /**
427
+ * Trust device
428
+ * PATCH /v1/devices/{deviceId}/trust
429
+ */
430
+ async trustDevice(deviceId, body, token) {
431
+ const path = `/v1/devices/${deviceId}/trust`;
432
+ return this.request(
433
+ "PATCH",
434
+ path,
435
+ body,
436
+ token
437
+ );
454
438
  }
455
- if (requireNumber && !/\d/.test(password)) {
456
- return { field: "password", message: messages.passwordRequireNumber };
439
+ /**
440
+ * List environments
441
+ * GET /v1/environments
442
+ */
443
+ async listEnvironments(token) {
444
+ const path = "/v1/environments";
445
+ return this.request(
446
+ "GET",
447
+ path,
448
+ void 0,
449
+ token
450
+ );
457
451
  }
458
- if (requireSpecial && !/[!@#$%^&*(),.?":{}|<>]/.test(password)) {
459
- return {
460
- field: "password",
461
- message: messages.passwordRequireSpecial
462
- };
452
+ /**
453
+ * Create environment
454
+ * POST /v1/environments
455
+ */
456
+ async createEnvironment(body, token) {
457
+ const path = "/v1/environments";
458
+ return this.request(
459
+ "POST",
460
+ path,
461
+ body,
462
+ token
463
+ );
463
464
  }
464
- return null;
465
- }
466
- function validatePhone(phone, locale) {
467
- const messages = locale?.validation || defaultLocale.validation;
468
- if (!phone) {
469
- return { field: "phone", message: messages.phoneRequired };
470
- }
471
- if (!PHONE_REGEX.test(phone)) {
472
- return {
473
- field: "phone",
474
- message: messages.phoneInvalid
475
- };
465
+ /**
466
+ * Get environment
467
+ * GET /v1/environments/{envId}
468
+ */
469
+ async getEnvironment(envId, token) {
470
+ const path = `/v1/environments/${envId}`;
471
+ return this.request(
472
+ "GET",
473
+ path,
474
+ void 0,
475
+ token
476
+ );
476
477
  }
477
- return null;
478
- }
479
- function validateUsername(username, locale) {
480
- const messages = locale?.validation || defaultLocale.validation;
481
- if (!username) {
482
- return { field: "username", message: messages.usernameRequired };
483
- }
484
- if (!USERNAME_REGEX.test(username)) {
485
- return {
486
- field: "username",
487
- message: messages.usernameInvalid
488
- };
478
+ /**
479
+ * Update environment
480
+ * PATCH /v1/environments/{envId}
481
+ */
482
+ async updateEnvironment(envId, body, token) {
483
+ const path = `/v1/environments/${envId}`;
484
+ return this.request(
485
+ "PATCH",
486
+ path,
487
+ body,
488
+ token
489
+ );
489
490
  }
490
- return null;
491
- }
492
- function validate2FACode(code, locale) {
493
- const messages = locale?.validation || defaultLocale.validation;
494
- if (!code) {
495
- return { field: "code", message: messages.codeRequired };
491
+ /**
492
+ * Delete environment
493
+ * DELETE /v1/environments/{envId}
494
+ */
495
+ async deleteEnvironment(envId, token) {
496
+ const path = `/v1/environments/${envId}`;
497
+ return this.request(
498
+ "DELETE",
499
+ path,
500
+ void 0,
501
+ token
502
+ );
496
503
  }
497
- if (!/^\d{6}$/.test(code)) {
498
- return { field: "code", message: messages.codeInvalid };
504
+ /**
505
+ * Clone environment
506
+ * POST /v1/environments/{envId}/clone
507
+ */
508
+ async cloneEnvironment(envId, body, token) {
509
+ const path = `/v1/environments/${envId}/clone`;
510
+ return this.request(
511
+ "POST",
512
+ path,
513
+ body,
514
+ token
515
+ );
499
516
  }
500
- return null;
501
- }
502
- function validateRequired(value, fieldName, locale) {
503
- const messages = locale?.validation || defaultLocale.validation;
504
- if (!value || typeof value === "string" && !value.trim()) {
505
- return {
506
- field: fieldName,
507
- message: interpolate(messages.fieldRequired, { field: fieldName })
508
- };
517
+ /**
518
+ * Set default environment
519
+ * POST /v1/environments/{envId}/set-default
520
+ */
521
+ async setDefaultEnvironment(envId, token) {
522
+ const path = `/v1/environments/${envId}/set-default`;
523
+ return this.request(
524
+ "POST",
525
+ path,
526
+ void 0,
527
+ token
528
+ );
509
529
  }
510
- return null;
511
- }
512
-
513
- // src/utils/tokens.ts
514
- var TOKEN_KEY = "authsome_token";
515
- var REFRESH_TOKEN_KEY = "authsome_refresh_token";
516
- var TokenManager = class {
517
- constructor(storage = new LocalStorageAdapter()) {
518
- this.storage = storage;
530
+ /**
531
+ * Get environment settings
532
+ * GET /v1/environments/{envId}/settings
533
+ */
534
+ async getEnvironmentSettings(envId, token) {
535
+ const path = `/v1/environments/${envId}/settings`;
536
+ return this.request(
537
+ "GET",
538
+ path,
539
+ void 0,
540
+ token
541
+ );
519
542
  }
520
543
  /**
521
- * Get access token
544
+ * Update environment settings
545
+ * PATCH /v1/environments/{envId}/settings
522
546
  */
523
- async getToken() {
524
- return await Promise.resolve(this.storage.getItem(TOKEN_KEY));
547
+ async updateEnvironmentSettings(envId, body, token) {
548
+ const path = `/v1/environments/${envId}/settings`;
549
+ return this.request(
550
+ "PATCH",
551
+ path,
552
+ body,
553
+ token
554
+ );
525
555
  }
526
556
  /**
527
- * Set access token
557
+ * Forgot password
558
+ * POST /v1/forgot-password
528
559
  */
529
- async setToken(token) {
530
- await Promise.resolve(this.storage.setItem(TOKEN_KEY, token));
560
+ async forgotPassword(body) {
561
+ const path = "/v1/forgot-password";
562
+ return this.request(
563
+ "POST",
564
+ path,
565
+ body
566
+ );
531
567
  }
532
568
  /**
533
- * Remove access token
569
+ * Health check
570
+ * GET /v1/health
534
571
  */
535
- async removeToken() {
536
- await Promise.resolve(this.storage.removeItem(TOKEN_KEY));
572
+ async getHealth() {
573
+ const path = "/v1/health";
574
+ return this.request(
575
+ "GET",
576
+ path,
577
+ void 0
578
+ );
537
579
  }
538
580
  /**
539
- * Get refresh token
581
+ * List API keys
582
+ * GET /v1/keys
540
583
  */
541
- async getRefreshToken() {
542
- return await Promise.resolve(this.storage.getItem(REFRESH_TOKEN_KEY));
584
+ async listAPIKeys(token) {
585
+ const path = "/v1/keys";
586
+ return this.request(
587
+ "GET",
588
+ path,
589
+ void 0,
590
+ token
591
+ );
543
592
  }
544
593
  /**
545
- * Set refresh token
594
+ * Create API key
595
+ * POST /v1/keys
546
596
  */
547
- async setRefreshToken(token) {
548
- await Promise.resolve(this.storage.setItem(REFRESH_TOKEN_KEY, token));
597
+ async createAPIKey(body, token) {
598
+ const path = "/v1/keys";
599
+ return this.request(
600
+ "POST",
601
+ path,
602
+ body,
603
+ token
604
+ );
549
605
  }
550
606
  /**
551
- * Remove refresh token
607
+ * Revoke API key
608
+ * DELETE /v1/keys/{keyId}
552
609
  */
553
- async removeRefreshToken() {
554
- await Promise.resolve(this.storage.removeItem(REFRESH_TOKEN_KEY));
610
+ async revokeAPIKey(keyId, body, token) {
611
+ const path = `/v1/keys/${keyId}`;
612
+ return this.request(
613
+ "DELETE",
614
+ path,
615
+ body,
616
+ token
617
+ );
618
+ }
619
+ /**
620
+ * Send magic link
621
+ * POST /v1/magic-link/send
622
+ */
623
+ async sendMagicLink(body) {
624
+ const path = "/v1/magic-link/send";
625
+ return this.request(
626
+ "POST",
627
+ path,
628
+ body
629
+ );
630
+ }
631
+ /**
632
+ * Verify magic link
633
+ * POST /v1/magic-link/verify
634
+ */
635
+ async verifyMagicLink(body) {
636
+ const path = "/v1/magic-link/verify";
637
+ return this.request(
638
+ "POST",
639
+ path,
640
+ body
641
+ );
555
642
  }
556
643
  /**
557
- * Clear all tokens
644
+ * Get current user
645
+ * GET /v1/me
646
+ */
647
+ async getMe(token) {
648
+ const path = "/v1/me";
649
+ return this.request(
650
+ "GET",
651
+ path,
652
+ void 0,
653
+ token
654
+ );
655
+ }
656
+ /**
657
+ * Update current user
658
+ * PATCH /v1/me
558
659
  */
559
- async clearTokens() {
560
- await this.removeToken();
561
- await this.removeRefreshToken();
660
+ async updateMe(body, token) {
661
+ const path = "/v1/me";
662
+ return this.request(
663
+ "PATCH",
664
+ path,
665
+ body,
666
+ token
667
+ );
562
668
  }
563
669
  /**
564
- * Check if token is expired
670
+ * Delete account
671
+ * DELETE /v1/me
565
672
  */
566
- isTokenExpired(token) {
567
- try {
568
- const payload = this.decodeToken(token);
569
- if (!payload.exp) return false;
570
- const expiresAt = payload.exp * 1e3;
571
- const now = Date.now();
572
- return expiresAt - now < 6e4;
573
- } catch {
574
- return true;
575
- }
673
+ async deleteMe(body, token) {
674
+ const path = "/v1/me";
675
+ return this.request(
676
+ "DELETE",
677
+ path,
678
+ body,
679
+ token
680
+ );
576
681
  }
577
682
  /**
578
- * Decode JWT token (without verification)
683
+ * List linked auth methods
684
+ * GET /v1/me/auth-methods
579
685
  */
580
- decodeToken(token) {
581
- const parts = token.split(".");
582
- if (parts.length !== 3) {
583
- throw new Error("Invalid token format");
584
- }
585
- const payload = parts[1];
586
- const decoded = atob(payload);
587
- return JSON.parse(decoded);
686
+ async listAuthMethods(token) {
687
+ const path = "/v1/me/auth-methods";
688
+ return this.request(
689
+ "GET",
690
+ path,
691
+ void 0,
692
+ token
693
+ );
588
694
  }
589
- };
590
-
591
- // src/utils/cookies.ts
592
- function parseCookie(setCookieHeader) {
593
- if (!setCookieHeader) return null;
594
- const parts = setCookieHeader.split(";").map((p) => p.trim());
595
- if (parts.length === 0) return null;
596
- const [nameValue] = parts;
597
- const [name, value] = nameValue.split("=");
598
- if (!name || value === void 0) return null;
599
- const cookieData = { name, value };
600
- const options = {};
601
- for (let i = 1; i < parts.length; i++) {
602
- const part = parts[i];
603
- const lowerPart = part.toLowerCase();
604
- if (lowerPart === "httponly") {
605
- options.httpOnly = true;
606
- } else if (lowerPart === "secure") {
607
- options.secure = true;
608
- } else if (lowerPart.startsWith("path=")) {
609
- options.path = part.substring(5);
610
- } else if (lowerPart.startsWith("domain=")) {
611
- options.domain = part.substring(7);
612
- } else if (lowerPart.startsWith("max-age=")) {
613
- const maxAge = parseInt(part.substring(8), 10);
614
- if (!isNaN(maxAge)) {
615
- options.maxAge = maxAge;
616
- }
617
- } else if (lowerPart.startsWith("expires=")) {
618
- const expiresStr = part.substring(8);
619
- const expiresDate = new Date(expiresStr);
620
- if (!isNaN(expiresDate.getTime())) {
621
- options.expires = expiresDate;
622
- }
623
- } else if (lowerPart.startsWith("samesite=")) {
624
- const sameSiteValue = lowerPart.substring(9);
625
- if (sameSiteValue === "strict" || sameSiteValue === "lax" || sameSiteValue === "none") {
626
- options.sameSite = sameSiteValue;
627
- }
628
- }
695
+ /**
696
+ * Unlink an auth method
697
+ * DELETE /v1/me/auth-methods/{provider}
698
+ */
699
+ async unlinkAuthMethod(provider, body, token) {
700
+ const path = `/v1/me/auth-methods/${provider}`;
701
+ return this.request(
702
+ "DELETE",
703
+ path,
704
+ body,
705
+ token
706
+ );
629
707
  }
630
- if (Object.keys(options).length > 0) {
631
- cookieData.options = options;
708
+ /**
709
+ * Export user data
710
+ * GET /v1/me/export
711
+ */
712
+ async exportMyData(token) {
713
+ const path = "/v1/me/export";
714
+ return this.request(
715
+ "GET",
716
+ path,
717
+ void 0,
718
+ token
719
+ );
632
720
  }
633
- return cookieData;
634
- }
635
- function extractCookiesFromHeaders(setCookieHeaders) {
636
- const headers = Array.isArray(setCookieHeaders) ? setCookieHeaders : [setCookieHeaders];
637
- const cookies = [];
638
- for (const header of headers) {
639
- const cookie = parseCookie(header);
640
- if (cookie) {
641
- cookies.push(cookie);
642
- }
721
+ /**
722
+ * MFA challenge
723
+ * POST /v1/mfa/challenge
724
+ */
725
+ async challengeMFA(body) {
726
+ const path = "/v1/mfa/challenge";
727
+ return this.request(
728
+ "POST",
729
+ path,
730
+ body
731
+ );
643
732
  }
644
- return cookies;
645
- }
646
- function serializeCookie(cookie) {
647
- const parts = [`${cookie.name}=${cookie.value}`];
648
- if (cookie.options) {
649
- const opts = cookie.options;
650
- if (opts.path) {
651
- parts.push(`Path=${opts.path}`);
652
- }
653
- if (opts.domain) {
654
- parts.push(`Domain=${opts.domain}`);
655
- }
656
- if (opts.expires) {
657
- parts.push(`Expires=${opts.expires.toUTCString()}`);
658
- }
659
- if (opts.maxAge !== void 0) {
660
- parts.push(`Max-Age=${opts.maxAge}`);
661
- }
662
- if (opts.httpOnly) {
663
- parts.push("HttpOnly");
664
- }
665
- if (opts.secure) {
666
- parts.push("Secure");
667
- }
668
- if (opts.sameSite) {
669
- const sameSite = opts.sameSite.charAt(0).toUpperCase() + opts.sameSite.slice(1);
670
- parts.push(`SameSite=${sameSite}`);
671
- }
733
+ /**
734
+ * Enroll in MFA
735
+ * POST /v1/mfa/enroll
736
+ */
737
+ async enrollMFA(body, token) {
738
+ const path = "/v1/mfa/enroll";
739
+ return this.request(
740
+ "POST",
741
+ path,
742
+ body,
743
+ token
744
+ );
672
745
  }
673
- return parts.join("; ");
674
- }
675
- function parseCookieOptions(cookieHeader) {
676
- const cookies = {};
677
- if (!cookieHeader) return cookies;
678
- const pairs = cookieHeader.split(";").map((p) => p.trim());
679
- for (const pair of pairs) {
680
- const [name, value] = pair.split("=");
681
- if (name && value !== void 0) {
682
- cookies[name.trim()] = value.trim();
683
- }
746
+ /**
747
+ * Disable MFA
748
+ * DELETE /v1/mfa/enrollment
749
+ */
750
+ async disableMFA(body, token) {
751
+ const path = "/v1/mfa/enrollment";
752
+ return this.request(
753
+ "DELETE",
754
+ path,
755
+ body,
756
+ token
757
+ );
684
758
  }
685
- return cookies;
686
- }
687
- function serializeCookies(cookies) {
688
- return Object.entries(cookies).map(([key, value]) => `${key}=${value}`).join("; ");
689
- }
690
-
691
- // src/adapters/base-provider.ts
692
- var BaseAuthProvider = class {
693
- constructor() {
694
- this.config = {};
695
- this.initialized = false;
759
+ /**
760
+ * Regenerate MFA recovery codes
761
+ * POST /v1/mfa/recovery/regenerate
762
+ */
763
+ async regenerateMFARecoveryCodes(body, token) {
764
+ const path = "/v1/mfa/recovery/regenerate";
765
+ return this.request(
766
+ "POST",
767
+ path,
768
+ body,
769
+ token
770
+ );
696
771
  }
697
772
  /**
698
- * Initialize the provider
773
+ * Verify MFA recovery code
774
+ * POST /v1/mfa/recovery/verify
699
775
  */
700
- async initialize(config) {
701
- this.config = config;
702
- this.initialized = true;
776
+ async verifyRecoveryCode(body) {
777
+ const path = "/v1/mfa/recovery/verify";
778
+ return this.request(
779
+ "POST",
780
+ path,
781
+ body
782
+ );
703
783
  }
704
784
  /**
705
- * Ensure provider is initialized
785
+ * Send SMS verification code
786
+ * POST /v1/mfa/sms/send
706
787
  */
707
- ensureInitialized() {
708
- if (!this.initialized) {
709
- throw new Error(`Provider ${this.name} is not initialized`);
710
- }
788
+ async sendSMSCode(body, token) {
789
+ const path = "/v1/mfa/sms/send";
790
+ return this.request(
791
+ "POST",
792
+ path,
793
+ body,
794
+ token
795
+ );
711
796
  }
712
797
  /**
713
- * Make HTTP request
798
+ * Verify SMS code
799
+ * POST /v1/mfa/sms/verify
714
800
  */
715
- async request(url, options = {}) {
716
- const response = await fetch(url, {
717
- ...options,
718
- headers: {
719
- "Content-Type": "application/json",
720
- ...options.headers
721
- }
722
- });
723
- if (!response.ok) {
724
- const error = await response.json().catch(() => ({
725
- message: response.statusText
726
- }));
727
- throw error;
728
- }
729
- return response.json();
801
+ async verifySMSCode(body, token) {
802
+ const path = "/v1/mfa/sms/verify";
803
+ return this.request(
804
+ "POST",
805
+ path,
806
+ body,
807
+ token
808
+ );
730
809
  }
731
810
  /**
732
- * Normalize error to AuthError
811
+ * Verify MFA code
812
+ * POST /v1/mfa/verify
733
813
  */
734
- normalizeError(error) {
735
- return toAuthError(error);
814
+ async verifyMFA(body) {
815
+ const path = "/v1/mfa/verify";
816
+ return this.request(
817
+ "POST",
818
+ path,
819
+ body
820
+ );
736
821
  }
737
- };
738
-
739
- // src/client.ts
740
- var AuthClient = class {
741
- // Expose adapter for accessing provider-specific methods
742
- get adapter() {
743
- return this.provider;
822
+ /**
823
+ * List organizations
824
+ * GET /v1/orgs
825
+ */
826
+ async listOrganizations(token) {
827
+ const path = "/v1/orgs";
828
+ return this.request(
829
+ "GET",
830
+ path,
831
+ void 0,
832
+ token
833
+ );
744
834
  }
745
- constructor(config) {
746
- this.provider = config.provider;
747
- this.autoRefresh = config.autoRefresh ?? true;
748
- this.refreshInterval = config.refreshInterval ?? 5 * 60 * 1e3;
749
- this.state = new Observable({
750
- state: "loading" /* LOADING */,
751
- user: null,
752
- session: null,
753
- error: null,
754
- isAuthenticated: false,
755
- isLoading: true
756
- });
835
+ /**
836
+ * Create organization
837
+ * POST /v1/orgs
838
+ */
839
+ async createOrganization(body, token) {
840
+ const path = "/v1/orgs";
841
+ return this.request(
842
+ "POST",
843
+ path,
844
+ body,
845
+ token
846
+ );
757
847
  }
758
848
  /**
759
- * Initialize the auth client
849
+ * Check slug availability
850
+ * GET /v1/orgs/check-slug
760
851
  */
761
- async initialize() {
762
- try {
763
- const user = await this.provider.getCurrentUser();
764
- const session = await this.provider.getCurrentSession();
765
- if (user && session) {
766
- this.updateState({
767
- state: "authenticated" /* AUTHENTICATED */,
768
- user,
769
- session,
770
- error: null,
771
- isAuthenticated: true,
772
- isLoading: false
773
- });
774
- if (this.autoRefresh) {
775
- this.startAutoRefresh();
776
- }
777
- } else {
778
- this.updateState({
779
- state: "unauthenticated" /* UNAUTHENTICATED */,
780
- user: null,
781
- session: null,
782
- error: null,
783
- isAuthenticated: false,
784
- isLoading: false
785
- });
786
- }
787
- } catch (error) {
788
- this.handleError(error);
789
- }
852
+ async checkOrgSlug(token) {
853
+ const path = "/v1/orgs/check-slug";
854
+ return this.request(
855
+ "GET",
856
+ path,
857
+ void 0,
858
+ token
859
+ );
790
860
  }
791
861
  /**
792
- * Sign in with credentials
862
+ * Accept invitation
863
+ * POST /v1/orgs/invitations/accept
793
864
  */
794
- async signIn(request) {
795
- try {
796
- this.setLoading();
797
- const response = await this.provider.signIn(request);
798
- if (response.requiresTwoFactor) {
799
- this.updateState({
800
- state: "unauthenticated" /* UNAUTHENTICATED */,
801
- user: response.user,
802
- session: null,
803
- error: null,
804
- isAuthenticated: false,
805
- isLoading: false
806
- });
807
- return;
808
- }
809
- this.updateState({
810
- state: "authenticated" /* AUTHENTICATED */,
811
- user: response.user,
812
- session: response.session,
813
- error: null,
814
- isAuthenticated: true,
815
- isLoading: false
816
- });
817
- if (this.autoRefresh) {
818
- this.startAutoRefresh();
819
- }
820
- } catch (error) {
821
- this.handleError(error);
822
- }
865
+ async acceptInvitation(body, token) {
866
+ const path = "/v1/orgs/invitations/accept";
867
+ return this.request(
868
+ "POST",
869
+ path,
870
+ body,
871
+ token
872
+ );
873
+ }
874
+ /**
875
+ * Decline invitation
876
+ * POST /v1/orgs/invitations/decline
877
+ */
878
+ async declineInvitation(body, token) {
879
+ const path = "/v1/orgs/invitations/decline";
880
+ return this.request(
881
+ "POST",
882
+ path,
883
+ body,
884
+ token
885
+ );
886
+ }
887
+ /**
888
+ * Get organization
889
+ * GET /v1/orgs/{orgId}
890
+ */
891
+ async getOrganization(orgId, token) {
892
+ const path = `/v1/orgs/${orgId}`;
893
+ return this.request(
894
+ "GET",
895
+ path,
896
+ void 0,
897
+ token
898
+ );
899
+ }
900
+ /**
901
+ * Update organization
902
+ * PATCH /v1/orgs/{orgId}
903
+ */
904
+ async updateOrganization(orgId, body, token) {
905
+ const path = `/v1/orgs/${orgId}`;
906
+ return this.request(
907
+ "PATCH",
908
+ path,
909
+ body,
910
+ token
911
+ );
912
+ }
913
+ /**
914
+ * Delete organization
915
+ * DELETE /v1/orgs/{orgId}
916
+ */
917
+ async deleteOrganization(orgId, body, token) {
918
+ const path = `/v1/orgs/${orgId}`;
919
+ return this.request(
920
+ "DELETE",
921
+ path,
922
+ body,
923
+ token
924
+ );
925
+ }
926
+ /**
927
+ * List invitations
928
+ * GET /v1/orgs/{orgId}/invitations
929
+ */
930
+ async listInvitations(orgId, token) {
931
+ const path = `/v1/orgs/${orgId}/invitations`;
932
+ return this.request(
933
+ "GET",
934
+ path,
935
+ void 0,
936
+ token
937
+ );
938
+ }
939
+ /**
940
+ * Create invitation
941
+ * POST /v1/orgs/{orgId}/invitations
942
+ */
943
+ async createInvitation(orgId, body, token) {
944
+ const path = `/v1/orgs/${orgId}/invitations`;
945
+ return this.request(
946
+ "POST",
947
+ path,
948
+ body,
949
+ token
950
+ );
951
+ }
952
+ /**
953
+ * List members
954
+ * GET /v1/orgs/{orgId}/members
955
+ */
956
+ async listMembers(orgId, token) {
957
+ const path = `/v1/orgs/${orgId}/members`;
958
+ return this.request(
959
+ "GET",
960
+ path,
961
+ void 0,
962
+ token
963
+ );
964
+ }
965
+ /**
966
+ * Add member
967
+ * POST /v1/orgs/{orgId}/members
968
+ */
969
+ async addMember(orgId, body, token) {
970
+ const path = `/v1/orgs/${orgId}/members`;
971
+ return this.request(
972
+ "POST",
973
+ path,
974
+ body,
975
+ token
976
+ );
977
+ }
978
+ /**
979
+ * Update member role
980
+ * PATCH /v1/orgs/{orgId}/members/{memberId}
981
+ */
982
+ async updateMember(orgId, memberId, body, token) {
983
+ const path = `/v1/orgs/${orgId}/members/${memberId}`;
984
+ return this.request(
985
+ "PATCH",
986
+ path,
987
+ body,
988
+ token
989
+ );
990
+ }
991
+ /**
992
+ * Remove member
993
+ * DELETE /v1/orgs/{orgId}/members/{memberId}
994
+ */
995
+ async removeMember(orgId, memberId, body, token) {
996
+ const path = `/v1/orgs/${orgId}/members/${memberId}`;
997
+ return this.request(
998
+ "DELETE",
999
+ path,
1000
+ body,
1001
+ token
1002
+ );
1003
+ }
1004
+ /**
1005
+ * List teams
1006
+ * GET /v1/orgs/{orgId}/teams
1007
+ */
1008
+ async listTeams(orgId, token) {
1009
+ const path = `/v1/orgs/${orgId}/teams`;
1010
+ return this.request(
1011
+ "GET",
1012
+ path,
1013
+ void 0,
1014
+ token
1015
+ );
1016
+ }
1017
+ /**
1018
+ * Create team
1019
+ * POST /v1/orgs/{orgId}/teams
1020
+ */
1021
+ async createTeam(orgId, body, token) {
1022
+ const path = `/v1/orgs/${orgId}/teams`;
1023
+ return this.request(
1024
+ "POST",
1025
+ path,
1026
+ body,
1027
+ token
1028
+ );
1029
+ }
1030
+ /**
1031
+ * Get team
1032
+ * GET /v1/orgs/{orgId}/teams/{teamId}
1033
+ */
1034
+ async getTeam(orgId, teamId, token) {
1035
+ const path = `/v1/orgs/${orgId}/teams/${teamId}`;
1036
+ return this.request(
1037
+ "GET",
1038
+ path,
1039
+ void 0,
1040
+ token
1041
+ );
1042
+ }
1043
+ /**
1044
+ * Update team
1045
+ * PATCH /v1/orgs/{orgId}/teams/{teamId}
1046
+ */
1047
+ async updateTeam(orgId, teamId, body, token) {
1048
+ const path = `/v1/orgs/${orgId}/teams/${teamId}`;
1049
+ return this.request(
1050
+ "PATCH",
1051
+ path,
1052
+ body,
1053
+ token
1054
+ );
823
1055
  }
824
1056
  /**
825
- * Sign up with credentials
1057
+ * Delete team
1058
+ * DELETE /v1/orgs/{orgId}/teams/{teamId}
826
1059
  */
827
- async signUp(request) {
828
- try {
829
- this.setLoading();
830
- const response = await this.provider.signUp(request);
831
- this.updateState({
832
- state: "authenticated" /* AUTHENTICATED */,
833
- user: response.user,
834
- session: response.session,
835
- error: null,
836
- isAuthenticated: true,
837
- isLoading: false
838
- });
839
- if (this.autoRefresh) {
840
- this.startAutoRefresh();
841
- }
842
- } catch (error) {
843
- this.handleError(error);
844
- }
1060
+ async deleteTeam(orgId, teamId, body, token) {
1061
+ const path = `/v1/orgs/${orgId}/teams/${teamId}`;
1062
+ return this.request(
1063
+ "DELETE",
1064
+ path,
1065
+ body,
1066
+ token
1067
+ );
845
1068
  }
846
1069
  /**
847
- * Sign out
848
- */
849
- async signOut() {
850
- try {
851
- this.stopAutoRefresh();
852
- await this.provider.signOut();
853
- this.updateState({
854
- state: "unauthenticated" /* UNAUTHENTICATED */,
855
- user: null,
856
- session: null,
857
- error: null,
858
- isAuthenticated: false,
859
- isLoading: false
860
- });
861
- } catch (error) {
862
- this.handleError(error);
863
- }
1070
+ * List passkeys
1071
+ * GET /v1/passkeys/
1072
+ */
1073
+ async listPasskeys(token) {
1074
+ const path = "/v1/passkeys/";
1075
+ return this.request(
1076
+ "GET",
1077
+ path,
1078
+ void 0,
1079
+ token
1080
+ );
864
1081
  }
865
1082
  /**
866
- * Update user profile
1083
+ * Begin passkey login
1084
+ * POST /v1/passkeys/login/begin
867
1085
  */
868
- async updateUser(request) {
869
- try {
870
- const user = await this.provider.updateUser(request);
871
- const currentState = this.state.getValue();
872
- this.updateState({
873
- ...currentState,
874
- user
875
- });
876
- } catch (error) {
877
- this.handleError(error);
878
- }
1086
+ async passkeyLoginBegin(body) {
1087
+ const path = "/v1/passkeys/login/begin";
1088
+ return this.request(
1089
+ "POST",
1090
+ path,
1091
+ body
1092
+ );
879
1093
  }
880
1094
  /**
881
- * Change password
1095
+ * Complete passkey login
1096
+ * POST /v1/passkeys/login/finish
882
1097
  */
883
- async changePassword(request) {
884
- try {
885
- await this.provider.changePassword(request);
886
- } catch (error) {
887
- throw this.provider.normalizeError(error);
888
- }
1098
+ async passkeyLoginFinish(body) {
1099
+ const path = "/v1/passkeys/login/finish";
1100
+ return this.request(
1101
+ "POST",
1102
+ path,
1103
+ body
1104
+ );
889
1105
  }
890
1106
  /**
891
- * Request password reset
1107
+ * Begin passkey registration
1108
+ * POST /v1/passkeys/register/begin
892
1109
  */
893
- async requestPasswordReset(request) {
894
- try {
895
- await this.provider.requestPasswordReset(request);
896
- } catch (error) {
897
- throw this.provider.normalizeError(error);
898
- }
1110
+ async passkeyRegisterBegin(body, token) {
1111
+ const path = "/v1/passkeys/register/begin";
1112
+ return this.request(
1113
+ "POST",
1114
+ path,
1115
+ body,
1116
+ token
1117
+ );
899
1118
  }
900
1119
  /**
901
- * Confirm password reset
1120
+ * Complete passkey registration
1121
+ * POST /v1/passkeys/register/finish
902
1122
  */
903
- async confirmPasswordReset(request) {
904
- try {
905
- await this.provider.confirmPasswordReset(request);
906
- } catch (error) {
907
- throw this.provider.normalizeError(error);
908
- }
1123
+ async passkeyRegisterFinish(body, token) {
1124
+ const path = "/v1/passkeys/register/finish";
1125
+ return this.request(
1126
+ "POST",
1127
+ path,
1128
+ body,
1129
+ token
1130
+ );
1131
+ }
1132
+ /**
1133
+ * Delete passkey
1134
+ * DELETE /v1/passkeys/{credentialId}
1135
+ */
1136
+ async deletePasskey(credentialId, body, token) {
1137
+ const path = `/v1/passkeys/${credentialId}`;
1138
+ return this.request(
1139
+ "DELETE",
1140
+ path,
1141
+ body,
1142
+ token
1143
+ );
909
1144
  }
910
1145
  /**
911
- * Get OAuth sign in URL
1146
+ * Refresh tokens
1147
+ * POST /v1/refresh
912
1148
  */
913
- async getOAuthUrl(request) {
914
- return this.provider.oauthSignIn(request);
1149
+ async refresh(body) {
1150
+ const path = "/v1/refresh";
1151
+ return this.request(
1152
+ "POST",
1153
+ path,
1154
+ body
1155
+ );
915
1156
  }
916
1157
  /**
917
- * Handle OAuth callback
1158
+ * Reset password
1159
+ * POST /v1/reset-password
918
1160
  */
919
- async handleOAuthCallback(request) {
920
- try {
921
- this.setLoading();
922
- const response = await this.provider.oauthCallback(request);
923
- this.updateState({
924
- state: "authenticated" /* AUTHENTICATED */,
925
- user: response.user,
926
- session: response.session,
927
- error: null,
928
- isAuthenticated: true,
929
- isLoading: false
930
- });
931
- if (this.autoRefresh) {
932
- this.startAutoRefresh();
933
- }
934
- } catch (error) {
935
- this.handleError(error);
936
- }
1161
+ async resetPassword(body) {
1162
+ const path = "/v1/reset-password";
1163
+ return this.request(
1164
+ "POST",
1165
+ path,
1166
+ body
1167
+ );
937
1168
  }
938
1169
  /**
939
- * Get available OAuth providers
1170
+ * List roles
1171
+ * GET /v1/roles
940
1172
  */
941
- async getOAuthProviders() {
942
- return this.provider.getOAuthProviders();
1173
+ async authsomeListRoles(token) {
1174
+ const path = "/v1/roles";
1175
+ return this.request(
1176
+ "GET",
1177
+ path,
1178
+ void 0,
1179
+ token
1180
+ );
943
1181
  }
944
1182
  /**
945
- * Send magic link
1183
+ * Create role
1184
+ * POST /v1/roles
946
1185
  */
947
- async sendMagicLink(request) {
948
- try {
949
- await this.provider.sendMagicLink(request);
950
- } catch (error) {
951
- throw this.provider.normalizeError(error);
952
- }
1186
+ async authsomeCreateRole(body, token) {
1187
+ const path = "/v1/roles";
1188
+ return this.request(
1189
+ "POST",
1190
+ path,
1191
+ body,
1192
+ token
1193
+ );
953
1194
  }
954
1195
  /**
955
- * Verify magic link
1196
+ * Get role
1197
+ * GET /v1/roles/{roleId}
956
1198
  */
957
- async verifyMagicLink(request) {
958
- try {
959
- this.setLoading();
960
- const response = await this.provider.verifyMagicLink(request);
961
- this.updateState({
962
- state: "authenticated" /* AUTHENTICATED */,
963
- user: response.user,
964
- session: response.session,
965
- error: null,
966
- isAuthenticated: true,
967
- isLoading: false
968
- });
969
- if (this.autoRefresh) {
970
- this.startAutoRefresh();
971
- }
972
- } catch (error) {
973
- this.handleError(error);
974
- }
1199
+ async authsomeGetRole(roleId, token) {
1200
+ const path = `/v1/roles/${roleId}`;
1201
+ return this.request(
1202
+ "GET",
1203
+ path,
1204
+ void 0,
1205
+ token
1206
+ );
975
1207
  }
976
1208
  /**
977
- * Send phone verification code
1209
+ * Update role
1210
+ * PATCH /v1/roles/{roleId}
978
1211
  */
979
- async sendPhoneCode(request) {
980
- try {
981
- await this.provider.sendPhoneCode(request);
982
- } catch (error) {
983
- throw this.provider.normalizeError(error);
984
- }
1212
+ async authsomeUpdateRole(roleId, body, token) {
1213
+ const path = `/v1/roles/${roleId}`;
1214
+ return this.request(
1215
+ "PATCH",
1216
+ path,
1217
+ body,
1218
+ token
1219
+ );
985
1220
  }
986
1221
  /**
987
- * Verify phone code
1222
+ * Delete role
1223
+ * DELETE /v1/roles/{roleId}
988
1224
  */
989
- async verifyPhoneCode(request) {
990
- try {
991
- this.setLoading();
992
- const response = await this.provider.verifyPhoneCode(request);
993
- this.updateState({
994
- state: "authenticated" /* AUTHENTICATED */,
995
- user: response.user,
996
- session: response.session,
997
- error: null,
998
- isAuthenticated: true,
999
- isLoading: false
1000
- });
1001
- if (this.autoRefresh) {
1002
- this.startAutoRefresh();
1003
- }
1004
- } catch (error) {
1005
- this.handleError(error);
1006
- }
1225
+ async authsomeDeleteRole(roleId, token) {
1226
+ const path = `/v1/roles/${roleId}`;
1227
+ return this.request(
1228
+ "DELETE",
1229
+ path,
1230
+ void 0,
1231
+ token
1232
+ );
1007
1233
  }
1008
1234
  /**
1009
- * Setup 2FA
1235
+ * Assign role to user
1236
+ * POST /v1/roles/{roleId}/assign
1010
1237
  */
1011
- async setupTwoFactor(request) {
1012
- return this.provider.setupTwoFactor(request);
1238
+ async authsomeAssignRole(roleId, body, token) {
1239
+ const path = `/v1/roles/${roleId}/assign`;
1240
+ return this.request(
1241
+ "POST",
1242
+ path,
1243
+ body,
1244
+ token
1245
+ );
1013
1246
  }
1014
1247
  /**
1015
- * Verify 2FA code
1248
+ * List role permissions
1249
+ * GET /v1/roles/{roleId}/permissions
1016
1250
  */
1017
- async verifyTwoFactor(request) {
1018
- try {
1019
- this.setLoading();
1020
- const response = await this.provider.verifyTwoFactor(request);
1021
- this.updateState({
1022
- state: "authenticated" /* AUTHENTICATED */,
1023
- user: response.user,
1024
- session: response.session,
1025
- error: null,
1026
- isAuthenticated: true,
1027
- isLoading: false
1028
- });
1029
- if (this.autoRefresh) {
1030
- this.startAutoRefresh();
1031
- }
1032
- } catch (error) {
1033
- this.handleError(error);
1034
- }
1251
+ async authsomeListRolePermissions(roleId, token) {
1252
+ const path = `/v1/roles/${roleId}/permissions`;
1253
+ return this.request(
1254
+ "GET",
1255
+ path,
1256
+ void 0,
1257
+ token
1258
+ );
1035
1259
  }
1036
1260
  /**
1037
- * Disable 2FA
1261
+ * Add permission to role
1262
+ * POST /v1/roles/{roleId}/permissions
1038
1263
  */
1039
- async disableTwoFactor() {
1040
- return this.provider.disableTwoFactor();
1264
+ async authsomeAddPermission(roleId, body, token) {
1265
+ const path = `/v1/roles/${roleId}/permissions`;
1266
+ return this.request(
1267
+ "POST",
1268
+ path,
1269
+ body,
1270
+ token
1271
+ );
1041
1272
  }
1042
1273
  /**
1043
- * Get 2FA status
1274
+ * Remove permission from role
1275
+ * DELETE /v1/roles/{roleId}/permissions/{permissionId}
1044
1276
  */
1045
- async getTwoFactorStatus() {
1046
- return this.provider.getTwoFactorStatus();
1277
+ async authsomeRemovePermission(roleId, permissionId, token) {
1278
+ const path = `/v1/roles/${roleId}/permissions/${permissionId}`;
1279
+ return this.request(
1280
+ "DELETE",
1281
+ path,
1282
+ void 0,
1283
+ token
1284
+ );
1047
1285
  }
1048
1286
  /**
1049
- * Register passkey
1287
+ * Unassign role from user
1288
+ * POST /v1/roles/{roleId}/unassign
1050
1289
  */
1051
- async registerPasskey(request) {
1052
- return this.provider.registerPasskey(request);
1290
+ async authsomeUnassignRole(roleId, body, token) {
1291
+ const path = `/v1/roles/${roleId}/unassign`;
1292
+ return this.request(
1293
+ "POST",
1294
+ path,
1295
+ body,
1296
+ token
1297
+ );
1053
1298
  }
1054
1299
  /**
1055
- * Authenticate with passkey
1300
+ * List sessions
1301
+ * GET /v1/sessions
1056
1302
  */
1057
- async authenticatePasskey(request) {
1058
- try {
1059
- this.setLoading();
1060
- const response = await this.provider.authenticatePasskey(request);
1061
- this.updateState({
1062
- state: "authenticated" /* AUTHENTICATED */,
1063
- user: response.user,
1064
- session: response.session,
1065
- error: null,
1066
- isAuthenticated: true,
1067
- isLoading: false
1068
- });
1069
- if (this.autoRefresh) {
1070
- this.startAutoRefresh();
1071
- }
1072
- } catch (error) {
1073
- this.handleError(error);
1074
- }
1303
+ async listSessions(token) {
1304
+ const path = "/v1/sessions";
1305
+ return this.request(
1306
+ "GET",
1307
+ path,
1308
+ void 0,
1309
+ token
1310
+ );
1075
1311
  }
1076
1312
  /**
1077
- * List passkeys
1313
+ * Revoke session
1314
+ * DELETE /v1/sessions/{sessionId}
1078
1315
  */
1079
- async listPasskeys() {
1080
- return this.provider.listPasskeys();
1316
+ async revokeSession(sessionId, body, token) {
1317
+ const path = `/v1/sessions/${sessionId}`;
1318
+ return this.request(
1319
+ "DELETE",
1320
+ path,
1321
+ body,
1322
+ token
1323
+ );
1081
1324
  }
1082
1325
  /**
1083
- * Delete passkey
1326
+ * Sign in
1327
+ * POST /v1/signin
1084
1328
  */
1085
- async deletePasskey(credentialId) {
1086
- return this.provider.deletePasskey(credentialId);
1329
+ async signIn(body) {
1330
+ const path = "/v1/signin";
1331
+ return this.request(
1332
+ "POST",
1333
+ path,
1334
+ body
1335
+ );
1336
+ }
1337
+ /**
1338
+ * Sign out
1339
+ * POST /v1/signout
1340
+ */
1341
+ async signOut(body, token) {
1342
+ const path = "/v1/signout";
1343
+ return this.request(
1344
+ "POST",
1345
+ path,
1346
+ body,
1347
+ token
1348
+ );
1087
1349
  }
1088
1350
  /**
1089
- * Get all organizations the user belongs to
1090
- * Only available if the provider supports organizations
1351
+ * Sign up
1352
+ * POST /v1/signup
1091
1353
  */
1092
- async getOrganizations() {
1093
- if (!this.provider.getOrganizations) {
1094
- throw this.createUnsupportedError("Organization support");
1095
- }
1096
- return this.provider.getOrganizations();
1354
+ async signUp(body) {
1355
+ const path = "/v1/signup";
1356
+ return this.request(
1357
+ "POST",
1358
+ path,
1359
+ body
1360
+ );
1097
1361
  }
1098
1362
  /**
1099
- * Get the currently active organization
1100
- * Only available if the provider supports organizations
1363
+ * Start OAuth flow
1364
+ * POST /v1/social/{provider}
1101
1365
  */
1102
- async getActiveOrganization() {
1103
- if (!this.provider.getActiveOrganization) {
1104
- throw this.createUnsupportedError("Organization support");
1105
- }
1106
- return this.provider.getActiveOrganization();
1366
+ async startOAuth(provider, body) {
1367
+ const path = `/v1/social/${provider}`;
1368
+ return this.request(
1369
+ "POST",
1370
+ path,
1371
+ body
1372
+ );
1107
1373
  }
1108
1374
  /**
1109
- * Set the active organization and refresh user state
1110
- * Only available if the provider supports organizations
1375
+ * OAuth callback
1376
+ * GET /v1/social/{provider}/callback
1111
1377
  */
1112
- async setActiveOrganization(organizationId) {
1113
- if (!this.provider.setActiveOrganization) {
1114
- throw this.createUnsupportedError("Organization support");
1115
- }
1116
- await this.provider.setActiveOrganization(organizationId);
1117
- await this.refreshSession();
1378
+ async oauthCallback(provider) {
1379
+ const path = `/v1/social/${provider}/callback`;
1380
+ return this.request(
1381
+ "GET",
1382
+ path,
1383
+ void 0
1384
+ );
1118
1385
  }
1119
1386
  /**
1120
- * Get organization memberships with roles and permissions
1121
- * Only available if the provider supports organizations
1387
+ * SSO SAML ACS endpoint
1388
+ * POST /v1/sso/{provider}/acs
1122
1389
  */
1123
- async getOrganizationMemberships() {
1124
- if (!this.provider.getOrganizationMemberships) {
1125
- throw this.createUnsupportedError("Organization memberships");
1126
- }
1127
- return this.provider.getOrganizationMemberships();
1390
+ async ssoACS(provider, body) {
1391
+ const path = `/v1/sso/${provider}/acs`;
1392
+ return this.request(
1393
+ "POST",
1394
+ path,
1395
+ body
1396
+ );
1128
1397
  }
1129
1398
  /**
1130
- * Check if the provider supports organizations
1399
+ * SSO callback (OIDC)
1400
+ * POST /v1/sso/{provider}/callback
1131
1401
  */
1132
- supportsOrganizations() {
1133
- return !!(this.provider.getOrganizations && this.provider.getActiveOrganization && this.provider.setActiveOrganization);
1402
+ async ssoCallback(provider, body) {
1403
+ const path = `/v1/sso/${provider}/callback`;
1404
+ return this.request(
1405
+ "POST",
1406
+ path,
1407
+ body
1408
+ );
1134
1409
  }
1135
1410
  /**
1136
- * Refresh session
1411
+ * Start SSO login flow
1412
+ * POST /v1/sso/{provider}/login
1137
1413
  */
1138
- async refreshSession() {
1139
- try {
1140
- const session = await this.provider.refreshSession();
1141
- const currentState = this.state.getValue();
1142
- this.updateState({
1143
- ...currentState,
1144
- session
1145
- });
1146
- } catch (error) {
1147
- console.warn("[AuthClient] Session refresh failed:", error);
1148
- }
1414
+ async startSSOLogin(provider, body) {
1415
+ const path = `/v1/sso/${provider}/login`;
1416
+ return this.request(
1417
+ "POST",
1418
+ path,
1419
+ body
1420
+ );
1149
1421
  }
1150
1422
  /**
1151
- * Get current user
1423
+ * List user roles
1424
+ * GET /v1/users/{userId}/roles
1152
1425
  */
1153
- getUser() {
1154
- return this.state.getValue().user;
1426
+ async authsomeListUserRoles(userId, token) {
1427
+ const path = `/v1/users/${userId}/roles`;
1428
+ return this.request(
1429
+ "GET",
1430
+ path,
1431
+ void 0,
1432
+ token
1433
+ );
1155
1434
  }
1156
1435
  /**
1157
- * Get current session
1436
+ * Verify email
1437
+ * POST /v1/verify-email
1158
1438
  */
1159
- getSession() {
1160
- return this.state.getValue().session;
1439
+ async verifyEmail(body) {
1440
+ const path = "/v1/verify-email";
1441
+ return this.request(
1442
+ "POST",
1443
+ path,
1444
+ body
1445
+ );
1161
1446
  }
1162
1447
  /**
1163
- * Check if authenticated
1448
+ * List webhooks
1449
+ * GET /v1/webhooks
1164
1450
  */
1165
- isAuthenticated() {
1166
- return this.state.getValue().isAuthenticated;
1451
+ async listWebhooks(token) {
1452
+ const path = "/v1/webhooks";
1453
+ return this.request(
1454
+ "GET",
1455
+ path,
1456
+ void 0,
1457
+ token
1458
+ );
1167
1459
  }
1168
1460
  /**
1169
- * Get current error
1461
+ * Create webhook
1462
+ * POST /v1/webhooks
1170
1463
  */
1171
- getError() {
1172
- return this.state.getValue().error;
1464
+ async createWebhook(body, token) {
1465
+ const path = "/v1/webhooks";
1466
+ return this.request(
1467
+ "POST",
1468
+ path,
1469
+ body,
1470
+ token
1471
+ );
1173
1472
  }
1174
1473
  /**
1175
- * Clear error
1474
+ * Get webhook
1475
+ * GET /v1/webhooks/{webhookId}
1176
1476
  */
1177
- clearError() {
1178
- const currentState = this.state.getValue();
1179
- this.updateState({
1180
- ...currentState,
1181
- error: null
1182
- });
1477
+ async getWebhook(webhookId, token) {
1478
+ const path = `/v1/webhooks/${webhookId}`;
1479
+ return this.request(
1480
+ "GET",
1481
+ path,
1482
+ void 0,
1483
+ token
1484
+ );
1183
1485
  }
1184
1486
  /**
1185
- * Subscribe to auth state changes
1487
+ * Update webhook
1488
+ * PATCH /v1/webhooks/{webhookId}
1186
1489
  */
1187
- subscribe(listener) {
1188
- return this.state.subscribe(listener);
1490
+ async updateWebhook(webhookId, body, token) {
1491
+ const path = `/v1/webhooks/${webhookId}`;
1492
+ return this.request(
1493
+ "PATCH",
1494
+ path,
1495
+ body,
1496
+ token
1497
+ );
1189
1498
  }
1190
1499
  /**
1191
- * Cleanup resources
1500
+ * Delete webhook
1501
+ * DELETE /v1/webhooks/{webhookId}
1192
1502
  */
1193
- destroy() {
1194
- this.stopAutoRefresh();
1195
- this.state.clearListeners();
1196
- }
1197
- // Private methods
1198
- updateState(newState) {
1199
- this.state.setValue(newState);
1200
- }
1201
- setLoading() {
1202
- const currentState = this.state.getValue();
1203
- this.updateState({
1204
- ...currentState,
1205
- state: "loading" /* LOADING */,
1206
- isLoading: true,
1207
- error: null
1208
- });
1503
+ async deleteWebhook(webhookId, body, token) {
1504
+ const path = `/v1/webhooks/${webhookId}`;
1505
+ return this.request(
1506
+ "DELETE",
1507
+ path,
1508
+ body,
1509
+ token
1510
+ );
1209
1511
  }
1210
- handleError(error) {
1211
- const authError = this.provider.normalizeError(error);
1212
- const currentState = this.state.getValue();
1213
- this.updateState({
1214
- ...currentState,
1215
- state: "error" /* ERROR */,
1216
- error: authError,
1217
- isLoading: false
1512
+ // ──────────────────────────────────────────────────
1513
+ // Internal request helper
1514
+ // ──────────────────────────────────────────────────
1515
+ async request(method, path, body, token) {
1516
+ const headers = {
1517
+ "Content-Type": "application/json",
1518
+ "Accept": "application/json"
1519
+ };
1520
+ if (token) {
1521
+ headers["Authorization"] = `Bearer ${token}`;
1522
+ }
1523
+ const response = await this.fetchFn(`${this.baseURL}${path}`, {
1524
+ method,
1525
+ headers,
1526
+ body: body !== void 0 ? JSON.stringify(body) : void 0
1218
1527
  });
1219
- throw authError;
1220
- }
1221
- startAutoRefresh() {
1222
- this.stopAutoRefresh();
1223
- this.refreshTimer = setInterval(() => {
1224
- this.refreshSession();
1225
- }, this.refreshInterval);
1226
- }
1227
- stopAutoRefresh() {
1228
- if (this.refreshTimer) {
1229
- clearInterval(this.refreshTimer);
1230
- this.refreshTimer = void 0;
1528
+ if (!response.ok) {
1529
+ let apiError;
1530
+ try {
1531
+ apiError = await response.json();
1532
+ } catch {
1533
+ }
1534
+ throw new AuthClientError(
1535
+ apiError?.error ?? `Request failed with status ${response.status}`,
1536
+ apiError?.code ?? response.status
1537
+ );
1538
+ }
1539
+ if (response.status === 204) {
1540
+ return void 0;
1231
1541
  }
1542
+ return response.json();
1232
1543
  }
1233
- createUnsupportedError(feature) {
1234
- return {
1235
- name: "AuthError",
1236
- message: `${feature} is not available with this auth provider`,
1237
- type: "unknown_error" /* UNKNOWN_ERROR */
1238
- };
1544
+ };
1545
+ var AuthClientError = class extends Error {
1546
+ code;
1547
+ constructor(message, code) {
1548
+ super(message);
1549
+ this.name = "AuthClientError";
1550
+ this.code = code;
1239
1551
  }
1240
1552
  };
1241
1553
 
1242
- // src/flows/types.ts
1243
- var FlowStep = /* @__PURE__ */ ((FlowStep2) => {
1244
- FlowStep2["SIGN_IN"] = "sign_in";
1245
- FlowStep2["SIGN_UP"] = "sign_up";
1246
- FlowStep2["EMAIL_PASSWORD_SIGN_IN"] = "email_password_sign_in";
1247
- FlowStep2["EMAIL_PASSWORD_SIGN_UP"] = "email_password_sign_up";
1248
- FlowStep2["OAUTH_SELECT"] = "oauth_select";
1249
- FlowStep2["OAUTH_CALLBACK"] = "oauth_callback";
1250
- FlowStep2["MAGIC_LINK_REQUEST"] = "magic_link_request";
1251
- FlowStep2["MAGIC_LINK_VERIFY"] = "magic_link_verify";
1252
- FlowStep2["MAGIC_LINK_SENT"] = "magic_link_sent";
1253
- FlowStep2["PHONE_REQUEST"] = "phone_request";
1254
- FlowStep2["PHONE_VERIFY"] = "phone_verify";
1255
- FlowStep2["USERNAME_SIGN_IN"] = "username_sign_in";
1256
- FlowStep2["USERNAME_SIGN_UP"] = "username_sign_up";
1257
- FlowStep2["PASSKEY_REGISTER"] = "passkey_register";
1258
- FlowStep2["PASSKEY_AUTHENTICATE"] = "passkey_authenticate";
1259
- FlowStep2["MFA_REQUIRED"] = "mfa_required";
1260
- FlowStep2["MFA_SETUP"] = "mfa_setup";
1261
- FlowStep2["MFA_VERIFY"] = "mfa_verify";
1262
- FlowStep2["MFA_SELECT_METHOD"] = "mfa_select_method";
1263
- FlowStep2["EMAIL_VERIFICATION_REQUIRED"] = "email_verification_required";
1264
- FlowStep2["EMAIL_VERIFICATION_SENT"] = "email_verification_sent";
1265
- FlowStep2["PHONE_VERIFICATION_REQUIRED"] = "phone_verification_required";
1266
- FlowStep2["PASSWORD_RESET_REQUEST"] = "password_reset_request";
1267
- FlowStep2["PASSWORD_RESET_SENT"] = "password_reset_sent";
1268
- FlowStep2["PASSWORD_RESET_CONFIRM"] = "password_reset_confirm";
1269
- FlowStep2["PASSWORD_CHANGE"] = "password_change";
1270
- FlowStep2["PROFILE_UPDATE"] = "profile_update";
1271
- FlowStep2["PROFILE_COMPLETE"] = "profile_complete";
1272
- FlowStep2["DEVICE_FLOW_INITIATE"] = "device_flow_initiate";
1273
- FlowStep2["DEVICE_CODE_ENTRY"] = "device_code_entry";
1274
- FlowStep2["DEVICE_CODE_VERIFY"] = "device_code_verify";
1275
- FlowStep2["DEVICE_AUTHORIZE"] = "device_authorize";
1276
- FlowStep2["DEVICE_POLLING"] = "device_polling";
1277
- FlowStep2["DEVICE_AUTHORIZED"] = "device_authorized";
1278
- FlowStep2["DEVICE_DENIED"] = "device_denied";
1279
- FlowStep2["SUCCESS"] = "success";
1280
- FlowStep2["ERROR"] = "error";
1281
- FlowStep2["CANCELLED"] = "cancelled";
1282
- return FlowStep2;
1283
- })(FlowStep || {});
1284
- var FlowConfigType = /* @__PURE__ */ ((FlowConfigType2) => {
1285
- FlowConfigType2["SIMPLE_SIGN_IN"] = "simple_sign_in";
1286
- FlowConfigType2["SIMPLE_SIGN_UP"] = "simple_sign_up";
1287
- FlowConfigType2["SIGN_UP_WITH_EMAIL_VERIFICATION"] = "sign_up_with_email_verification";
1288
- FlowConfigType2["SIGN_IN_WITH_MFA"] = "sign_in_with_mfa";
1289
- FlowConfigType2["OAUTH_SIGN_IN"] = "oauth_sign_in";
1290
- FlowConfigType2["MAGIC_LINK_FLOW"] = "magic_link_flow";
1291
- FlowConfigType2["PHONE_AUTH_FLOW"] = "phone_auth_flow";
1292
- FlowConfigType2["COMPLETE_SIGN_UP_FLOW"] = "complete_sign_up_flow";
1293
- FlowConfigType2["SECURE_SIGN_IN_FLOW"] = "secure_sign_in_flow";
1294
- FlowConfigType2["PASSWORD_RESET_FLOW"] = "password_reset_flow";
1295
- FlowConfigType2["EMAIL_VERIFICATION_FLOW"] = "email_verification_flow";
1296
- FlowConfigType2["DEVICE_FLOW"] = "device_flow";
1297
- FlowConfigType2["CUSTOM"] = "custom";
1298
- return FlowConfigType2;
1299
- })(FlowConfigType || {});
1300
- var FlowAction = /* @__PURE__ */ ((FlowAction2) => {
1301
- FlowAction2["START"] = "start";
1302
- FlowAction2["NEXT"] = "next";
1303
- FlowAction2["BACK"] = "back";
1304
- FlowAction2["CANCEL"] = "cancel";
1305
- FlowAction2["ERROR"] = "error";
1306
- FlowAction2["RESET"] = "reset";
1307
- return FlowAction2;
1308
- })(FlowAction || {});
1309
-
1310
- // src/flows/engine.ts
1311
- var FlowEngine = class {
1312
- constructor(config, initialState) {
1313
- this.history = [];
1314
- this.config = config;
1315
- this.state = {
1316
- currentStep: config.initialStep,
1317
- ...initialState
1318
- };
1319
- this.history.push(this.state.currentStep);
1554
+ // src/client.ts
1555
+ var AuthClient2 = class extends AuthClient {
1556
+ /**
1557
+ * Refresh session tokens.
1558
+ *
1559
+ * Accepts a raw refresh-token string (used by auth.ts) or the full
1560
+ * RefreshRequest body.
1561
+ */
1562
+ async refresh(body) {
1563
+ const req = typeof body === "string" ? { refresh_token: body } : body;
1564
+ return super.refresh(req);
1320
1565
  }
1321
1566
  /**
1322
- * Get current flow state
1567
+ * Sign out.
1568
+ *
1569
+ * Accepts a raw token string (used by auth.ts) or the full
1570
+ * (body, token) pair from the generated client.
1323
1571
  */
1324
- getState() {
1325
- return { ...this.state };
1572
+ async signOut(bodyOrToken, token) {
1573
+ if (typeof bodyOrToken === "string") {
1574
+ return super.signOut({}, bodyOrToken);
1575
+ }
1576
+ return super.signOut(bodyOrToken, token);
1326
1577
  }
1327
1578
  /**
1328
- * Get current step
1579
+ * MFA challenge — bridge for auth.ts.
1580
+ *
1581
+ * auth.ts calls `mfaChallenge({ enrollment_id, code })` and expects
1582
+ * an AuthResponse back. The generated client uses `challengeMFA`.
1329
1583
  */
1330
- getCurrentStep() {
1331
- return this.state.currentStep;
1584
+ async mfaChallenge(body) {
1585
+ return super.challengeMFA(body);
1332
1586
  }
1333
1587
  /**
1334
- * Check if step is allowed in this flow
1588
+ * Verify an MFA recovery code.
1589
+ *
1590
+ * Accepts a raw code string (used by auth.ts) or the full request body.
1335
1591
  */
1336
- isStepAllowed(step) {
1337
- return this.config.allowedSteps.includes(step);
1592
+ async verifyRecoveryCode(body) {
1593
+ const req = typeof body === "string" ? { code: body } : body;
1594
+ return super.verifyRecoveryCode(req);
1338
1595
  }
1339
1596
  /**
1340
- * Transition to next step based on action
1597
+ * Send an SMS code for MFA — bridge for auth.ts.
1598
+ *
1599
+ * Simplifies the call-site by accepting just the session token.
1341
1600
  */
1342
- async transition(event) {
1343
- const { action, data, error } = event;
1344
- switch (action) {
1345
- case "start":
1346
- return this.handleStart(data);
1347
- case "next":
1348
- return this.handleNext(data);
1349
- case "back":
1350
- return this.handleBack();
1351
- case "cancel":
1352
- return this.handleCancel();
1353
- case "error":
1354
- return this.handleError(error);
1355
- case "reset":
1356
- return this.handleReset();
1357
- default:
1358
- throw new AuthError(
1359
- `Unknown flow action: ${action}`,
1360
- "validation_error" /* VALIDATION_ERROR */
1361
- );
1362
- }
1601
+ async sendSMSCodeForMFA(token) {
1602
+ return super.sendSMSCode({}, token);
1363
1603
  }
1364
1604
  /**
1365
- * Start or restart the flow
1605
+ * Verify an SMS code for MFA — bridge for auth.ts.
1606
+ *
1607
+ * Simplifies the call-site by accepting code + token directly.
1366
1608
  */
1367
- handleStart(data) {
1368
- this.state = {
1369
- currentStep: this.config.initialStep,
1370
- ...data
1371
- };
1372
- this.history = [this.state.currentStep];
1373
- if (this.config.onStepChange) {
1374
- this.config.onStepChange(this.state.currentStep, this.state);
1375
- }
1376
- return this.getState();
1609
+ async verifySMSCodeForMFA(code, token) {
1610
+ return super.verifySMSCode({ code }, token);
1377
1611
  }
1378
1612
  /**
1379
- * Move to next step
1613
+ * Fetch the client configuration from the backend.
1614
+ *
1615
+ * The config describes which auth methods are enabled so SDK
1616
+ * components can auto-configure without manual props.
1380
1617
  */
1381
- handleNext(data) {
1382
- this.state = {
1383
- ...this.state,
1384
- ...data,
1385
- previousStep: this.state.currentStep
1386
- };
1387
- const transitionConfig = this.config.transitions[this.state.currentStep];
1388
- if (!transitionConfig) {
1389
- throw new AuthError(
1390
- `No transition configured for step: ${this.state.currentStep}`,
1391
- "validation_error" /* VALIDATION_ERROR */
1392
- );
1618
+ async fetchClientConfig(publishableKey) {
1619
+ const url = new URL("/v1/client-config", this.config.baseURL);
1620
+ if (publishableKey) {
1621
+ url.searchParams.set("key", publishableKey);
1393
1622
  }
1394
- if (transitionConfig.conditions) {
1395
- for (const condition of transitionConfig.conditions) {
1396
- if (condition.when(this.state)) {
1397
- return this.moveToStep(condition.then);
1398
- }
1399
- }
1623
+ const fetchFn = this.config.fetch ?? globalThis.fetch;
1624
+ const res = await fetchFn(url.toString(), {
1625
+ method: "GET",
1626
+ headers: { "Content-Type": "application/json" }
1627
+ });
1628
+ if (!res.ok) {
1629
+ throw new AuthClientError("Failed to fetch client config", res.status);
1630
+ }
1631
+ return res.json();
1632
+ }
1633
+ };
1634
+
1635
+ // src/auth.ts
1636
+ var SESSION_KEY = "authsome:session";
1637
+ var CONFIG_KEY = "authsome:client_config";
1638
+ var REFRESH_BEFORE_MS = 6e4;
1639
+ var CONFIG_TTL_MS = 5 * 6e4;
1640
+ var memoryStorage = /* @__PURE__ */ (() => {
1641
+ const store = /* @__PURE__ */ new Map();
1642
+ return {
1643
+ getItem: (key) => store.get(key) ?? null,
1644
+ setItem: (key, value) => {
1645
+ store.set(key, value);
1646
+ },
1647
+ removeItem: (key) => {
1648
+ store.delete(key);
1400
1649
  }
1401
- if (transitionConfig.onSuccess) {
1402
- return this.moveToStep(transitionConfig.onSuccess);
1650
+ };
1651
+ })();
1652
+ function defaultStorage() {
1653
+ try {
1654
+ if (typeof window !== "undefined" && window.localStorage) {
1655
+ return window.localStorage;
1403
1656
  }
1404
- throw new AuthError(
1405
- `No valid transition found for step: ${this.state.currentStep}`,
1406
- "validation_error" /* VALIDATION_ERROR */
1407
- );
1657
+ } catch {
1408
1658
  }
1409
- /**
1410
- * Go back to previous step
1411
- */
1412
- handleBack() {
1413
- if (this.history.length < 2) {
1414
- throw new AuthError(
1415
- "Cannot go back - already at first step",
1416
- "validation_error" /* VALIDATION_ERROR */
1417
- );
1659
+ return memoryStorage;
1660
+ }
1661
+ var AuthManager = class {
1662
+ client;
1663
+ storage;
1664
+ state = { status: "idle" };
1665
+ listeners = /* @__PURE__ */ new Set();
1666
+ refreshTimer = null;
1667
+ onError;
1668
+ publishableKey;
1669
+ clientConfig = null;
1670
+ configListeners = /* @__PURE__ */ new Set();
1671
+ configFetchPromise = null;
1672
+ constructor(config) {
1673
+ this.client = new AuthClient2(config);
1674
+ this.storage = config.storage ?? defaultStorage();
1675
+ this.onError = config.onError;
1676
+ this.publishableKey = config.publishableKey;
1677
+ if (config.initialClientConfig) {
1678
+ this.clientConfig = config.initialClientConfig;
1679
+ }
1680
+ if (config.onStateChange) {
1681
+ this.listeners.add(config.onStateChange);
1418
1682
  }
1419
- this.history.pop();
1420
- const previousStep = this.history[this.history.length - 1];
1421
- const transitionConfig = this.config.transitions[this.state.currentStep];
1422
- const targetStep = transitionConfig?.onBack || previousStep;
1423
- return this.moveToStep(targetStep, false);
1683
+ }
1684
+ // ── Public API ────────────────────────────────────
1685
+ /** Current auth state (snapshot). */
1686
+ getState() {
1687
+ return this.state;
1688
+ }
1689
+ /** Subscribe to state changes. Returns an unsubscribe function. */
1690
+ subscribe(listener) {
1691
+ this.listeners.add(listener);
1692
+ return () => {
1693
+ this.listeners.delete(listener);
1694
+ };
1695
+ }
1696
+ /** Access the underlying HTTP client. */
1697
+ getClient() {
1698
+ return this.client;
1424
1699
  }
1425
1700
  /**
1426
- * Cancel the flow
1701
+ * Initialize by hydrating the session from storage.
1702
+ * When a publishableKey is set, also fetches client config in parallel.
1703
+ * Call this once on app start.
1427
1704
  */
1428
- handleCancel() {
1429
- const transitionConfig = this.config.transitions[this.state.currentStep];
1430
- const targetStep = transitionConfig?.onCancel;
1431
- if (this.config.onCancel) {
1432
- this.config.onCancel(this.state);
1705
+ async initialize() {
1706
+ if (this.publishableKey && !this.clientConfig) {
1707
+ void this.fetchClientConfig();
1433
1708
  }
1434
- if (targetStep) {
1435
- return this.moveToStep(targetStep);
1709
+ try {
1710
+ const raw = await this.storage.getItem(SESSION_KEY);
1711
+ if (!raw) {
1712
+ this.setState({ status: "unauthenticated" });
1713
+ return;
1714
+ }
1715
+ const session = JSON.parse(raw);
1716
+ const expiresAt = new Date(session.expires_at).getTime();
1717
+ if (Date.now() >= expiresAt) {
1718
+ await this.refreshSession(session.refresh_token);
1719
+ return;
1720
+ }
1721
+ this.setState({ status: "loading" });
1722
+ const user = await this.client.getMe(session.session_token);
1723
+ this.setState({ status: "authenticated", user, session });
1724
+ this.scheduleRefresh(session);
1725
+ } catch {
1726
+ await this.clearSession();
1727
+ this.setState({ status: "unauthenticated" });
1436
1728
  }
1437
- this.state.currentStep = "cancelled";
1438
- return this.getState();
1439
1729
  }
1440
- /**
1441
- * Handle error in flow
1442
- */
1443
- handleError(error) {
1444
- this.state.error = error;
1445
- const transitionConfig = this.config.transitions[this.state.currentStep];
1446
- const targetStep = transitionConfig?.onError;
1447
- if (this.config.onError) {
1448
- this.config.onError(error, this.state);
1730
+ /** Sign in with email & password. */
1731
+ async signIn(credentials) {
1732
+ this.setState({ status: "loading" });
1733
+ try {
1734
+ const res = await this.client.signIn(credentials);
1735
+ const session = {
1736
+ session_token: res.session_token,
1737
+ refresh_token: res.refresh_token,
1738
+ expires_at: new Date(Date.now() + 36e5).toISOString()
1739
+ // fallback
1740
+ };
1741
+ await this.handleAuthResponse(res.user, session);
1742
+ } catch (err) {
1743
+ this.handleError(err);
1744
+ throw err;
1449
1745
  }
1450
- if (targetStep) {
1451
- return this.moveToStep(targetStep);
1746
+ }
1747
+ /** Sign up with email & password. */
1748
+ async signUp(data) {
1749
+ this.setState({ status: "loading" });
1750
+ try {
1751
+ const res = await this.client.signUp(data);
1752
+ const session = {
1753
+ session_token: res.session_token,
1754
+ refresh_token: res.refresh_token,
1755
+ expires_at: new Date(Date.now() + 36e5).toISOString()
1756
+ };
1757
+ await this.handleAuthResponse(res.user, session);
1758
+ } catch (err) {
1759
+ this.handleError(err);
1760
+ throw err;
1452
1761
  }
1453
- return this.getState();
1454
1762
  }
1455
- /**
1456
- * Reset flow to initial state
1457
- */
1458
- handleReset() {
1459
- return this.handleStart();
1763
+ /** Sign out and clear the session. */
1764
+ async signOut() {
1765
+ const token = this.getSessionToken();
1766
+ if (token) {
1767
+ try {
1768
+ await this.client.signOut(token);
1769
+ } catch {
1770
+ }
1771
+ }
1772
+ this.clearRefreshTimer();
1773
+ await this.clearSession();
1774
+ this.setState({ status: "unauthenticated" });
1460
1775
  }
1461
- /**
1462
- * Move to a specific step
1463
- */
1464
- moveToStep(step, addToHistory = true) {
1465
- if (!this.isStepAllowed(step)) {
1466
- throw new AuthError(
1467
- `Step ${step} is not allowed in this flow`,
1468
- "validation_error" /* VALIDATION_ERROR */
1469
- );
1776
+ /** Submit an MFA challenge code. */
1777
+ async submitMFACode(enrollmentId, code) {
1778
+ this.setState({ status: "loading" });
1779
+ try {
1780
+ const res = await this.client.mfaChallenge({ enrollment_id: enrollmentId, code });
1781
+ const session = {
1782
+ session_token: res.session_token,
1783
+ refresh_token: res.refresh_token,
1784
+ expires_at: new Date(Date.now() + 36e5).toISOString()
1785
+ };
1786
+ await this.handleAuthResponse(res.user, session);
1787
+ } catch (err) {
1788
+ this.handleError(err);
1470
1789
  }
1471
- this.state.currentStep = step;
1472
- if (addToHistory) {
1473
- this.history.push(step);
1790
+ }
1791
+ /** Submit an MFA recovery code. */
1792
+ async submitRecoveryCode(code) {
1793
+ this.setState({ status: "loading" });
1794
+ try {
1795
+ const res = await this.client.verifyRecoveryCode(code);
1796
+ const session = {
1797
+ session_token: res.session_token,
1798
+ refresh_token: res.refresh_token,
1799
+ expires_at: new Date(Date.now() + 36e5).toISOString()
1800
+ };
1801
+ await this.handleAuthResponse(res.user, session);
1802
+ } catch (err) {
1803
+ this.handleError(err);
1804
+ }
1805
+ }
1806
+ /** Send an SMS code for MFA verification. Returns masked phone + expiry info. */
1807
+ async sendSMSCode() {
1808
+ const token = this.getSessionToken();
1809
+ if (!token) throw new Error("No session token available");
1810
+ return this.client.sendSMSCodeForMFA(token);
1811
+ }
1812
+ /** Submit an SMS verification code during MFA challenge. */
1813
+ async submitSMSCode(code) {
1814
+ this.setState({ status: "loading" });
1815
+ try {
1816
+ const token = this.getSessionToken();
1817
+ if (!token) throw new Error("No session token available");
1818
+ const res = await this.client.verifySMSCodeForMFA(code, token);
1819
+ const session = {
1820
+ session_token: res.session_token,
1821
+ refresh_token: res.refresh_token,
1822
+ expires_at: new Date(Date.now() + 36e5).toISOString()
1823
+ };
1824
+ await this.handleAuthResponse(res.user, session);
1825
+ } catch (err) {
1826
+ this.handleError(err);
1474
1827
  }
1475
- if (this.config.onStepChange) {
1476
- this.config.onStepChange(step, this.state);
1828
+ }
1829
+ /** Refresh the current session manually. */
1830
+ async refreshNow() {
1831
+ const state = this.state;
1832
+ if (state.status !== "authenticated") return;
1833
+ await this.refreshSession(state.session.refresh_token);
1834
+ }
1835
+ /** Get the current session token (if authenticated). */
1836
+ getSessionToken() {
1837
+ if (this.state.status === "authenticated") {
1838
+ return this.state.session.session_token;
1477
1839
  }
1478
- if (step === "success" && this.state.user && this.state.session) {
1479
- if (this.config.onComplete) {
1480
- this.config.onComplete(this.state.user, this.state.session);
1481
- }
1840
+ if (this.state.status === "mfa_required") {
1841
+ return this.state.session.session_token;
1482
1842
  }
1483
- return this.getState();
1843
+ return null;
1484
1844
  }
1485
- /**
1486
- * Get flow history
1487
- */
1488
- getHistory() {
1489
- return [...this.history];
1845
+ /** Get the current user (if authenticated). */
1846
+ getUser() {
1847
+ if (this.state.status === "authenticated") {
1848
+ return this.state.user;
1849
+ }
1850
+ return null;
1851
+ }
1852
+ // ── Client Config API ────────────────────────────
1853
+ /** Get the cached client config (or null if not yet fetched). */
1854
+ getClientConfig() {
1855
+ return this.clientConfig;
1856
+ }
1857
+ /** Subscribe to client config changes. Returns an unsubscribe function. */
1858
+ subscribeConfig(listener) {
1859
+ this.configListeners.add(listener);
1860
+ return () => {
1861
+ this.configListeners.delete(listener);
1862
+ };
1490
1863
  }
1491
1864
  /**
1492
- * Check if can go back
1865
+ * Fetch client config from the backend.
1866
+ * Deduplicates concurrent calls and caches the result with a TTL.
1493
1867
  */
1494
- canGoBack() {
1495
- return this.history.length > 1;
1496
- }
1497
- };
1498
-
1499
- // src/flows/configs.ts
1500
- var simpleSignInFlow = {
1501
- name: "Simple Sign In",
1502
- description: "Basic email/password sign-in",
1503
- initialStep: "email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */,
1504
- allowedSteps: [
1505
- "email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */,
1506
- "email_verification_required" /* EMAIL_VERIFICATION_REQUIRED */,
1507
- "email_verification_sent" /* EMAIL_VERIFICATION_SENT */,
1508
- "password_reset_request" /* PASSWORD_RESET_REQUEST */,
1509
- "password_reset_sent" /* PASSWORD_RESET_SENT */,
1510
- "success" /* SUCCESS */,
1511
- "error" /* ERROR */
1512
- ],
1513
- transitions: {
1514
- ["email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */]: {
1515
- onSuccess: "success" /* SUCCESS */,
1516
- onError: "email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */
1517
- },
1518
- ["email_verification_required" /* EMAIL_VERIFICATION_REQUIRED */]: {
1519
- onSuccess: "email_verification_sent" /* EMAIL_VERIFICATION_SENT */,
1520
- onError: "email_verification_required" /* EMAIL_VERIFICATION_REQUIRED */
1521
- },
1522
- ["email_verification_sent" /* EMAIL_VERIFICATION_SENT */]: {
1523
- onSuccess: "email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */,
1524
- onError: "email_verification_required" /* EMAIL_VERIFICATION_REQUIRED */
1525
- },
1526
- ["password_reset_request" /* PASSWORD_RESET_REQUEST */]: {
1527
- onSuccess: "password_reset_sent" /* PASSWORD_RESET_SENT */,
1528
- onBack: "email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */
1529
- },
1530
- ["password_reset_sent" /* PASSWORD_RESET_SENT */]: {
1531
- onSuccess: "email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */
1868
+ async fetchClientConfig() {
1869
+ if (this.configFetchPromise) {
1870
+ return this.configFetchPromise;
1532
1871
  }
1533
- }
1534
- };
1535
- var signInWithMFAFlow = {
1536
- name: "Sign In with MFA",
1537
- description: "Sign-in that handles MFA if enabled",
1538
- initialStep: "email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */,
1539
- allowedSteps: [
1540
- "email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */,
1541
- "email_verification_required" /* EMAIL_VERIFICATION_REQUIRED */,
1542
- "email_verification_sent" /* EMAIL_VERIFICATION_SENT */,
1543
- "mfa_required" /* MFA_REQUIRED */,
1544
- "mfa_select_method" /* MFA_SELECT_METHOD */,
1545
- "mfa_verify" /* MFA_VERIFY */,
1546
- "password_reset_request" /* PASSWORD_RESET_REQUEST */,
1547
- "password_reset_sent" /* PASSWORD_RESET_SENT */,
1548
- "success" /* SUCCESS */,
1549
- "error" /* ERROR */
1550
- ],
1551
- transitions: {
1552
- ["email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */]: {
1553
- onSuccess: "success" /* SUCCESS */,
1554
- onError: "email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */,
1555
- conditions: [
1556
- {
1557
- when: (state) => state.mfaRequired === true,
1558
- then: "mfa_required" /* MFA_REQUIRED */
1559
- }
1560
- ]
1561
- },
1562
- ["email_verification_required" /* EMAIL_VERIFICATION_REQUIRED */]: {
1563
- onSuccess: "email_verification_sent" /* EMAIL_VERIFICATION_SENT */,
1564
- onError: "email_verification_required" /* EMAIL_VERIFICATION_REQUIRED */
1565
- },
1566
- ["email_verification_sent" /* EMAIL_VERIFICATION_SENT */]: {
1567
- onSuccess: "email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */,
1568
- onError: "email_verification_required" /* EMAIL_VERIFICATION_REQUIRED */
1569
- },
1570
- ["mfa_required" /* MFA_REQUIRED */]: {
1571
- onSuccess: "mfa_verify" /* MFA_VERIFY */,
1572
- conditions: [
1573
- {
1574
- when: (state) => (state.mfaMethods?.length || 0) > 1,
1575
- then: "mfa_select_method" /* MFA_SELECT_METHOD */
1872
+ try {
1873
+ const cached = await this.storage.getItem(CONFIG_KEY);
1874
+ if (cached) {
1875
+ const { config, fetchedAt } = JSON.parse(cached);
1876
+ if (Date.now() - fetchedAt < CONFIG_TTL_MS) {
1877
+ this.setClientConfig(config);
1878
+ return config;
1576
1879
  }
1577
- ]
1578
- },
1579
- ["mfa_select_method" /* MFA_SELECT_METHOD */]: {
1580
- onSuccess: "mfa_verify" /* MFA_VERIFY */,
1581
- onBack: "email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */
1582
- },
1583
- ["mfa_verify" /* MFA_VERIFY */]: {
1584
- onSuccess: "success" /* SUCCESS */,
1585
- onError: "mfa_verify" /* MFA_VERIFY */,
1586
- onBack: "mfa_select_method" /* MFA_SELECT_METHOD */
1587
- },
1588
- ["password_reset_request" /* PASSWORD_RESET_REQUEST */]: {
1589
- onSuccess: "password_reset_sent" /* PASSWORD_RESET_SENT */,
1590
- onBack: "email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */
1880
+ }
1881
+ } catch {
1591
1882
  }
1883
+ this.configFetchPromise = this.client.fetchClientConfig(this.publishableKey).then(async (config) => {
1884
+ this.setClientConfig(config);
1885
+ try {
1886
+ await this.storage.setItem(
1887
+ CONFIG_KEY,
1888
+ JSON.stringify({ config, fetchedAt: Date.now() })
1889
+ );
1890
+ } catch {
1891
+ }
1892
+ return config;
1893
+ }).finally(() => {
1894
+ this.configFetchPromise = null;
1895
+ });
1896
+ return this.configFetchPromise;
1592
1897
  }
1593
- };
1594
- var completeSignUpFlow = {
1595
- name: "Complete Sign Up",
1596
- description: "Sign-up with email verification and profile completion",
1597
- initialStep: "email_password_sign_up" /* EMAIL_PASSWORD_SIGN_UP */,
1598
- allowedSteps: [
1599
- "email_password_sign_up" /* EMAIL_PASSWORD_SIGN_UP */,
1600
- "email_verification_required" /* EMAIL_VERIFICATION_REQUIRED */,
1601
- "email_verification_sent" /* EMAIL_VERIFICATION_SENT */,
1602
- "profile_complete" /* PROFILE_COMPLETE */,
1603
- "success" /* SUCCESS */,
1604
- "error" /* ERROR */
1605
- ],
1606
- transitions: {
1607
- ["email_password_sign_up" /* EMAIL_PASSWORD_SIGN_UP */]: {
1608
- onSuccess: "email_verification_required" /* EMAIL_VERIFICATION_REQUIRED */,
1609
- onError: "email_password_sign_up" /* EMAIL_PASSWORD_SIGN_UP */,
1610
- conditions: [
1611
- {
1612
- when: (state) => state.verificationRequired === false,
1613
- then: "profile_complete" /* PROFILE_COMPLETE */
1614
- }
1615
- ]
1616
- },
1617
- ["email_verification_required" /* EMAIL_VERIFICATION_REQUIRED */]: {
1618
- onSuccess: "email_verification_sent" /* EMAIL_VERIFICATION_SENT */
1619
- },
1620
- ["email_verification_sent" /* EMAIL_VERIFICATION_SENT */]: {
1621
- onSuccess: "profile_complete" /* PROFILE_COMPLETE */
1622
- },
1623
- ["profile_complete" /* PROFILE_COMPLETE */]: {
1624
- onSuccess: "success" /* SUCCESS */,
1625
- onError: "profile_complete" /* PROFILE_COMPLETE */
1898
+ /** Tear down: clear timers and listeners. */
1899
+ destroy() {
1900
+ this.clearRefreshTimer();
1901
+ this.listeners.clear();
1902
+ this.configListeners.clear();
1903
+ }
1904
+ // ── Internals ─────────────────────────────────────
1905
+ async handleAuthResponse(user, session) {
1906
+ await this.persistSession(session);
1907
+ this.setState({ status: "authenticated", user, session });
1908
+ this.scheduleRefresh(session);
1909
+ }
1910
+ async refreshSession(refreshToken) {
1911
+ try {
1912
+ const newSession = await this.client.refresh(refreshToken);
1913
+ const user = await this.client.getMe(newSession.session_token);
1914
+ await this.persistSession(newSession);
1915
+ this.setState({ status: "authenticated", user, session: newSession });
1916
+ this.scheduleRefresh(newSession);
1917
+ } catch {
1918
+ await this.clearSession();
1919
+ this.setState({ status: "unauthenticated" });
1626
1920
  }
1627
1921
  }
1628
- };
1629
- var magicLinkFlow = {
1630
- name: "Magic Link",
1631
- description: "Passwordless authentication via email",
1632
- initialStep: "magic_link_request" /* MAGIC_LINK_REQUEST */,
1633
- allowedSteps: [
1634
- "magic_link_request" /* MAGIC_LINK_REQUEST */,
1635
- "magic_link_sent" /* MAGIC_LINK_SENT */,
1636
- "magic_link_verify" /* MAGIC_LINK_VERIFY */,
1637
- "success" /* SUCCESS */,
1638
- "error" /* ERROR */
1639
- ],
1640
- transitions: {
1641
- ["magic_link_request" /* MAGIC_LINK_REQUEST */]: {
1642
- onSuccess: "magic_link_sent" /* MAGIC_LINK_SENT */,
1643
- onError: "magic_link_request" /* MAGIC_LINK_REQUEST */
1644
- },
1645
- ["magic_link_sent" /* MAGIC_LINK_SENT */]: {
1646
- onSuccess: "magic_link_verify" /* MAGIC_LINK_VERIFY */
1647
- },
1648
- ["magic_link_verify" /* MAGIC_LINK_VERIFY */]: {
1649
- onSuccess: "success" /* SUCCESS */,
1650
- onError: "magic_link_request" /* MAGIC_LINK_REQUEST */
1922
+ scheduleRefresh(session) {
1923
+ this.clearRefreshTimer();
1924
+ const expiresAt = new Date(session.expires_at).getTime();
1925
+ const delay = expiresAt - Date.now() - REFRESH_BEFORE_MS;
1926
+ if (delay <= 0) {
1927
+ void this.refreshSession(session.refresh_token);
1928
+ return;
1929
+ }
1930
+ this.refreshTimer = setTimeout(() => {
1931
+ void this.refreshSession(session.refresh_token);
1932
+ }, delay);
1933
+ }
1934
+ clearRefreshTimer() {
1935
+ if (this.refreshTimer !== null) {
1936
+ clearTimeout(this.refreshTimer);
1937
+ this.refreshTimer = null;
1651
1938
  }
1652
1939
  }
1653
- };
1654
- var phoneAuthFlow = {
1655
- name: "Phone Authentication",
1656
- description: "SMS-based authentication",
1657
- initialStep: "phone_request" /* PHONE_REQUEST */,
1658
- allowedSteps: [
1659
- "phone_request" /* PHONE_REQUEST */,
1660
- "phone_verify" /* PHONE_VERIFY */,
1661
- "success" /* SUCCESS */,
1662
- "error" /* ERROR */
1663
- ],
1664
- transitions: {
1665
- ["phone_request" /* PHONE_REQUEST */]: {
1666
- onSuccess: "phone_verify" /* PHONE_VERIFY */,
1667
- onError: "phone_request" /* PHONE_REQUEST */
1668
- },
1669
- ["phone_verify" /* PHONE_VERIFY */]: {
1670
- onSuccess: "success" /* SUCCESS */,
1671
- onError: "phone_verify" /* PHONE_VERIFY */,
1672
- onBack: "phone_request" /* PHONE_REQUEST */
1940
+ async persistSession(session) {
1941
+ await this.storage.setItem(SESSION_KEY, JSON.stringify(session));
1942
+ }
1943
+ async clearSession() {
1944
+ await this.storage.removeItem(SESSION_KEY);
1945
+ }
1946
+ setClientConfig(config) {
1947
+ this.clientConfig = config;
1948
+ for (const listener of this.configListeners) {
1949
+ try {
1950
+ listener(config);
1951
+ } catch {
1952
+ }
1673
1953
  }
1674
1954
  }
1675
- };
1676
- var oauthSignInFlow = {
1677
- name: "OAuth Sign In",
1678
- description: "Third-party OAuth authentication",
1679
- initialStep: "oauth_select" /* OAUTH_SELECT */,
1680
- allowedSteps: [
1681
- "oauth_select" /* OAUTH_SELECT */,
1682
- "oauth_callback" /* OAUTH_CALLBACK */,
1683
- "success" /* SUCCESS */,
1684
- "error" /* ERROR */
1685
- ],
1686
- transitions: {
1687
- ["oauth_select" /* OAUTH_SELECT */]: {
1688
- onSuccess: "oauth_callback" /* OAUTH_CALLBACK */,
1689
- onError: "oauth_select" /* OAUTH_SELECT */
1690
- },
1691
- ["oauth_callback" /* OAUTH_CALLBACK */]: {
1692
- onSuccess: "success" /* SUCCESS */,
1693
- onError: "oauth_select" /* OAUTH_SELECT */
1955
+ setState(newState) {
1956
+ this.state = newState;
1957
+ for (const listener of this.listeners) {
1958
+ try {
1959
+ listener(newState);
1960
+ } catch {
1961
+ }
1694
1962
  }
1695
1963
  }
1696
- };
1697
- var passwordResetFlow = {
1698
- name: "Password Reset",
1699
- description: "Reset forgotten password",
1700
- initialStep: "password_reset_request" /* PASSWORD_RESET_REQUEST */,
1701
- allowedSteps: [
1702
- "password_reset_request" /* PASSWORD_RESET_REQUEST */,
1703
- "password_reset_sent" /* PASSWORD_RESET_SENT */,
1704
- "password_reset_confirm" /* PASSWORD_RESET_CONFIRM */,
1705
- "success" /* SUCCESS */,
1706
- "error" /* ERROR */
1707
- ],
1708
- transitions: {
1709
- ["password_reset_request" /* PASSWORD_RESET_REQUEST */]: {
1710
- onSuccess: "password_reset_sent" /* PASSWORD_RESET_SENT */,
1711
- onError: "password_reset_request" /* PASSWORD_RESET_REQUEST */
1712
- },
1713
- ["password_reset_sent" /* PASSWORD_RESET_SENT */]: {
1714
- onSuccess: "password_reset_confirm" /* PASSWORD_RESET_CONFIRM */
1715
- },
1716
- ["password_reset_confirm" /* PASSWORD_RESET_CONFIRM */]: {
1717
- onSuccess: "success" /* SUCCESS */,
1718
- onError: "password_reset_confirm" /* PASSWORD_RESET_CONFIRM */
1964
+ handleError(err) {
1965
+ const message = err instanceof AuthClientError ? err.message : "An unexpected error occurred";
1966
+ const code = err instanceof AuthClientError ? err.code : void 0;
1967
+ if (code === 403 && message.toLowerCase().includes("mfa")) {
1968
+ const token = this.getSessionToken();
1969
+ if (token) {
1970
+ this.setState({
1971
+ status: "mfa_required",
1972
+ session: {
1973
+ session_token: token,
1974
+ refresh_token: "",
1975
+ expires_at: new Date(Date.now() + 3e5).toISOString()
1976
+ }
1977
+ });
1978
+ return;
1979
+ }
1719
1980
  }
1981
+ this.setState({ status: "error", error: message });
1982
+ this.onError?.({ error: message, code });
1720
1983
  }
1721
1984
  };
1722
- var emailVerificationFlow = {
1723
- name: "Email Verification",
1724
- description: "Verify email address with code or link",
1725
- initialStep: "email_verification_required" /* EMAIL_VERIFICATION_REQUIRED */,
1726
- allowedSteps: [
1727
- "email_verification_required" /* EMAIL_VERIFICATION_REQUIRED */,
1728
- "email_verification_sent" /* EMAIL_VERIFICATION_SENT */,
1729
- "success" /* SUCCESS */,
1730
- "error" /* ERROR */
1731
- ],
1732
- transitions: {
1733
- ["email_verification_required" /* EMAIL_VERIFICATION_REQUIRED */]: {
1734
- onSuccess: "email_verification_sent" /* EMAIL_VERIFICATION_SENT */,
1735
- onError: "email_verification_required" /* EMAIL_VERIFICATION_REQUIRED */
1736
- },
1737
- ["email_verification_sent" /* EMAIL_VERIFICATION_SENT */]: {
1738
- onSuccess: "success" /* SUCCESS */,
1739
- onError: "email_verification_required" /* EMAIL_VERIFICATION_REQUIRED */
1985
+
1986
+ // src/webauthn.ts
1987
+ function base64urlToBuffer(base64url) {
1988
+ const base64 = base64url.replace(/-/g, "+").replace(/_/g, "/");
1989
+ const padded = base64 + "=".repeat((4 - base64.length % 4) % 4);
1990
+ const binary = atob(padded);
1991
+ const bytes = new Uint8Array(binary.length);
1992
+ for (let i = 0; i < binary.length; i++) {
1993
+ bytes[i] = binary.charCodeAt(i);
1994
+ }
1995
+ return bytes;
1996
+ }
1997
+ function bufferToBase64url(buffer) {
1998
+ const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);
1999
+ let binary = "";
2000
+ for (let i = 0; i < bytes.byteLength; i++) {
2001
+ binary += String.fromCharCode(bytes[i]);
2002
+ }
2003
+ return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
2004
+ }
2005
+ function prepareCreationOptions(options) {
2006
+ const publicKey = options.publicKey ?? options;
2007
+ const out = { ...publicKey };
2008
+ if (typeof out.challenge === "string") {
2009
+ out.challenge = base64urlToBuffer(out.challenge);
2010
+ }
2011
+ if (out.user && typeof out.user === "object") {
2012
+ const user = { ...out.user };
2013
+ if (typeof user.id === "string") {
2014
+ user.id = base64urlToBuffer(user.id);
1740
2015
  }
2016
+ out.user = user;
1741
2017
  }
1742
- };
1743
- var deviceFlow = {
1744
- name: "Device Flow",
1745
- description: "OAuth 2.0 Device Authorization Grant for CLI/device login",
1746
- initialStep: "device_code_entry" /* DEVICE_CODE_ENTRY */,
1747
- allowedSteps: [
1748
- "device_code_entry" /* DEVICE_CODE_ENTRY */,
1749
- "device_code_verify" /* DEVICE_CODE_VERIFY */,
1750
- "device_authorize" /* DEVICE_AUTHORIZE */,
1751
- "device_authorized" /* DEVICE_AUTHORIZED */,
1752
- "device_denied" /* DEVICE_DENIED */,
1753
- "success" /* SUCCESS */,
1754
- "error" /* ERROR */
1755
- ],
1756
- transitions: {
1757
- ["device_code_entry" /* DEVICE_CODE_ENTRY */]: {
1758
- onSuccess: "device_code_verify" /* DEVICE_CODE_VERIFY */,
1759
- onError: "device_code_entry" /* DEVICE_CODE_ENTRY */,
1760
- onCancel: "cancelled" /* CANCELLED */
1761
- },
1762
- ["device_code_verify" /* DEVICE_CODE_VERIFY */]: {
1763
- onSuccess: "device_authorize" /* DEVICE_AUTHORIZE */,
1764
- onError: "device_code_entry" /* DEVICE_CODE_ENTRY */,
1765
- onBack: "device_code_entry" /* DEVICE_CODE_ENTRY */
1766
- },
1767
- ["device_authorize" /* DEVICE_AUTHORIZE */]: {
1768
- onSuccess: "device_authorized" /* DEVICE_AUTHORIZED */,
1769
- onError: "device_denied" /* DEVICE_DENIED */,
1770
- onCancel: "device_denied" /* DEVICE_DENIED */
1771
- },
1772
- ["device_authorized" /* DEVICE_AUTHORIZED */]: {
1773
- onSuccess: "success" /* SUCCESS */
1774
- },
1775
- ["device_denied" /* DEVICE_DENIED */]: {
1776
- onSuccess: "error" /* ERROR */
2018
+ if (Array.isArray(out.excludeCredentials)) {
2019
+ out.excludeCredentials = out.excludeCredentials.map((c) => {
2020
+ if (typeof c.id === "string") {
2021
+ return { ...c, id: base64urlToBuffer(c.id) };
2022
+ }
2023
+ return c;
2024
+ });
2025
+ }
2026
+ return out;
2027
+ }
2028
+ function prepareRequestOptions(options) {
2029
+ const publicKey = options.publicKey ?? options;
2030
+ const out = { ...publicKey };
2031
+ if (typeof out.challenge === "string") {
2032
+ out.challenge = base64urlToBuffer(out.challenge);
2033
+ }
2034
+ if (Array.isArray(out.allowCredentials)) {
2035
+ out.allowCredentials = out.allowCredentials.map((c) => {
2036
+ if (typeof c.id === "string") {
2037
+ return { ...c, id: base64urlToBuffer(c.id) };
2038
+ }
2039
+ return c;
2040
+ });
2041
+ }
2042
+ return out;
2043
+ }
2044
+ function serializeCredential(credential) {
2045
+ const cred = credential;
2046
+ const response = cred.response;
2047
+ const result = {
2048
+ id: cred.id,
2049
+ rawId: bufferToBase64url(cred.rawId),
2050
+ type: cred.type,
2051
+ response: {}
2052
+ };
2053
+ const serializedResponse = {
2054
+ clientDataJSON: bufferToBase64url(response.clientDataJSON)
2055
+ };
2056
+ if ("attestationObject" in response) {
2057
+ const attestation = response;
2058
+ serializedResponse.attestationObject = bufferToBase64url(
2059
+ attestation.attestationObject
2060
+ );
2061
+ }
2062
+ if ("authenticatorData" in response) {
2063
+ const assertion = response;
2064
+ serializedResponse.authenticatorData = bufferToBase64url(
2065
+ assertion.authenticatorData
2066
+ );
2067
+ serializedResponse.signature = bufferToBase64url(assertion.signature);
2068
+ if (assertion.userHandle) {
2069
+ serializedResponse.userHandle = bufferToBase64url(assertion.userHandle);
1777
2070
  }
1778
2071
  }
1779
- };
1780
- function getFlowConfig(type) {
1781
- switch (type) {
1782
- case "simple_sign_in" /* SIMPLE_SIGN_IN */:
1783
- return simpleSignInFlow;
1784
- case "sign_in_with_mfa" /* SIGN_IN_WITH_MFA */:
1785
- return signInWithMFAFlow;
1786
- case "complete_sign_up_flow" /* COMPLETE_SIGN_UP_FLOW */:
1787
- return completeSignUpFlow;
1788
- case "magic_link_flow" /* MAGIC_LINK_FLOW */:
1789
- return magicLinkFlow;
1790
- case "phone_auth_flow" /* PHONE_AUTH_FLOW */:
1791
- return phoneAuthFlow;
1792
- case "oauth_sign_in" /* OAUTH_SIGN_IN */:
1793
- return oauthSignInFlow;
1794
- case "password_reset_flow" /* PASSWORD_RESET_FLOW */:
1795
- return passwordResetFlow;
1796
- case "email_verification_flow" /* EMAIL_VERIFICATION_FLOW */:
1797
- return emailVerificationFlow;
1798
- case "device_flow" /* DEVICE_FLOW */:
1799
- return deviceFlow;
1800
- default:
1801
- throw new Error(`Unknown flow type: ${type}`);
2072
+ result.response = serializedResponse;
2073
+ if (cred.authenticatorAttachment) {
2074
+ result.authenticatorAttachment = cred.authenticatorAttachment;
1802
2075
  }
2076
+ return result;
1803
2077
  }
1804
- var predefinedFlows = {
1805
- ["simple_sign_in" /* SIMPLE_SIGN_IN */]: simpleSignInFlow,
1806
- ["sign_in_with_mfa" /* SIGN_IN_WITH_MFA */]: signInWithMFAFlow,
1807
- ["complete_sign_up_flow" /* COMPLETE_SIGN_UP_FLOW */]: completeSignUpFlow,
1808
- ["magic_link_flow" /* MAGIC_LINK_FLOW */]: magicLinkFlow,
1809
- ["phone_auth_flow" /* PHONE_AUTH_FLOW */]: phoneAuthFlow,
1810
- ["oauth_sign_in" /* OAUTH_SIGN_IN */]: oauthSignInFlow,
1811
- ["password_reset_flow" /* PASSWORD_RESET_FLOW */]: passwordResetFlow,
1812
- ["email_verification_flow" /* EMAIL_VERIFICATION_FLOW */]: emailVerificationFlow,
1813
- ["device_flow" /* DEVICE_FLOW */]: deviceFlow
2078
+ export {
2079
+ AuthClient2 as AuthClient,
2080
+ AuthClientError,
2081
+ AuthManager,
2082
+ base64urlToBuffer,
2083
+ bufferToBase64url,
2084
+ prepareCreationOptions,
2085
+ prepareRequestOptions,
2086
+ serializeCredential
1814
2087
  };
1815
-
1816
- exports.AuthClient = AuthClient;
1817
- exports.AuthError = AuthError;
1818
- exports.AuthErrorType = AuthErrorType;
1819
- exports.AuthState = AuthState;
1820
- exports.BaseAuthProvider = BaseAuthProvider;
1821
- exports.FlowAction = FlowAction;
1822
- exports.FlowConfigType = FlowConfigType;
1823
- exports.FlowEngine = FlowEngine;
1824
- exports.FlowStep = FlowStep;
1825
- exports.LocalStorageAdapter = LocalStorageAdapter;
1826
- exports.MemoryStorageAdapter = MemoryStorageAdapter;
1827
- exports.OAuthProvider = OAuthProvider;
1828
- exports.Observable = Observable;
1829
- exports.SessionStorageAdapter = SessionStorageAdapter;
1830
- exports.TokenManager = TokenManager;
1831
- exports.TwoFactorMethod = TwoFactorMethod;
1832
- exports.completeSignUpFlow = completeSignUpFlow;
1833
- exports.createAuthError = createAuthError;
1834
- exports.createLocale = createLocale;
1835
- exports.defaultLocale = defaultLocale;
1836
- exports.emailVerificationFlow = emailVerificationFlow;
1837
- exports.extractCookiesFromHeaders = extractCookiesFromHeaders;
1838
- exports.getFlowConfig = getFlowConfig;
1839
- exports.interpolate = interpolate;
1840
- exports.isAuthError = isAuthError;
1841
- exports.isMFARequiredError = isMFARequiredError;
1842
- exports.isNetworkError = isNetworkError;
1843
- exports.isUnauthenticatedError = isUnauthenticatedError;
1844
- exports.magicLinkFlow = magicLinkFlow;
1845
- exports.oauthSignInFlow = oauthSignInFlow;
1846
- exports.parseCookie = parseCookie;
1847
- exports.parseCookieOptions = parseCookieOptions;
1848
- exports.passwordResetFlow = passwordResetFlow;
1849
- exports.phoneAuthFlow = phoneAuthFlow;
1850
- exports.predefinedFlows = predefinedFlows;
1851
- exports.serializeCookie = serializeCookie;
1852
- exports.serializeCookies = serializeCookies;
1853
- exports.signInWithMFAFlow = signInWithMFAFlow;
1854
- exports.simpleSignInFlow = simpleSignInFlow;
1855
- exports.toAuthError = toAuthError;
1856
- exports.validate2FACode = validate2FACode;
1857
- exports.validateEmail = validateEmail;
1858
- exports.validatePassword = validatePassword;
1859
- exports.validatePhone = validatePhone;
1860
- exports.validateRequired = validateRequired;
1861
- exports.validateUsername = validateUsername;
1862
- //# sourceMappingURL=index.js.map
1863
2088
  //# sourceMappingURL=index.js.map