@djangocfg/api 2.1.599 → 2.1.600

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +2 -1
  2. package/dist/OAuthProvidersResponse-QZ566OYR.mjs +25 -0
  3. package/dist/OAuthProvidersResponse-QZ566OYR.mjs.map +1 -0
  4. package/dist/auth.cjs +526 -288
  5. package/dist/auth.cjs.map +1 -1
  6. package/dist/auth.d.cts +144 -31
  7. package/dist/auth.d.ts +144 -31
  8. package/dist/auth.mjs +409 -213
  9. package/dist/auth.mjs.map +1 -1
  10. package/dist/cfg_accounts_oauth_connections_response_200_AutoRef-N532BRPN.mjs +28 -0
  11. package/dist/cfg_accounts_oauth_connections_response_200_AutoRef-N532BRPN.mjs.map +1 -0
  12. package/dist/chunk-PCOSFQTH.mjs +10 -0
  13. package/dist/chunk-PCOSFQTH.mjs.map +1 -0
  14. package/dist/clients.cjs +34 -3
  15. package/dist/clients.cjs.map +1 -1
  16. package/dist/clients.d.cts +135 -14
  17. package/dist/clients.d.ts +135 -14
  18. package/dist/clients.mjs +34 -3
  19. package/dist/clients.mjs.map +1 -1
  20. package/dist/hooks.cjs +1 -0
  21. package/dist/hooks.cjs.map +1 -1
  22. package/dist/hooks.mjs +1 -0
  23. package/dist/hooks.mjs.map +1 -1
  24. package/dist/index.cjs +34 -3
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.cts +169 -17
  27. package/dist/index.d.ts +169 -17
  28. package/dist/index.mjs +34 -3
  29. package/dist/index.mjs.map +1 -1
  30. package/dist/storage.cjs +1 -0
  31. package/dist/storage.cjs.map +1 -1
  32. package/dist/storage.d.cts +1 -0
  33. package/dist/storage.d.ts +1 -0
  34. package/dist/storage.mjs +1 -0
  35. package/dist/storage.mjs.map +1 -1
  36. package/package.json +2 -2
  37. package/src/__tests__/noStorageLiterals.test.ts +1 -1
  38. package/src/_api/generated/_cfg_accounts/hooks/index.ts +2 -0
  39. package/src/_api/generated/_cfg_accounts/hooks/useCfgAccountsOauthGoogleAuthorizeCreate.ts +68 -0
  40. package/src/_api/generated/_cfg_accounts/hooks/useCfgAccountsOauthGoogleCallbackCreate.ts +68 -0
  41. package/src/_api/generated/_cfg_accounts/openapi.json +263 -19
  42. package/src/_api/generated/_cfg_accounts/schemas/OAuthCallbackRequestRequest.ts +2 -2
  43. package/src/_api/generated/_cfg_accounts/schemas/OAuthError.ts +2 -1
  44. package/src/_api/generated/_cfg_accounts/schemas/OAuthErrorCodeEnum.ts +9 -0
  45. package/src/_api/generated/_cfg_accounts/schemas/OAuthProviderEnum.ts +1 -1
  46. package/src/_api/generated/_cfg_accounts/schemas/OAuthProviderInfo.ts +14 -0
  47. package/src/_api/generated/_cfg_accounts/schemas/OAuthProvidersResponse.ts +2 -1
  48. package/src/_api/generated/_cfg_accounts/schemas/index.ts +2 -0
  49. package/src/_api/generated/helpers/keys.ts +1 -0
  50. package/src/_api/generated/openapi.json +263 -19
  51. package/src/_api/generated/sdk.gen.ts +36 -4
  52. package/src/_api/generated/types.gen.ts +136 -11
  53. package/src/auth/__tests__/oauthErrors.test.ts +23 -0
  54. package/src/auth/__tests__/passwordLogin.test.tsx +1 -0
  55. package/src/auth/__tests__/useOAuthLogin.test.tsx +387 -0
  56. package/src/auth/hooks/index.ts +12 -1
  57. package/src/auth/hooks/useGithubAuth.ts +15 -225
  58. package/src/auth/hooks/useOAuthLogin.ts +237 -0
  59. package/src/auth/hooks/useOAuthProviders.ts +76 -0
  60. package/src/auth/utils/index.ts +8 -0
  61. package/src/auth/utils/oauthErrors.ts +45 -0
package/dist/auth.cjs CHANGED
@@ -32,28 +32,70 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
32
32
  ));
33
33
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
34
34
 
35
+ // src/_api/generated/_cfg_accounts/schemas/OAuthProviderEnum.ts
36
+ var import_zod, OAuthProviderEnumSchema;
37
+ var init_OAuthProviderEnum = __esm({
38
+ "src/_api/generated/_cfg_accounts/schemas/OAuthProviderEnum.ts"() {
39
+ "use strict";
40
+ import_zod = require("zod");
41
+ OAuthProviderEnumSchema = import_zod.z.enum(["github", "google"]);
42
+ }
43
+ });
44
+
45
+ // src/_api/generated/_cfg_accounts/schemas/OAuthProviderInfo.ts
46
+ var import_zod2, OAuthProviderInfoSchema;
47
+ var init_OAuthProviderInfo = __esm({
48
+ "src/_api/generated/_cfg_accounts/schemas/OAuthProviderInfo.ts"() {
49
+ "use strict";
50
+ import_zod2 = require("zod");
51
+ init_OAuthProviderEnum();
52
+ OAuthProviderInfoSchema = import_zod2.z.object({
53
+ id: OAuthProviderEnumSchema,
54
+ name: import_zod2.z.string(),
55
+ icon: import_zod2.z.string()
56
+ });
57
+ }
58
+ });
59
+
60
+ // src/_api/generated/_cfg_accounts/schemas/OAuthProvidersResponse.ts
61
+ var OAuthProvidersResponse_exports = {};
62
+ __export(OAuthProvidersResponse_exports, {
63
+ OAuthProvidersResponseSchema: () => OAuthProvidersResponseSchema
64
+ });
65
+ var import_zod3, OAuthProvidersResponseSchema;
66
+ var init_OAuthProvidersResponse = __esm({
67
+ "src/_api/generated/_cfg_accounts/schemas/OAuthProvidersResponse.ts"() {
68
+ "use strict";
69
+ import_zod3 = require("zod");
70
+ init_OAuthProviderInfo();
71
+ OAuthProvidersResponseSchema = import_zod3.z.object({
72
+ providers: import_zod3.z.array(OAuthProviderInfoSchema)
73
+ });
74
+ }
75
+ });
76
+
35
77
  // src/_api/generated/_cfg_accounts/schemas/WebmailLinkProviderEnum.ts
36
- var import_zod, WebmailLinkProviderEnumSchema;
78
+ var import_zod4, WebmailLinkProviderEnumSchema;
37
79
  var init_WebmailLinkProviderEnum = __esm({
38
80
  "src/_api/generated/_cfg_accounts/schemas/WebmailLinkProviderEnum.ts"() {
39
81
  "use strict";
40
- import_zod = require("zod");
41
- WebmailLinkProviderEnumSchema = import_zod.z.enum(["gmail", "outlook", "yahoo", "icloud", "proton", "zoho", "aol", "fastmail", "gmx", "mailcom", "mail_ru", "yandex", "rambler", "qq", "netease", "sina", "aliyun", "naver", "daum", "web_de", "tonline", "seznam", "wp_pl", "o2_pl", "interia", "libero", "virgilio", "orange", "laposte", "free_fr", "sfr"]);
82
+ import_zod4 = require("zod");
83
+ WebmailLinkProviderEnumSchema = import_zod4.z.enum(["gmail", "outlook", "yahoo", "icloud", "proton", "zoho", "aol", "fastmail", "gmx", "mailcom", "mail_ru", "yandex", "rambler", "qq", "netease", "sina", "aliyun", "naver", "daum", "web_de", "tonline", "seznam", "wp_pl", "o2_pl", "interia", "libero", "virgilio", "orange", "laposte", "free_fr", "sfr"]);
42
84
  }
43
85
  });
44
86
 
45
87
  // src/_api/generated/_cfg_accounts/schemas/WebmailLink.ts
46
- var import_zod2, WebmailLinkSchema;
88
+ var import_zod5, WebmailLinkSchema;
47
89
  var init_WebmailLink = __esm({
48
90
  "src/_api/generated/_cfg_accounts/schemas/WebmailLink.ts"() {
49
91
  "use strict";
50
- import_zod2 = require("zod");
92
+ import_zod5 = require("zod");
51
93
  init_WebmailLinkProviderEnum();
52
- WebmailLinkSchema = import_zod2.z.object({
94
+ WebmailLinkSchema = import_zod5.z.object({
53
95
  provider: WebmailLinkProviderEnumSchema,
54
- provider_name: import_zod2.z.string(),
55
- url: import_zod2.z.url().or(import_zod2.z.literal("")),
56
- is_search: import_zod2.z.boolean()
96
+ provider_name: import_zod5.z.string(),
97
+ url: import_zod5.z.url().or(import_zod5.z.literal("")),
98
+ is_search: import_zod5.z.boolean()
57
99
  });
58
100
  }
59
101
  });
@@ -63,17 +105,17 @@ var OTPRequestResponse_exports = {};
63
105
  __export(OTPRequestResponse_exports, {
64
106
  OTPRequestResponseSchema: () => OTPRequestResponseSchema
65
107
  });
66
- var import_zod3, OTPRequestResponseSchema;
108
+ var import_zod6, OTPRequestResponseSchema;
67
109
  var init_OTPRequestResponse = __esm({
68
110
  "src/_api/generated/_cfg_accounts/schemas/OTPRequestResponse.ts"() {
69
111
  "use strict";
70
- import_zod3 = require("zod");
112
+ import_zod6 = require("zod");
71
113
  init_WebmailLink();
72
- OTPRequestResponseSchema = import_zod3.z.object({
73
- message: import_zod3.z.string(),
114
+ OTPRequestResponseSchema = import_zod6.z.object({
115
+ message: import_zod6.z.string(),
74
116
  webmail: WebmailLinkSchema.nullable().optional(),
75
- resend_in: import_zod3.z.number().int().min(0).optional(),
76
- expires_in: import_zod3.z.number().int().min(0).optional()
117
+ resend_in: import_zod6.z.number().int().min(0).optional(),
118
+ expires_in: import_zod6.z.number().int().min(0).optional()
77
119
  });
78
120
  }
79
121
  });
@@ -83,31 +125,31 @@ var User_exports = {};
83
125
  __export(User_exports, {
84
126
  UserSchema: () => UserSchema
85
127
  });
86
- var import_zod4, UserSchema;
128
+ var import_zod7, UserSchema;
87
129
  var init_User = __esm({
88
130
  "src/_api/generated/_cfg_accounts/schemas/User.ts"() {
89
131
  "use strict";
90
- import_zod4 = require("zod");
91
- UserSchema = import_zod4.z.object({
92
- id: import_zod4.z.number().int(),
93
- email: import_zod4.z.email().or(import_zod4.z.literal("")),
94
- first_name: import_zod4.z.string().max(50).nullable().optional(),
95
- last_name: import_zod4.z.string().max(50).nullable().optional(),
96
- full_name: import_zod4.z.string(),
97
- initials: import_zod4.z.string(),
98
- display_username: import_zod4.z.string(),
99
- company: import_zod4.z.string().max(100).nullable().optional(),
100
- phone: import_zod4.z.string().max(20).nullable().optional(),
101
- position: import_zod4.z.string().max(100).nullable().optional(),
102
- language: import_zod4.z.string().max(10).nullable().optional(),
103
- timezone: import_zod4.z.string().max(64).nullable().optional(),
104
- avatar: import_zod4.z.url().or(import_zod4.z.literal("")).nullable(),
105
- is_staff: import_zod4.z.boolean(),
106
- is_superuser: import_zod4.z.boolean(),
107
- date_joined: import_zod4.z.string().datetime({ offset: true }),
108
- last_login: import_zod4.z.string().datetime({ offset: true }).nullable(),
109
- unanswered_messages_count: import_zod4.z.number().int().default(0),
110
- api_key: import_zod4.z.string().nullable()
132
+ import_zod7 = require("zod");
133
+ UserSchema = import_zod7.z.object({
134
+ id: import_zod7.z.number().int(),
135
+ email: import_zod7.z.email().or(import_zod7.z.literal("")),
136
+ first_name: import_zod7.z.string().max(50).nullable().optional(),
137
+ last_name: import_zod7.z.string().max(50).nullable().optional(),
138
+ full_name: import_zod7.z.string(),
139
+ initials: import_zod7.z.string(),
140
+ display_username: import_zod7.z.string(),
141
+ company: import_zod7.z.string().max(100).nullable().optional(),
142
+ phone: import_zod7.z.string().max(20).nullable().optional(),
143
+ position: import_zod7.z.string().max(100).nullable().optional(),
144
+ language: import_zod7.z.string().max(10).nullable().optional(),
145
+ timezone: import_zod7.z.string().max(64).nullable().optional(),
146
+ avatar: import_zod7.z.url().or(import_zod7.z.literal("")).nullable(),
147
+ is_staff: import_zod7.z.boolean(),
148
+ is_superuser: import_zod7.z.boolean(),
149
+ date_joined: import_zod7.z.string().datetime({ offset: true }),
150
+ last_login: import_zod7.z.string().datetime({ offset: true }).nullable(),
151
+ unanswered_messages_count: import_zod7.z.number().int().default(0),
152
+ api_key: import_zod7.z.string().nullable()
111
153
  });
112
154
  }
113
155
  });
@@ -117,19 +159,19 @@ var OTPVerifyResponse_exports = {};
117
159
  __export(OTPVerifyResponse_exports, {
118
160
  OTPVerifyResponseSchema: () => OTPVerifyResponseSchema
119
161
  });
120
- var import_zod5, OTPVerifyResponseSchema;
162
+ var import_zod8, OTPVerifyResponseSchema;
121
163
  var init_OTPVerifyResponse = __esm({
122
164
  "src/_api/generated/_cfg_accounts/schemas/OTPVerifyResponse.ts"() {
123
165
  "use strict";
124
- import_zod5 = require("zod");
166
+ import_zod8 = require("zod");
125
167
  init_User();
126
- OTPVerifyResponseSchema = import_zod5.z.object({
127
- requires_2fa: import_zod5.z.boolean().default(false).optional(),
128
- session_id: import_zod5.z.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i).nullable().optional(),
129
- refresh: import_zod5.z.string().nullable().optional(),
130
- access: import_zod5.z.string().nullable().optional(),
168
+ OTPVerifyResponseSchema = import_zod8.z.object({
169
+ requires_2fa: import_zod8.z.boolean().default(false).optional(),
170
+ session_id: import_zod8.z.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i).nullable().optional(),
171
+ refresh: import_zod8.z.string().nullable().optional(),
172
+ access: import_zod8.z.string().nullable().optional(),
131
173
  user: UserSchema.nullable().optional(),
132
- should_prompt_2fa: import_zod5.z.boolean().optional()
174
+ should_prompt_2fa: import_zod8.z.boolean().optional()
133
175
  });
134
176
  }
135
177
  });
@@ -139,19 +181,19 @@ var PasswordLoginResponse_exports = {};
139
181
  __export(PasswordLoginResponse_exports, {
140
182
  PasswordLoginResponseSchema: () => PasswordLoginResponseSchema
141
183
  });
142
- var import_zod6, PasswordLoginResponseSchema;
184
+ var import_zod9, PasswordLoginResponseSchema;
143
185
  var init_PasswordLoginResponse = __esm({
144
186
  "src/_api/generated/_cfg_accounts/schemas/PasswordLoginResponse.ts"() {
145
187
  "use strict";
146
- import_zod6 = require("zod");
188
+ import_zod9 = require("zod");
147
189
  init_User();
148
- PasswordLoginResponseSchema = import_zod6.z.object({
149
- requires_2fa: import_zod6.z.boolean().default(false).optional(),
150
- session_id: import_zod6.z.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i).nullable().optional(),
151
- refresh: import_zod6.z.string().nullable().optional(),
152
- access: import_zod6.z.string().nullable().optional(),
190
+ PasswordLoginResponseSchema = import_zod9.z.object({
191
+ requires_2fa: import_zod9.z.boolean().default(false).optional(),
192
+ session_id: import_zod9.z.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i).nullable().optional(),
193
+ refresh: import_zod9.z.string().nullable().optional(),
194
+ access: import_zod9.z.string().nullable().optional(),
153
195
  user: UserSchema.nullable().optional(),
154
- should_prompt_2fa: import_zod6.z.boolean().optional()
196
+ should_prompt_2fa: import_zod9.z.boolean().optional()
155
197
  });
156
198
  }
157
199
  });
@@ -167,8 +209,10 @@ __export(auth_exports, {
167
209
  AnalyticsEvent: () => AnalyticsEvent,
168
210
  AuthContext: () => AuthContext_default,
169
211
  AuthProvider: () => AuthProvider,
212
+ OAUTH_PROVIDER_IDS: () => OAUTH_PROVIDER_IDS,
170
213
  authLogger: () => authLogger,
171
214
  beginTwoFactorChallenge: () => beginTwoFactorChallenge,
215
+ clearOAuthAttempt: () => clearOAuthAttempt,
172
216
  clearProfileCache: () => clearProfileCache,
173
217
  consumeSavedRedirect: () => consumeSavedRedirect,
174
218
  decodeBase64: () => decodeBase64,
@@ -180,10 +224,12 @@ __export(auth_exports, {
180
224
  hasValidCache: () => hasValidCache,
181
225
  isAllowedAuthPath: () => isAllowedAuthPath,
182
226
  isForbidden: () => isForbidden,
227
+ isOAuthProviderId: () => isOAuthProviderId,
183
228
  logAuthFailure: () => logAuthFailure,
184
229
  logger: () => logger,
185
230
  normalizePath: () => normalizePath,
186
231
  peekSavedRedirect: () => peekSavedRedirect,
232
+ readOAuthFailure: () => readOAuthFailure,
187
233
  resolveAuthError: () => resolveAuthError,
188
234
  resolveGuardIsAuthenticated: () => resolveGuardIsAuthenticated,
189
235
  resolveGuardIsLoading: () => resolveGuardIsLoading,
@@ -202,6 +248,8 @@ __export(auth_exports, {
202
248
  useDeleteAccount: () => useDeleteAccount,
203
249
  useGithubAuth: () => useGithubAuth,
204
250
  useLocalStorage: () => useLocalStorage,
251
+ useOAuthLogin: () => useOAuthLogin,
252
+ useOAuthProviders: () => useOAuthProviders,
205
253
  useQueryParams: () => useQueryParams,
206
254
  useSession: () => useSession,
207
255
  useSessionStorage: () => useSessionStorage,
@@ -230,7 +278,7 @@ var AUTH_CONSTANTS = {
230
278
 
231
279
  // src/auth/context/AuthContext.tsx
232
280
  var import_navigation4 = require("next/navigation");
233
- var import_react18 = require("react");
281
+ var import_react20 = require("react");
234
282
 
235
283
  // src/_api/generated/helpers/errors.ts
236
284
  var APIError = class extends Error {
@@ -309,6 +357,7 @@ var CFG_KEYS = {
309
357
  redirectUrlTs: k("cfg.auth.redirect_url_ts", "session", true),
310
358
  oauthState: k("cfg.auth.oauth_state", "session", true),
311
359
  oauthProvider: k("cfg.auth.oauth_provider", "session", true),
360
+ oauthProviders: k("cfg.auth.oauth_providers", "session", false),
312
361
  profileCache: k("cfg.profile.cache", "local", true),
313
362
  monitorSessionId: k("cfg.monitor.session_id", "local", false),
314
363
  monitorSessionCookie: k("cfg.monitor.session_id", "cookie", false),
@@ -1896,8 +1945,8 @@ var useAuthForm = /* @__PURE__ */ __name((options) => {
1896
1945
  };
1897
1946
  }, "useAuthForm");
1898
1947
 
1899
- // src/auth/hooks/useGithubAuth.ts
1900
- var import_react10 = require("react");
1948
+ // src/auth/hooks/useOAuthLogin.ts
1949
+ var import_react11 = require("react");
1901
1950
 
1902
1951
  // src/_api/generated/core/bodySerializer.gen.ts
1903
1952
  var serializeFormDataPair = /* @__PURE__ */ __name((data, key, value) => {
@@ -2763,7 +2812,7 @@ var CfgAccountsOauth = class {
2763
2812
  /**
2764
2813
  * Start GitHub OAuth
2765
2814
  *
2766
- * Generate GitHub OAuth authorization URL. Redirect user to this URL to start authentication.
2815
+ * Generate the GitHub authorization URL. Redirect the user to it to start authentication. The redirect URI is derived from the request Origin.
2767
2816
  */
2768
2817
  static cfgAccountsOauthGithubAuthorizeCreate(options) {
2769
2818
  return (options?.client ?? client).post({
@@ -2778,7 +2827,7 @@ var CfgAccountsOauth = class {
2778
2827
  /**
2779
2828
  * Complete GitHub OAuth
2780
2829
  *
2781
- * Exchange authorization code for JWT tokens. Call this after GitHub redirects back with code.
2830
+ * Exchange the authorization code for JWT tokens. Call this after GitHub redirects back with a code. The state is single use.
2782
2831
  */
2783
2832
  static cfgAccountsOauthGithubCallbackCreate(options) {
2784
2833
  return (options.client ?? client).post({
@@ -2790,10 +2839,40 @@ var CfgAccountsOauth = class {
2790
2839
  }
2791
2840
  });
2792
2841
  }
2842
+ /**
2843
+ * Start Google OAuth
2844
+ *
2845
+ * Generate the Google authorization URL. Redirect the user to it to start authentication. The redirect URI is derived from the request Origin.
2846
+ */
2847
+ static cfgAccountsOauthGoogleAuthorizeCreate(options) {
2848
+ return (options?.client ?? client).post({
2849
+ url: "/cfg/accounts/oauth/google/authorize/",
2850
+ ...options,
2851
+ headers: {
2852
+ "Content-Type": "application/json",
2853
+ ...options?.headers
2854
+ }
2855
+ });
2856
+ }
2857
+ /**
2858
+ * Complete Google OAuth
2859
+ *
2860
+ * Exchange the authorization code for JWT tokens. Call this after Google redirects back with a code. The state is single use.
2861
+ */
2862
+ static cfgAccountsOauthGoogleCallbackCreate(options) {
2863
+ return (options.client ?? client).post({
2864
+ url: "/cfg/accounts/oauth/google/callback/",
2865
+ ...options,
2866
+ headers: {
2867
+ "Content-Type": "application/json",
2868
+ ...options.headers
2869
+ }
2870
+ });
2871
+ }
2793
2872
  /**
2794
2873
  * List OAuth providers
2795
2874
  *
2796
- * Get list of available OAuth providers for authentication.
2875
+ * Providers that are configured, in display order. The login screen shows exactly these buttons.
2797
2876
  */
2798
2877
  static cfgAccountsOauthProvidersRetrieve(options) {
2799
2878
  return (options?.client ?? client).get({ url: "/cfg/accounts/oauth/providers/", ...options });
@@ -3264,6 +3343,27 @@ var Analytics = {
3264
3343
  }
3265
3344
  };
3266
3345
 
3346
+ // src/_api/generated/types.gen.ts
3347
+ var OAuthErrorCodeEnum = /* @__PURE__ */ ((OAuthErrorCodeEnum2) => {
3348
+ OAuthErrorCodeEnum2["OAUTH_DISABLED"] = "oauth_disabled";
3349
+ OAuthErrorCodeEnum2["GITHUB_OAUTH_DISABLED"] = "github_oauth_disabled";
3350
+ OAuthErrorCodeEnum2["ORIGIN_NOT_ALLOWED"] = "origin_not_allowed";
3351
+ OAuthErrorCodeEnum2["MISSING_REDIRECT_URI"] = "missing_redirect_uri";
3352
+ OAuthErrorCodeEnum2["INVALID_STATE"] = "invalid_state";
3353
+ OAuthErrorCodeEnum2["OAUTH_EXCHANGE_FAILED"] = "oauth_exchange_failed";
3354
+ OAuthErrorCodeEnum2["INVALID_ID_TOKEN"] = "invalid_id_token";
3355
+ OAuthErrorCodeEnum2["EMAIL_MISSING"] = "email_missing";
3356
+ OAuthErrorCodeEnum2["EMAIL_NOT_VERIFIED"] = "email_not_verified";
3357
+ OAuthErrorCodeEnum2["HOSTED_DOMAIN_NOT_ALLOWED"] = "hosted_domain_not_allowed";
3358
+ OAuthErrorCodeEnum2["ACCOUNT_INACTIVE"] = "account_inactive";
3359
+ OAuthErrorCodeEnum2["LINK_NOT_ALLOWED"] = "link_not_allowed";
3360
+ OAuthErrorCodeEnum2["RATE_LIMITED"] = "rate_limited";
3361
+ OAuthErrorCodeEnum2["PROVIDER_UNAVAILABLE"] = "provider_unavailable";
3362
+ OAuthErrorCodeEnum2["SERVER_ERROR"] = "server_error";
3363
+ OAuthErrorCodeEnum2["NOT_FOUND"] = "not_found";
3364
+ return OAuthErrorCodeEnum2;
3365
+ })(OAuthErrorCodeEnum || {});
3366
+
3267
3367
  // src/auth/utils/errors.ts
3268
3368
  var prop = /* @__PURE__ */ __name((value, key) => typeof value === "object" && value !== null ? value[key] : void 0, "prop");
3269
3369
  var TRANSPORT_FALLBACK = /^HTTP \d{3}:\s*/;
@@ -3325,126 +3425,24 @@ var logAuthFailure = /* @__PURE__ */ __name((log, message, error) => {
3325
3425
  log.error(message, error);
3326
3426
  }, "logAuthFailure");
3327
3427
 
3328
- // src/auth/hooks/useGithubAuth.ts
3329
- var OAUTH_STATE_KEY = CFG_KEYS.oauthState.key;
3330
- var OAUTH_PROVIDER_KEY = CFG_KEYS.oauthProvider.key;
3331
- var useGithubAuth = /* @__PURE__ */ __name((options = {}) => {
3332
- const { sourceUrl, onSuccess, onError, onRequires2FA, redirectUrl, skipRedirect = false } = options;
3333
- const router = useCfgRouter();
3334
- const [isLoading, setIsLoading] = (0, import_react10.useState)(false);
3335
- const [error, setError] = (0, import_react10.useState)(null);
3336
- const startGithubAuth = (0, import_react10.useCallback)(async () => {
3337
- setIsLoading(true);
3338
- setError(null);
3339
- auth.clearSession();
3340
- try {
3341
- authLogger.info("Starting GitHub OAuth flow...");
3342
- Analytics.event("auth_oauth_start" /* AUTH_OAUTH_START */, {
3343
- category: "auth" /* AUTH */,
3344
- label: "github"
3345
- });
3346
- const result = await CfgAccountsOauth.cfgAccountsOauthGithubAuthorizeCreate({
3347
- body: {
3348
- source_url: sourceUrl || (typeof window !== "undefined" ? window.location.href : "")
3349
- },
3350
- throwOnError: true
3351
- });
3352
- const response = result.data;
3353
- if (!response.authorization_url) {
3354
- throw new Error("Failed to get authorization URL");
3355
- }
3356
- authLogger.info("Redirecting to GitHub...", response.authorization_url);
3357
- if (typeof window !== "undefined") {
3358
- sessionStorage.setItem(OAUTH_STATE_KEY, response.state);
3359
- sessionStorage.setItem(OAUTH_PROVIDER_KEY, "github");
3360
- }
3361
- window.location.href = response.authorization_url;
3362
- } catch (err) {
3363
- const errorMessage = formatAuthError(err, "Failed to start GitHub authentication");
3364
- authLogger.error("GitHub OAuth start error:", err);
3365
- setError(errorMessage);
3366
- onError?.(errorMessage);
3367
- Analytics.event("auth_oauth_fail" /* AUTH_OAUTH_FAIL */, {
3368
- category: "auth" /* AUTH */,
3369
- label: "github"
3370
- });
3371
- } finally {
3372
- setIsLoading(false);
3373
- }
3374
- }, [sourceUrl, onError]);
3375
- const handleGithubCallback = (0, import_react10.useCallback)(async (code, state) => {
3376
- setIsLoading(true);
3377
- setError(null);
3378
- try {
3379
- authLogger.info("Processing GitHub OAuth callback...");
3380
- if (typeof window !== "undefined") {
3381
- const storedState = sessionStorage.getItem(OAUTH_STATE_KEY);
3382
- if (storedState && storedState !== state) {
3383
- throw new Error("Invalid OAuth state - possible CSRF attack");
3384
- }
3385
- sessionStorage.removeItem(OAUTH_STATE_KEY);
3386
- sessionStorage.removeItem(OAUTH_PROVIDER_KEY);
3387
- }
3388
- const result = await CfgAccountsOauth.cfgAccountsOauthGithubCallbackCreate({
3389
- body: { code, state },
3390
- throwOnError: true
3391
- });
3392
- const response = result.data;
3393
- if (response.requires_2fa && response.session_id) {
3394
- authLogger.info("GitHub OAuth requires 2FA, session:", response.session_id);
3395
- Analytics.event("auth_oauth_start" /* AUTH_OAUTH_START */, {
3396
- category: "auth" /* AUTH */,
3397
- label: "github-2fa-required"
3398
- });
3399
- onRequires2FA?.(response.session_id, response.should_prompt_2fa || false);
3400
- return;
3401
- }
3402
- if (!response.access || !response.refresh) {
3403
- throw new Error("Invalid response from OAuth callback");
3404
- }
3405
- authLogger.info("GitHub OAuth successful, user:", response.user);
3406
- auth.setSession({ access: response.access, refresh: response.refresh });
3407
- Analytics.event("auth_login_success" /* AUTH_LOGIN_SUCCESS */, {
3408
- category: "auth" /* AUTH */,
3409
- label: "github"
3410
- });
3411
- if (response.user?.id) {
3412
- Analytics.setUser(String(response.user.id));
3413
- }
3414
- if (response.user) {
3415
- onSuccess?.(response.user, response.is_new_user || false);
3416
- }
3417
- if (!skipRedirect) {
3418
- const finalRedirectUrl = redirectUrl || "/private";
3419
- router.hardPush(finalRedirectUrl);
3420
- }
3421
- return;
3422
- } catch (err) {
3423
- const errorMessage = formatAuthError(err, "GitHub authentication failed");
3424
- authLogger.error("GitHub OAuth callback error:", err);
3425
- setError(errorMessage);
3426
- onError?.(errorMessage);
3427
- Analytics.event("auth_oauth_fail" /* AUTH_OAUTH_FAIL */, {
3428
- category: "auth" /* AUTH */,
3429
- label: "github"
3430
- });
3431
- } finally {
3432
- setIsLoading(false);
3433
- }
3434
- }, [onSuccess, onError, onRequires2FA, redirectUrl, router, skipRedirect]);
3435
- return {
3436
- isLoading,
3437
- error,
3438
- startGithubAuth,
3439
- handleGithubCallback
3440
- };
3441
- }, "useGithubAuth");
3442
-
3443
- // src/auth/hooks/useTwoFactorVerify.ts
3444
- var import_react12 = require("react");
3428
+ // src/auth/utils/oauthErrors.ts
3429
+ var SERVER_CODES = new Set(Object.values(OAuthErrorCodeEnum));
3430
+ var record = /* @__PURE__ */ __name((value) => typeof value === "object" && value !== null ? value : null, "record");
3431
+ var readOAuthFailure = /* @__PURE__ */ __name((err, fallback) => {
3432
+ const body = record(record(err)?.response);
3433
+ const code = body?.error;
3434
+ if (typeof code === "string" && SERVER_CODES.has(code)) {
3435
+ const description = body?.error_description;
3436
+ return {
3437
+ code,
3438
+ message: typeof description === "string" && description ? description : fallback
3439
+ };
3440
+ }
3441
+ return { message: formatAuthError(err, fallback) };
3442
+ }, "readOAuthFailure");
3445
3443
 
3446
3444
  // src/auth/hooks/useSessionStorage.ts
3447
- var import_react11 = require("react");
3445
+ var import_react10 = require("react");
3448
3446
 
3449
3447
  // src/auth/utils/storage.ts
3450
3448
  var MAX_ITEM_KB = 1024;
@@ -3473,7 +3471,7 @@ __name(isWithinSizeLimit, "isWithinSizeLimit");
3473
3471
 
3474
3472
  // src/auth/hooks/useSessionStorage.ts
3475
3473
  function useSessionStorage(key, initialValue) {
3476
- const [storedValue, setStoredValue] = (0, import_react11.useState)(() => {
3474
+ const [storedValue, setStoredValue] = (0, import_react10.useState)(() => {
3477
3475
  if (typeof window === "undefined") {
3478
3476
  return initialValue;
3479
3477
  }
@@ -3661,6 +3659,243 @@ var useAuthRedirectManager = /* @__PURE__ */ __name((options = {}) => {
3661
3659
  };
3662
3660
  }, "useAuthRedirectManager");
3663
3661
 
3662
+ // src/auth/hooks/useOAuthLogin.ts
3663
+ var ADAPTERS = {
3664
+ github: {
3665
+ authorize: /* @__PURE__ */ __name(async (body) => (await CfgAccountsOauth.cfgAccountsOauthGithubAuthorizeCreate({ body, throwOnError: true })).data, "authorize"),
3666
+ callback: /* @__PURE__ */ __name(async (body) => (await CfgAccountsOauth.cfgAccountsOauthGithubCallbackCreate({ body, throwOnError: true })).data, "callback")
3667
+ },
3668
+ google: {
3669
+ authorize: /* @__PURE__ */ __name(async (body) => (await CfgAccountsOauth.cfgAccountsOauthGoogleAuthorizeCreate({ body, throwOnError: true })).data, "authorize"),
3670
+ callback: /* @__PURE__ */ __name(async (body) => (await CfgAccountsOauth.cfgAccountsOauthGoogleCallbackCreate({ body, throwOnError: true })).data, "callback")
3671
+ }
3672
+ };
3673
+ var OAUTH_PROVIDER_IDS = Object.keys(ADAPTERS);
3674
+ var isOAuthProviderId = /* @__PURE__ */ __name((value) => typeof value === "string" && Object.hasOwn(ADAPTERS, value), "isOAuthProviderId");
3675
+ var STATE_KEY = CFG_KEYS.oauthState.key;
3676
+ var PROVIDER_KEY = CFG_KEYS.oauthProvider.key;
3677
+ var clearOAuthAttempt = /* @__PURE__ */ __name(() => {
3678
+ cfgStorage.remove(STATE_KEY);
3679
+ cfgStorage.remove(PROVIDER_KEY);
3680
+ }, "clearOAuthAttempt");
3681
+ var useOAuthLogin = /* @__PURE__ */ __name((options = {}) => {
3682
+ const router = useCfgRouter();
3683
+ const optionsRef = (0, import_react11.useRef)(options);
3684
+ optionsRef.current = options;
3685
+ const routerRef = (0, import_react11.useRef)(router);
3686
+ routerRef.current = router;
3687
+ const [loadingProvider, setLoadingProvider] = (0, import_react11.useState)(null);
3688
+ const [error, setError] = (0, import_react11.useState)(null);
3689
+ const [errorCode, setErrorCode] = (0, import_react11.useState)(null);
3690
+ (0, import_react11.useEffect)(() => {
3691
+ const onShow = /* @__PURE__ */ __name((event) => {
3692
+ if (event.persisted) setLoadingProvider(null);
3693
+ }, "onShow");
3694
+ window.addEventListener("pageshow", onShow);
3695
+ return () => window.removeEventListener("pageshow", onShow);
3696
+ }, []);
3697
+ const fail = (0, import_react11.useCallback)((provider, message, code) => {
3698
+ setError(message);
3699
+ setErrorCode(code ?? null);
3700
+ setLoadingProvider(null);
3701
+ optionsRef.current.onError?.(message, code);
3702
+ Analytics.event("auth_oauth_fail" /* AUTH_OAUTH_FAIL */, {
3703
+ category: "auth" /* AUTH */,
3704
+ label: provider
3705
+ });
3706
+ }, []);
3707
+ const start = (0, import_react11.useCallback)(async (provider) => {
3708
+ setLoadingProvider(provider);
3709
+ setError(null);
3710
+ setErrorCode(null);
3711
+ auth.clearSession();
3712
+ try {
3713
+ Analytics.event("auth_oauth_start" /* AUTH_OAUTH_START */, {
3714
+ category: "auth" /* AUTH */,
3715
+ label: provider
3716
+ });
3717
+ const sourceUrl = optionsRef.current.sourceUrl || window.location.href;
3718
+ const response = await ADAPTERS[provider].authorize({ source_url: sourceUrl });
3719
+ if (!response.authorization_url || !response.state) {
3720
+ throw new Error("Failed to get authorization URL");
3721
+ }
3722
+ cfgStorage.write(STATE_KEY, response.state);
3723
+ cfgStorage.write(PROVIDER_KEY, provider);
3724
+ authLogger.info(`Redirecting to ${provider}...`);
3725
+ window.location.href = response.authorization_url;
3726
+ } catch (err) {
3727
+ authLogger.error(`${provider} OAuth start error:`, err);
3728
+ const failure = readOAuthFailure(err, "Failed to start authentication");
3729
+ fail(provider, failure.message, failure.code);
3730
+ }
3731
+ }, [fail]);
3732
+ const complete = (0, import_react11.useCallback)(async (provider, code, state) => {
3733
+ setLoadingProvider(provider);
3734
+ setError(null);
3735
+ setErrorCode(null);
3736
+ const storedState = cfgStorage.read(STATE_KEY);
3737
+ const storedProvider = cfgStorage.read(PROVIDER_KEY);
3738
+ clearOAuthAttempt();
3739
+ if (!storedState || storedState !== state || storedProvider && storedProvider !== provider) {
3740
+ authLogger.warn(`${provider} OAuth callback rejected: state does not match this browser`);
3741
+ fail(provider, "Invalid sign-in attempt. Please try again.", "invalid_state");
3742
+ return;
3743
+ }
3744
+ try {
3745
+ const response = await ADAPTERS[provider].callback({ code, state });
3746
+ if (response.requires_2fa && response.session_id) {
3747
+ Analytics.event("auth_oauth_start" /* AUTH_OAUTH_START */, {
3748
+ category: "auth" /* AUTH */,
3749
+ label: `${provider}-2fa-required`
3750
+ });
3751
+ optionsRef.current.onRequires2FA?.(response.session_id, response.should_prompt_2fa || false);
3752
+ setLoadingProvider(null);
3753
+ return;
3754
+ }
3755
+ if (!response.access || !response.refresh) {
3756
+ throw new Error("Invalid response from OAuth callback");
3757
+ }
3758
+ auth.setSession({ access: response.access, refresh: response.refresh });
3759
+ Analytics.event("auth_login_success" /* AUTH_LOGIN_SUCCESS */, {
3760
+ category: "auth" /* AUTH */,
3761
+ label: provider
3762
+ });
3763
+ if (response.user?.id) {
3764
+ Analytics.setUser(String(response.user.id));
3765
+ }
3766
+ if (response.user) {
3767
+ optionsRef.current.onSuccess?.(response.user, response.is_new_user || false, provider);
3768
+ }
3769
+ setLoadingProvider(null);
3770
+ if (!optionsRef.current.skipRedirect) {
3771
+ routerRef.current.hardPush(consumeSavedRedirect() || optionsRef.current.redirectUrl || "/private");
3772
+ }
3773
+ } catch (err) {
3774
+ authLogger.error(`${provider} OAuth callback error:`, err);
3775
+ const failure = readOAuthFailure(err, "Authentication failed");
3776
+ fail(provider, failure.message, failure.code);
3777
+ }
3778
+ }, [fail]);
3779
+ return {
3780
+ isLoading: loadingProvider !== null,
3781
+ loadingProvider,
3782
+ error,
3783
+ errorCode,
3784
+ start,
3785
+ complete
3786
+ };
3787
+ }, "useOAuthLogin");
3788
+
3789
+ // src/auth/hooks/useOAuthProviders.ts
3790
+ var import_react12 = require("react");
3791
+
3792
+ // src/_api/generated/_cfg_accounts/hooks/useCfgAccountsOauthProvidersRetrieve.ts
3793
+ var import_swr = __toESM(require("swr"), 1);
3794
+ function useCfgAccountsOauthProvidersRetrieve(args, config) {
3795
+ const { enabled = true, ...swrConfig } = config ?? {};
3796
+ const key = enabled ? ["cfg_accounts_oauth_providers_retrieve", args ?? {}] : null;
3797
+ return (0, import_swr.default)(
3798
+ key,
3799
+ async () => {
3800
+ const res = await CfgAccountsOauth.cfgAccountsOauthProvidersRetrieve({ ...args ?? {}, throwOnError: true });
3801
+ const data = res.data;
3802
+ void Promise.resolve().then(() => (init_OAuthProvidersResponse(), OAuthProvidersResponse_exports)).then(({ OAuthProvidersResponseSchema: OAuthProvidersResponseSchema2 }) => {
3803
+ const parsed = OAuthProvidersResponseSchema2.safeParse(data);
3804
+ if (parsed.success) return;
3805
+ console.warn(
3806
+ "[zod] response did not match schema",
3807
+ {
3808
+ operation: "cfg_accounts_oauth_providers_retrieve",
3809
+ method: "GET",
3810
+ path: "/cfg/accounts/oauth/providers/",
3811
+ issues: parsed.error.issues,
3812
+ data
3813
+ }
3814
+ );
3815
+ if (typeof window !== "undefined") {
3816
+ try {
3817
+ window.dispatchEvent(
3818
+ new CustomEvent("zod-validation-error", {
3819
+ detail: {
3820
+ operation: "cfg_accounts_oauth_providers_retrieve",
3821
+ method: "GET",
3822
+ path: "/cfg/accounts/oauth/providers/",
3823
+ issues: parsed.error.issues,
3824
+ data,
3825
+ timestamp: /* @__PURE__ */ new Date()
3826
+ },
3827
+ bubbles: true,
3828
+ cancelable: false
3829
+ })
3830
+ );
3831
+ } catch {
3832
+ }
3833
+ }
3834
+ }).catch(() => {
3835
+ });
3836
+ return data;
3837
+ },
3838
+ swrConfig
3839
+ );
3840
+ }
3841
+ __name(useCfgAccountsOauthProvidersRetrieve, "useCfgAccountsOauthProvidersRetrieve");
3842
+
3843
+ // src/auth/hooks/useOAuthProviders.ts
3844
+ var EMPTY = [];
3845
+ var CACHE_KEY = CFG_KEYS.oauthProviders.key;
3846
+ var isInfo = /* @__PURE__ */ __name((value) => typeof value === "object" && value !== null && typeof value.id === "string", "isInfo");
3847
+ var lastRaw = null;
3848
+ var lastParsed;
3849
+ var readCached = /* @__PURE__ */ __name(() => {
3850
+ const raw = cfgStorage.read(CACHE_KEY);
3851
+ if (raw === lastRaw) return lastParsed;
3852
+ lastRaw = raw;
3853
+ try {
3854
+ const parsed = raw === null ? null : JSON.parse(raw);
3855
+ lastParsed = Array.isArray(parsed) && parsed.every(isInfo) ? parsed : void 0;
3856
+ } catch {
3857
+ lastParsed = void 0;
3858
+ }
3859
+ return lastParsed;
3860
+ }, "readCached");
3861
+ var subscribe3 = /* @__PURE__ */ __name(() => () => {
3862
+ }, "subscribe");
3863
+ var serverSnapshot = /* @__PURE__ */ __name(() => void 0, "serverSnapshot");
3864
+ var useOAuthProviders = /* @__PURE__ */ __name(() => {
3865
+ const cached = (0, import_react12.useSyncExternalStore)(subscribe3, readCached, serverSnapshot);
3866
+ const { data, error, isLoading } = useCfgAccountsOauthProvidersRetrieve(void 0, {
3867
+ revalidateOnFocus: false,
3868
+ revalidateOnReconnect: false,
3869
+ revalidateOnMount: true,
3870
+ shouldRetryOnError: false,
3871
+ dedupingInterval: 60 * 60 * 1e3,
3872
+ fallbackData: cached && { providers: cached },
3873
+ onSuccess: /* @__PURE__ */ __name((response) => {
3874
+ cfgStorage.writeJSON(CACHE_KEY, response.providers);
3875
+ }, "onSuccess")
3876
+ });
3877
+ const providers = (0, import_react12.useMemo)(
3878
+ () => data?.providers.filter((p) => OAUTH_PROVIDER_IDS.includes(p.id)) ?? EMPTY,
3879
+ [data]
3880
+ );
3881
+ return { providers, isReady: !isLoading || Boolean(error) || cached !== void 0 };
3882
+ }, "useOAuthProviders");
3883
+
3884
+ // src/auth/hooks/useGithubAuth.ts
3885
+ var import_react13 = require("react");
3886
+ var useGithubAuth = /* @__PURE__ */ __name((options = {}) => {
3887
+ const { isLoading, error, start, complete } = useOAuthLogin(options);
3888
+ const startGithubAuth = (0, import_react13.useCallback)(() => start("github"), [start]);
3889
+ const handleGithubCallback = (0, import_react13.useCallback)(
3890
+ (code, state) => complete("github", code, state),
3891
+ [complete]
3892
+ );
3893
+ return { isLoading, error, startGithubAuth, handleGithubCallback };
3894
+ }, "useGithubAuth");
3895
+
3896
+ // src/auth/hooks/useTwoFactorVerify.ts
3897
+ var import_react14 = require("react");
3898
+
3664
3899
  // src/auth/hooks/twoFactor.shared.ts
3665
3900
  var TOTP_CODE_LENGTH = 6;
3666
3901
  function extractAttemptsRemaining(err) {
@@ -3680,15 +3915,15 @@ __name(isValidTotpCode, "isValidTotpCode");
3680
3915
  var useTwoFactorVerify = /* @__PURE__ */ __name((options = {}) => {
3681
3916
  const { onSuccess, onError, redirectUrl, skipRedirect = false } = options;
3682
3917
  const router = useCfgRouter();
3683
- const [isLoading, setIsLoading] = (0, import_react12.useState)(false);
3684
- const [error, setError] = (0, import_react12.useState)(null);
3685
- const [warning, setWarning] = (0, import_react12.useState)(null);
3686
- const [remainingBackupCodes, setRemainingBackupCodes] = (0, import_react12.useState)(null);
3687
- const [attemptsRemaining, setAttemptsRemaining] = (0, import_react12.useState)(null);
3688
- const clearError = (0, import_react12.useCallback)(() => {
3918
+ const [isLoading, setIsLoading] = (0, import_react14.useState)(false);
3919
+ const [error, setError] = (0, import_react14.useState)(null);
3920
+ const [warning, setWarning] = (0, import_react14.useState)(null);
3921
+ const [remainingBackupCodes, setRemainingBackupCodes] = (0, import_react14.useState)(null);
3922
+ const [attemptsRemaining, setAttemptsRemaining] = (0, import_react14.useState)(null);
3923
+ const clearError = (0, import_react14.useCallback)(() => {
3689
3924
  setError(null);
3690
3925
  }, []);
3691
- const handleSuccess = (0, import_react12.useCallback)((response) => {
3926
+ const handleSuccess = (0, import_react14.useCallback)((response) => {
3692
3927
  auth.setSession({ access: response.access_token, refresh: response.refresh_token });
3693
3928
  if (response.warning) {
3694
3929
  setWarning(response.warning);
@@ -3710,7 +3945,7 @@ var useTwoFactorVerify = /* @__PURE__ */ __name((options = {}) => {
3710
3945
  router.hardPush(finalRedirectUrl);
3711
3946
  }
3712
3947
  }, [onSuccess, redirectUrl, router, skipRedirect]);
3713
- const verifyTOTP = (0, import_react12.useCallback)(async (sessionId, code) => {
3948
+ const verifyTOTP = (0, import_react14.useCallback)(async (sessionId, code) => {
3714
3949
  if (!sessionId) {
3715
3950
  const msg = "Missing 2FA session ID";
3716
3951
  setError(msg);
@@ -3753,7 +3988,7 @@ var useTwoFactorVerify = /* @__PURE__ */ __name((options = {}) => {
3753
3988
  setIsLoading(false);
3754
3989
  }
3755
3990
  }, [handleSuccess, onError]);
3756
- const verifyBackupCode = (0, import_react12.useCallback)(async (sessionId, backupCode) => {
3991
+ const verifyBackupCode = (0, import_react14.useCallback)(async (sessionId, backupCode) => {
3757
3992
  if (!sessionId) {
3758
3993
  const msg = "Missing 2FA session ID";
3759
3994
  setError(msg);
@@ -3812,26 +4047,26 @@ var useTwoFactorVerify = /* @__PURE__ */ __name((options = {}) => {
3812
4047
  }, "useTwoFactorVerify");
3813
4048
 
3814
4049
  // src/auth/hooks/useTwoFactorSetup.ts
3815
- var import_react13 = require("react");
4050
+ var import_react15 = require("react");
3816
4051
  var useTwoFactorSetup = /* @__PURE__ */ __name((options = {}) => {
3817
4052
  const { onComplete, onError } = options;
3818
- const [isLoading, setIsLoading] = (0, import_react13.useState)(false);
3819
- const [error, setError] = (0, import_react13.useState)(null);
3820
- const [setupData, setSetupData] = (0, import_react13.useState)(null);
3821
- const [backupCodes, setBackupCodes] = (0, import_react13.useState)(null);
3822
- const [backupCodesWarning, setBackupCodesWarning] = (0, import_react13.useState)(null);
3823
- const [setupStep, setSetupStep] = (0, import_react13.useState)("idle");
3824
- const clearError = (0, import_react13.useCallback)(() => {
4053
+ const [isLoading, setIsLoading] = (0, import_react15.useState)(false);
4054
+ const [error, setError] = (0, import_react15.useState)(null);
4055
+ const [setupData, setSetupData] = (0, import_react15.useState)(null);
4056
+ const [backupCodes, setBackupCodes] = (0, import_react15.useState)(null);
4057
+ const [backupCodesWarning, setBackupCodesWarning] = (0, import_react15.useState)(null);
4058
+ const [setupStep, setSetupStep] = (0, import_react15.useState)("idle");
4059
+ const clearError = (0, import_react15.useCallback)(() => {
3825
4060
  setError(null);
3826
4061
  }, []);
3827
- const resetSetup = (0, import_react13.useCallback)(() => {
4062
+ const resetSetup = (0, import_react15.useCallback)(() => {
3828
4063
  setSetupData(null);
3829
4064
  setBackupCodes(null);
3830
4065
  setBackupCodesWarning(null);
3831
4066
  setSetupStep("idle");
3832
4067
  setError(null);
3833
4068
  }, []);
3834
- const startSetup = (0, import_react13.useCallback)(async (deviceName) => {
4069
+ const startSetup = (0, import_react15.useCallback)(async (deviceName) => {
3835
4070
  setIsLoading(true);
3836
4071
  setError(null);
3837
4072
  setSetupStep("scanning");
@@ -3863,7 +4098,7 @@ var useTwoFactorSetup = /* @__PURE__ */ __name((options = {}) => {
3863
4098
  setIsLoading(false);
3864
4099
  }
3865
4100
  }, [onError]);
3866
- const confirmSetup = (0, import_react13.useCallback)(async (code) => {
4101
+ const confirmSetup = (0, import_react15.useCallback)(async (code) => {
3867
4102
  if (!setupData) {
3868
4103
  const msg = "Setup not started. Call startSetup() first.";
3869
4104
  setError(msg);
@@ -3919,16 +4154,16 @@ var useTwoFactorSetup = /* @__PURE__ */ __name((options = {}) => {
3919
4154
  }, "useTwoFactorSetup");
3920
4155
 
3921
4156
  // src/auth/hooks/useTwoFactorStatus.ts
3922
- var import_react14 = require("react");
4157
+ var import_react16 = require("react");
3923
4158
  var useTwoFactorStatus = /* @__PURE__ */ __name(() => {
3924
- const [isLoading, setIsLoading] = (0, import_react14.useState)(false);
3925
- const [error, setError] = (0, import_react14.useState)(null);
3926
- const [has2FAEnabled, setHas2FAEnabled] = (0, import_react14.useState)(null);
3927
- const [devices, setDevices] = (0, import_react14.useState)([]);
3928
- const clearError = (0, import_react14.useCallback)(() => {
4159
+ const [isLoading, setIsLoading] = (0, import_react16.useState)(false);
4160
+ const [error, setError] = (0, import_react16.useState)(null);
4161
+ const [has2FAEnabled, setHas2FAEnabled] = (0, import_react16.useState)(null);
4162
+ const [devices, setDevices] = (0, import_react16.useState)([]);
4163
+ const clearError = (0, import_react16.useCallback)(() => {
3929
4164
  setError(null);
3930
4165
  }, []);
3931
- const fetchStatus = (0, import_react14.useCallback)(async () => {
4166
+ const fetchStatus = (0, import_react16.useCallback)(async () => {
3932
4167
  setIsLoading(true);
3933
4168
  setError(null);
3934
4169
  try {
@@ -3953,7 +4188,7 @@ var useTwoFactorStatus = /* @__PURE__ */ __name(() => {
3953
4188
  setIsLoading(false);
3954
4189
  }
3955
4190
  }, []);
3956
- const disable2FA = (0, import_react14.useCallback)(async (code) => {
4191
+ const disable2FA = (0, import_react16.useCallback)(async (code) => {
3957
4192
  if (!isValidTotpCode(code)) {
3958
4193
  setError("Please enter a 6-digit code");
3959
4194
  return false;
@@ -3996,9 +4231,9 @@ var useTwoFactor = /* @__PURE__ */ __name((options = {}) => {
3996
4231
  }, "useTwoFactor");
3997
4232
 
3998
4233
  // src/auth/hooks/useLocalStorage.ts
3999
- var import_react15 = require("react");
4234
+ var import_react17 = require("react");
4000
4235
  function useLocalStorage(key, initialValue) {
4001
- const [storedValue, setStoredValue] = (0, import_react15.useState)(() => {
4236
+ const [storedValue, setStoredValue] = (0, import_react17.useState)(() => {
4002
4237
  if (typeof window === "undefined") {
4003
4238
  return initialValue;
4004
4239
  }
@@ -4190,13 +4425,13 @@ function useBase64() {
4190
4425
  __name(useBase64, "useBase64");
4191
4426
 
4192
4427
  // src/auth/hooks/useProfileCache.ts
4193
- var CACHE_KEY = CFG_KEYS.profileCache.key;
4428
+ var CACHE_KEY2 = CFG_KEYS.profileCache.key;
4194
4429
  var CACHE_VERSION = 1;
4195
4430
  var DEFAULT_TTL = 144e5;
4196
4431
  function getCachedProfile() {
4197
4432
  try {
4198
4433
  if (typeof window === "undefined") return null;
4199
- const cached = localStorage.getItem(CACHE_KEY);
4434
+ const cached = localStorage.getItem(CACHE_KEY2);
4200
4435
  if (!cached) {
4201
4436
  authLogger.debug("No cached profile found");
4202
4437
  return null;
@@ -4234,7 +4469,7 @@ function setCachedProfile(profile, options) {
4234
4469
  ttl: options?.ttl || DEFAULT_TTL
4235
4470
  };
4236
4471
  const encoded = encodeBase64(JSON.stringify(cachedData));
4237
- localStorage.setItem(CACHE_KEY, encoded);
4472
+ localStorage.setItem(CACHE_KEY2, encoded);
4238
4473
  authLogger.debug("Profile cached, TTL:", cachedData.ttl / 1e3, "seconds");
4239
4474
  } catch (error) {
4240
4475
  authLogger.error("Error writing cache:", error);
@@ -4244,7 +4479,7 @@ __name(setCachedProfile, "setCachedProfile");
4244
4479
  function clearProfileCache() {
4245
4480
  try {
4246
4481
  if (typeof window === "undefined") return;
4247
- localStorage.removeItem(CACHE_KEY);
4482
+ localStorage.removeItem(CACHE_KEY2);
4248
4483
  authLogger.debug("Cache cleared");
4249
4484
  } catch (error) {
4250
4485
  authLogger.error("Error clearing cache:", error);
@@ -4258,7 +4493,7 @@ __name(hasValidCache, "hasValidCache");
4258
4493
  function getCacheMetadata() {
4259
4494
  try {
4260
4495
  if (typeof window === "undefined") return null;
4261
- const cached = localStorage.getItem(CACHE_KEY);
4496
+ const cached = localStorage.getItem(CACHE_KEY2);
4262
4497
  if (!cached) return { exists: false };
4263
4498
  const decoded = decodeBase64(cached);
4264
4499
  const cachedData = JSON.parse(decoded);
@@ -4279,15 +4514,15 @@ function getCacheMetadata() {
4279
4514
  __name(getCacheMetadata, "getCacheMetadata");
4280
4515
 
4281
4516
  // src/auth/hooks/useDeleteAccount.ts
4282
- var import_react16 = require("react");
4517
+ var import_react18 = require("react");
4283
4518
  var useDeleteAccount = /* @__PURE__ */ __name(() => {
4284
- const [isLoading, setIsLoading] = (0, import_react16.useState)(false);
4285
- const [error, setError] = (0, import_react16.useState)(null);
4519
+ const [isLoading, setIsLoading] = (0, import_react18.useState)(false);
4520
+ const [error, setError] = (0, import_react18.useState)(null);
4286
4521
  const { logout } = useAuth();
4287
- const clearError = (0, import_react16.useCallback)(() => {
4522
+ const clearError = (0, import_react18.useCallback)(() => {
4288
4523
  setError(null);
4289
4524
  }, []);
4290
- const deleteAccount = (0, import_react16.useCallback)(async () => {
4525
+ const deleteAccount = (0, import_react18.useCallback)(async () => {
4291
4526
  setIsLoading(true);
4292
4527
  setError(null);
4293
4528
  try {
@@ -4317,13 +4552,13 @@ var useDeleteAccount = /* @__PURE__ */ __name(() => {
4317
4552
  }, "useDeleteAccount");
4318
4553
 
4319
4554
  // src/auth/context/AccountsContext.tsx
4320
- var import_react17 = require("react");
4555
+ var import_react19 = require("react");
4321
4556
 
4322
4557
  // src/_api/generated/_cfg_accounts/hooks/useCfgAccountsApiKeyRegenerateCreate.ts
4323
4558
  var import_mutation = __toESM(require("swr/mutation"), 1);
4324
4559
 
4325
4560
  // src/_api/generated/_cfg_accounts/hooks/useCfgAccountsApiKeyRetrieve.ts
4326
- var import_swr = __toESM(require("swr"), 1);
4561
+ var import_swr2 = __toESM(require("swr"), 1);
4327
4562
 
4328
4563
  // src/_api/generated/_cfg_accounts/hooks/useCfgAccountsApiKeyRevealCreate.ts
4329
4564
  var import_mutation2 = __toESM(require("swr/mutation"), 1);
@@ -4332,7 +4567,7 @@ var import_mutation2 = __toESM(require("swr/mutation"), 1);
4332
4567
  var import_mutation3 = __toESM(require("swr/mutation"), 1);
4333
4568
 
4334
4569
  // src/_api/generated/_cfg_accounts/hooks/useCfgAccountsOauthConnectionsList.ts
4335
- var import_swr2 = __toESM(require("swr"), 1);
4570
+ var import_swr3 = __toESM(require("swr"), 1);
4336
4571
 
4337
4572
  // src/_api/generated/_cfg_accounts/hooks/useCfgAccountsOauthDisconnectCreate.ts
4338
4573
  var import_mutation4 = __toESM(require("swr/mutation"), 1);
@@ -4343,16 +4578,19 @@ var import_mutation5 = __toESM(require("swr/mutation"), 1);
4343
4578
  // src/_api/generated/_cfg_accounts/hooks/useCfgAccountsOauthGithubCallbackCreate.ts
4344
4579
  var import_mutation6 = __toESM(require("swr/mutation"), 1);
4345
4580
 
4346
- // src/_api/generated/_cfg_accounts/hooks/useCfgAccountsOauthProvidersRetrieve.ts
4347
- var import_swr3 = __toESM(require("swr"), 1);
4581
+ // src/_api/generated/_cfg_accounts/hooks/useCfgAccountsOauthGoogleAuthorizeCreate.ts
4582
+ var import_mutation7 = __toESM(require("swr/mutation"), 1);
4583
+
4584
+ // src/_api/generated/_cfg_accounts/hooks/useCfgAccountsOauthGoogleCallbackCreate.ts
4585
+ var import_mutation8 = __toESM(require("swr/mutation"), 1);
4348
4586
 
4349
4587
  // src/_api/generated/_cfg_accounts/hooks/useCfgAccountsOtpConsentPolicyRetrieve.ts
4350
4588
  var import_swr4 = __toESM(require("swr"), 1);
4351
4589
 
4352
4590
  // src/_api/generated/_cfg_accounts/hooks/useCfgAccountsOtpRequestCreate.ts
4353
- var import_mutation7 = __toESM(require("swr/mutation"), 1);
4591
+ var import_mutation9 = __toESM(require("swr/mutation"), 1);
4354
4592
  function useCfgAccountsOtpRequestCreate(config) {
4355
- return (0, import_mutation7.default)(
4593
+ return (0, import_mutation9.default)(
4356
4594
  ["cfg_accounts_otp_request_create"],
4357
4595
  async (_key, { arg }) => {
4358
4596
  const res = await CfgAccountsOtp.cfgAccountsOtpRequestCreate({ ...arg, throwOnError: true });
@@ -4399,9 +4637,9 @@ function useCfgAccountsOtpRequestCreate(config) {
4399
4637
  __name(useCfgAccountsOtpRequestCreate, "useCfgAccountsOtpRequestCreate");
4400
4638
 
4401
4639
  // src/_api/generated/_cfg_accounts/hooks/useCfgAccountsOtpVerifyCreate.ts
4402
- var import_mutation8 = __toESM(require("swr/mutation"), 1);
4640
+ var import_mutation10 = __toESM(require("swr/mutation"), 1);
4403
4641
  function useCfgAccountsOtpVerifyCreate(config) {
4404
- return (0, import_mutation8.default)(
4642
+ return (0, import_mutation10.default)(
4405
4643
  ["cfg_accounts_otp_verify_create"],
4406
4644
  async (_key, { arg }) => {
4407
4645
  const res = await CfgAccountsOtp.cfgAccountsOtpVerifyCreate({ ...arg, throwOnError: true });
@@ -4448,9 +4686,9 @@ function useCfgAccountsOtpVerifyCreate(config) {
4448
4686
  __name(useCfgAccountsOtpVerifyCreate, "useCfgAccountsOtpVerifyCreate");
4449
4687
 
4450
4688
  // src/_api/generated/_cfg_accounts/hooks/useCfgAccountsProfileAvatarCreate.ts
4451
- var import_mutation9 = __toESM(require("swr/mutation"), 1);
4689
+ var import_mutation11 = __toESM(require("swr/mutation"), 1);
4452
4690
  function useCfgAccountsProfileAvatarCreate(config) {
4453
- return (0, import_mutation9.default)(
4691
+ return (0, import_mutation11.default)(
4454
4692
  ["cfg_accounts_profile_avatar_create"],
4455
4693
  async (_key, { arg }) => {
4456
4694
  const res = await CfgAccountsProfile.cfgAccountsProfileAvatarCreate({ ...arg, throwOnError: true });
@@ -4497,15 +4735,15 @@ function useCfgAccountsProfileAvatarCreate(config) {
4497
4735
  __name(useCfgAccountsProfileAvatarCreate, "useCfgAccountsProfileAvatarCreate");
4498
4736
 
4499
4737
  // src/_api/generated/_cfg_accounts/hooks/useCfgAccountsProfileDeleteCreate.ts
4500
- var import_mutation10 = __toESM(require("swr/mutation"), 1);
4738
+ var import_mutation12 = __toESM(require("swr/mutation"), 1);
4501
4739
 
4502
4740
  // src/_api/generated/_cfg_accounts/hooks/useCfgAccountsProfilePartialPartialUpdate.ts
4503
- var import_mutation11 = __toESM(require("swr/mutation"), 1);
4741
+ var import_mutation13 = __toESM(require("swr/mutation"), 1);
4504
4742
 
4505
4743
  // src/_api/generated/_cfg_accounts/hooks/useCfgAccountsProfilePartialUpdate.ts
4506
- var import_mutation12 = __toESM(require("swr/mutation"), 1);
4744
+ var import_mutation14 = __toESM(require("swr/mutation"), 1);
4507
4745
  function useCfgAccountsProfilePartialUpdate(config) {
4508
- return (0, import_mutation12.default)(
4746
+ return (0, import_mutation14.default)(
4509
4747
  ["cfg_accounts_profile_partial_update"],
4510
4748
  async (_key, { arg }) => {
4511
4749
  const res = await CfgAccountsProfile.cfgAccountsProfilePartialUpdate({ ...arg, throwOnError: true });
@@ -4555,12 +4793,12 @@ __name(useCfgAccountsProfilePartialUpdate, "useCfgAccountsProfilePartialUpdate")
4555
4793
  var import_swr5 = __toESM(require("swr"), 1);
4556
4794
 
4557
4795
  // src/_api/generated/_cfg_accounts/hooks/useCfgAccountsProfileUpdatePartialUpdate.ts
4558
- var import_mutation13 = __toESM(require("swr/mutation"), 1);
4796
+ var import_mutation15 = __toESM(require("swr/mutation"), 1);
4559
4797
 
4560
4798
  // src/_api/generated/_cfg_accounts/hooks/useCfgAccountsProfileUpdateUpdate.ts
4561
- var import_mutation14 = __toESM(require("swr/mutation"), 1);
4799
+ var import_mutation16 = __toESM(require("swr/mutation"), 1);
4562
4800
  function useCfgAccountsProfileUpdateUpdate(config) {
4563
- return (0, import_mutation14.default)(
4801
+ return (0, import_mutation16.default)(
4564
4802
  ["cfg_accounts_profile_update_update"],
4565
4803
  async (_key, { arg }) => {
4566
4804
  const res = await CfgAccountsProfile.cfgAccountsProfileUpdateUpdate({ ...arg, throwOnError: true });
@@ -4607,12 +4845,12 @@ function useCfgAccountsProfileUpdateUpdate(config) {
4607
4845
  __name(useCfgAccountsProfileUpdateUpdate, "useCfgAccountsProfileUpdateUpdate");
4608
4846
 
4609
4847
  // src/_api/generated/_cfg_accounts/hooks/useCfgAccountsTokenBlacklistCreate.ts
4610
- var import_mutation15 = __toESM(require("swr/mutation"), 1);
4848
+ var import_mutation17 = __toESM(require("swr/mutation"), 1);
4611
4849
 
4612
4850
  // src/_api/generated/_cfg_accounts/hooks/useCfgAccountsTokenCreate.ts
4613
- var import_mutation16 = __toESM(require("swr/mutation"), 1);
4851
+ var import_mutation18 = __toESM(require("swr/mutation"), 1);
4614
4852
  function useCfgAccountsTokenCreate(config) {
4615
- return (0, import_mutation16.default)(
4853
+ return (0, import_mutation18.default)(
4616
4854
  ["cfg_accounts_token_create"],
4617
4855
  async (_key, { arg }) => {
4618
4856
  const res = await CfgAccountsAuth.cfgAccountsTokenCreate({ ...arg, throwOnError: true });
@@ -4659,7 +4897,7 @@ function useCfgAccountsTokenCreate(config) {
4659
4897
  __name(useCfgAccountsTokenCreate, "useCfgAccountsTokenCreate");
4660
4898
 
4661
4899
  // src/_api/generated/_cfg_accounts/hooks/useCfgAccountsTokenRefreshCreate.ts
4662
- var import_mutation17 = __toESM(require("swr/mutation"), 1);
4900
+ var import_mutation19 = __toESM(require("swr/mutation"), 1);
4663
4901
 
4664
4902
  // src/auth/context/AccountsContext.tsx
4665
4903
  var import_jsx_runtime = require("react/jsx-runtime");
@@ -4674,21 +4912,21 @@ function hasApiOrigin() {
4674
4912
  }
4675
4913
  }
4676
4914
  __name(hasApiOrigin, "hasApiOrigin");
4677
- var AccountsContext = (0, import_react17.createContext)(void 0);
4915
+ var AccountsContext = (0, import_react19.createContext)(void 0);
4678
4916
  function AccountsProvider({ children }) {
4679
- const [profile, setProfile] = (0, import_react17.useState)(() => {
4917
+ const [profile, setProfile] = (0, import_react19.useState)(() => {
4680
4918
  const cached = getCachedProfile();
4681
4919
  return cached || void 0;
4682
4920
  });
4683
- const [isLoadingProfile, setIsLoadingProfile] = (0, import_react17.useState)(false);
4684
- const [profileError, setProfileError] = (0, import_react17.useState)(null);
4685
- const profileRef = (0, import_react17.useRef)(profile);
4686
- const isLoadingRef = (0, import_react17.useRef)(false);
4687
- const fetchSeqRef = (0, import_react17.useRef)(0);
4688
- (0, import_react17.useEffect)(() => {
4921
+ const [isLoadingProfile, setIsLoadingProfile] = (0, import_react19.useState)(false);
4922
+ const [profileError, setProfileError] = (0, import_react19.useState)(null);
4923
+ const profileRef = (0, import_react19.useRef)(profile);
4924
+ const isLoadingRef = (0, import_react19.useRef)(false);
4925
+ const fetchSeqRef = (0, import_react19.useRef)(0);
4926
+ (0, import_react19.useEffect)(() => {
4689
4927
  profileRef.current = profile;
4690
4928
  }, [profile]);
4691
- (0, import_react17.useEffect)(() => {
4929
+ (0, import_react19.useEffect)(() => {
4692
4930
  isLoadingRef.current = isLoadingProfile;
4693
4931
  }, [isLoadingProfile]);
4694
4932
  const { trigger: triggerProfileUpdate } = useCfgAccountsProfileUpdateUpdate();
@@ -4697,7 +4935,7 @@ function AccountsProvider({ children }) {
4697
4935
  const { trigger: triggerOtpRequest } = useCfgAccountsOtpRequestCreate();
4698
4936
  const { trigger: triggerOtpVerify } = useCfgAccountsOtpVerifyCreate();
4699
4937
  const { trigger: triggerPasswordLogin } = useCfgAccountsTokenCreate();
4700
- const refreshProfile = (0, import_react17.useCallback)(async (options) => {
4938
+ const refreshProfile = (0, import_react19.useCallback)(async (options) => {
4701
4939
  const { callerId, force } = options || {};
4702
4940
  if (!hasApiOrigin()) {
4703
4941
  authLogger.debug(`No API origin configured, skipping profile fetch (caller: ${callerId})`);
@@ -4731,26 +4969,26 @@ function AccountsProvider({ children }) {
4731
4969
  }
4732
4970
  }
4733
4971
  }, []);
4734
- const updateProfile = (0, import_react17.useCallback)(async (data) => {
4972
+ const updateProfile = (0, import_react19.useCallback)(async (data) => {
4735
4973
  await triggerProfileUpdate({ body: data });
4736
4974
  const user = await refreshProfile({ callerId: "updateProfile", force: true });
4737
4975
  return user;
4738
4976
  }, [triggerProfileUpdate, refreshProfile]);
4739
- const partialUpdateProfile = (0, import_react17.useCallback)(async (data) => {
4977
+ const partialUpdateProfile = (0, import_react19.useCallback)(async (data) => {
4740
4978
  await triggerProfilePartialUpdate({ body: data });
4741
4979
  const user = await refreshProfile({ callerId: "partialUpdateProfile", force: true });
4742
4980
  return user;
4743
4981
  }, [triggerProfilePartialUpdate, refreshProfile]);
4744
- const uploadAvatar = (0, import_react17.useCallback)(async (avatar) => {
4982
+ const uploadAvatar = (0, import_react19.useCallback)(async (avatar) => {
4745
4983
  await triggerAvatar({ body: { avatar } });
4746
4984
  const user = await refreshProfile({ callerId: "uploadAvatar", force: true });
4747
4985
  return user;
4748
4986
  }, [triggerAvatar, refreshProfile]);
4749
- const requestOTP = (0, import_react17.useCallback)(async (data) => {
4987
+ const requestOTP = (0, import_react19.useCallback)(async (data) => {
4750
4988
  const result = await triggerOtpRequest({ body: data });
4751
4989
  return result;
4752
4990
  }, [triggerOtpRequest]);
4753
- const settleLoginEnvelope = (0, import_react17.useCallback)(async (result, callerId) => {
4991
+ const settleLoginEnvelope = (0, import_react19.useCallback)(async (result, callerId) => {
4754
4992
  if (result.requires_2fa && result.session_id) {
4755
4993
  authLogger.info("2FA required, session:", result.session_id);
4756
4994
  return;
@@ -4764,17 +5002,17 @@ function AccountsProvider({ children }) {
4764
5002
  }
4765
5003
  }
4766
5004
  }, [refreshProfile]);
4767
- const verifyOTP = (0, import_react17.useCallback)(async (data) => {
5005
+ const verifyOTP = (0, import_react19.useCallback)(async (data) => {
4768
5006
  const result = await triggerOtpVerify({ body: data });
4769
5007
  await settleLoginEnvelope(result, "verifyOTP");
4770
5008
  return result;
4771
5009
  }, [triggerOtpVerify, settleLoginEnvelope]);
4772
- const loginWithPassword = (0, import_react17.useCallback)(async (data) => {
5010
+ const loginWithPassword = (0, import_react19.useCallback)(async (data) => {
4773
5011
  const result = await triggerPasswordLogin({ body: data });
4774
5012
  await settleLoginEnvelope(result, "loginWithPassword");
4775
5013
  return result;
4776
5014
  }, [triggerPasswordLogin, settleLoginEnvelope]);
4777
- const logout = (0, import_react17.useCallback)(() => {
5015
+ const logout = (0, import_react19.useCallback)(() => {
4778
5016
  const refresh = auth.getRefreshToken();
4779
5017
  if (refresh) {
4780
5018
  CfgAccountsAuth.cfgAccountsTokenBlacklistCreate({ body: { refresh } }).catch(() => {
@@ -4786,7 +5024,7 @@ function AccountsProvider({ children }) {
4786
5024
  setProfileError(null);
4787
5025
  clearProfileCache();
4788
5026
  }, []);
4789
- const value = (0, import_react17.useMemo)(() => ({
5027
+ const value = (0, import_react19.useMemo)(() => ({
4790
5028
  profile,
4791
5029
  isLoadingProfile,
4792
5030
  profileError,
@@ -4815,7 +5053,7 @@ function AccountsProvider({ children }) {
4815
5053
  }
4816
5054
  __name(AccountsProvider, "AccountsProvider");
4817
5055
  function useAccountsContext() {
4818
- const context = (0, import_react17.useContext)(AccountsContext);
5056
+ const context = (0, import_react19.useContext)(AccountsContext);
4819
5057
  if (!context) {
4820
5058
  throw new Error("useAccountsContext must be used within AccountsProvider");
4821
5059
  }
@@ -4836,7 +5074,7 @@ var resolveAuthRoutes = /* @__PURE__ */ __name((routes) => ({
4836
5074
  defaultAuthCallback: routes?.defaultAuthCallback || routes?.auth || defaultRoutes.defaultAuthCallback
4837
5075
  }), "resolveAuthRoutes");
4838
5076
  var EMAIL_STORAGE_KEY = CFG_KEYS.email.key;
4839
- var AuthContext = (0, import_react18.createContext)(void 0);
5077
+ var AuthContext = (0, import_react20.createContext)(void 0);
4840
5078
  var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
4841
5079
  const accounts = useAccountsContext();
4842
5080
  const session = useSession();
@@ -4848,28 +5086,28 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
4848
5086
  EMAIL_STORAGE_KEY,
4849
5087
  null
4850
5088
  );
4851
- const routes = (0, import_react18.useMemo)(() => resolveAuthRoutes(config?.routes), [config?.routes]);
4852
- const routesRef = (0, import_react18.useRef)(routes);
4853
- (0, import_react18.useEffect)(() => {
5089
+ const routes = (0, import_react20.useMemo)(() => resolveAuthRoutes(config?.routes), [config?.routes]);
5090
+ const routesRef = (0, import_react20.useRef)(routes);
5091
+ (0, import_react20.useEffect)(() => {
4854
5092
  routesRef.current = routes;
4855
5093
  }, [routes]);
4856
5094
  const redirectManager = useAuthRedirectManager({
4857
5095
  fallbackUrl: routes.defaultCallback,
4858
5096
  clearOnUse: true
4859
5097
  });
4860
- const configRef = (0, import_react18.useRef)(config);
4861
- (0, import_react18.useEffect)(() => {
5098
+ const configRef = (0, import_react20.useRef)(config);
5099
+ (0, import_react20.useEffect)(() => {
4862
5100
  configRef.current = config;
4863
5101
  }, [config]);
4864
- const accountsRef = (0, import_react18.useRef)(accounts);
4865
- (0, import_react18.useEffect)(() => {
5102
+ const accountsRef = (0, import_react20.useRef)(accounts);
5103
+ (0, import_react20.useEffect)(() => {
4866
5104
  accountsRef.current = accounts;
4867
5105
  }, [accounts]);
4868
- const pendingManualNavRef = (0, import_react18.useRef)(false);
4869
- const [profileSettled, setProfileSettled] = (0, import_react18.useState)(false);
5106
+ const pendingManualNavRef = (0, import_react20.useRef)(false);
5107
+ const [profileSettled, setProfileSettled] = (0, import_react20.useState)(false);
4870
5108
  const hasProfile = Boolean(accounts.profile);
4871
- const profileAttemptedRef = (0, import_react18.useRef)(false);
4872
- (0, import_react18.useEffect)(() => {
5109
+ const profileAttemptedRef = (0, import_react20.useRef)(false);
5110
+ (0, import_react20.useEffect)(() => {
4873
5111
  if (!isAuthenticated) {
4874
5112
  profileAttemptedRef.current = false;
4875
5113
  const hasTokens = Boolean(auth.getToken() || auth.getRefreshToken());
@@ -4897,8 +5135,8 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
4897
5135
  };
4898
5136
  }, [isAuthenticated, hasProfile]);
4899
5137
  const isLoading = !profileSettled;
4900
- const expiredHandledRef = (0, import_react18.useRef)(false);
4901
- (0, import_react18.useEffect)(() => {
5138
+ const expiredHandledRef = (0, import_react20.useRef)(false);
5139
+ (0, import_react20.useEffect)(() => {
4902
5140
  const unsubscribe = auth.onSessionExpired(() => {
4903
5141
  if (expiredHandledRef.current) return;
4904
5142
  expiredHandledRef.current = true;
@@ -4911,7 +5149,7 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
4911
5149
  });
4912
5150
  return unsubscribe;
4913
5151
  }, [router]);
4914
- (0, import_react18.useEffect)(() => {
5152
+ (0, import_react20.useEffect)(() => {
4915
5153
  if (!isAuthenticated || pendingManualNavRef.current) return;
4916
5154
  if (pathname === routes.auth && !queryParams.get("flow")) {
4917
5155
  const saved = redirectManager.hasRedirect() ? redirectManager.getRedirect() : null;
@@ -4919,7 +5157,7 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
4919
5157
  router.push(saved || routes.defaultCallback);
4920
5158
  }
4921
5159
  }, [isAuthenticated, pathname, queryParams, routes, router, redirectManager]);
4922
- const loadCurrentProfile = (0, import_react18.useCallback)(async (callerId) => {
5160
+ const loadCurrentProfile = (0, import_react20.useCallback)(async (callerId) => {
4923
5161
  if (!auth.isAuthenticated()) {
4924
5162
  throw new Error("No valid authentication token");
4925
5163
  }
@@ -4927,7 +5165,7 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
4927
5165
  callerId: callerId || "AuthContext.loadCurrentProfile"
4928
5166
  });
4929
5167
  }, []);
4930
- const checkAuthAndRedirect = (0, import_react18.useCallback)(async () => {
5168
+ const checkAuthAndRedirect = (0, import_react20.useCallback)(async () => {
4931
5169
  if (auth.isAuthenticated()) {
4932
5170
  try {
4933
5171
  await loadCurrentProfile("checkAuthAndRedirect");
@@ -4939,7 +5177,7 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
4939
5177
  router.push(routesRef.current.defaultAuthCallback);
4940
5178
  }
4941
5179
  }, [loadCurrentProfile, router]);
4942
- const requestOTP = (0, import_react18.useCallback)(
5180
+ const requestOTP = (0, import_react20.useCallback)(
4943
5181
  async (identifier, sourceUrl, consent) => {
4944
5182
  auth.clearSession();
4945
5183
  try {
@@ -4981,7 +5219,7 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
4981
5219
  },
4982
5220
  []
4983
5221
  );
4984
- const verifyOTP = (0, import_react18.useCallback)(
5222
+ const verifyOTP = (0, import_react20.useCallback)(
4985
5223
  async (identifier, otpCode, sourceUrl, redirectUrl, skipRedirect) => {
4986
5224
  try {
4987
5225
  pendingManualNavRef.current = Boolean(skipRedirect);
@@ -5041,7 +5279,7 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
5041
5279
  },
5042
5280
  [setStoredEmail, redirectManager, router]
5043
5281
  );
5044
- const login = (0, import_react18.useCallback)(
5282
+ const login = (0, import_react20.useCallback)(
5045
5283
  async (email, password, options) => {
5046
5284
  const { redirectUrl, skipRedirect } = options || {};
5047
5285
  try {
@@ -5106,7 +5344,7 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
5106
5344
  },
5107
5345
  [setStoredEmail, redirectManager, router]
5108
5346
  );
5109
- const refreshToken = (0, import_react18.useCallback)(async () => {
5347
+ const refreshToken = (0, import_react20.useCallback)(async () => {
5110
5348
  const access = await auth.refreshNow();
5111
5349
  if (access) {
5112
5350
  Analytics.event("auth_token_refresh" /* AUTH_TOKEN_REFRESH */, {
@@ -5119,7 +5357,7 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
5119
5357
  });
5120
5358
  return { success: false, message: "Error refreshing token" };
5121
5359
  }, []);
5122
- const logout = (0, import_react18.useCallback)(() => {
5360
+ const logout = (0, import_react20.useCallback)(() => {
5123
5361
  Analytics.event("auth_logout" /* AUTH_LOGOUT */, {
5124
5362
  category: "auth" /* AUTH */
5125
5363
  });
@@ -5128,21 +5366,21 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
5128
5366
  }, [router]);
5129
5367
  const user = accounts.profile ?? null;
5130
5368
  const isAdminUser = Boolean(user?.is_staff || user?.is_superuser);
5131
- (0, import_react18.useEffect)(() => {
5369
+ (0, import_react20.useEffect)(() => {
5132
5370
  applyRoleLogPolicy({ isAdmin: isAdminUser });
5133
5371
  }, [isAdminUser]);
5134
- const updateProfile = (0, import_react18.useCallback)(
5372
+ const updateProfile = (0, import_react20.useCallback)(
5135
5373
  async (data) => {
5136
5374
  const result = await accountsRef.current.partialUpdateProfile(data);
5137
5375
  return result;
5138
5376
  },
5139
5377
  []
5140
5378
  );
5141
- const uploadAvatar = (0, import_react18.useCallback)(async (avatar) => {
5379
+ const uploadAvatar = (0, import_react20.useCallback)(async (avatar) => {
5142
5380
  const result = await accountsRef.current.uploadAvatar(avatar);
5143
5381
  return result;
5144
5382
  }, []);
5145
- const value = (0, import_react18.useMemo)(
5383
+ const value = (0, import_react20.useMemo)(
5146
5384
  () => ({
5147
5385
  user,
5148
5386
  isLoading,
@@ -5198,7 +5436,7 @@ function AuthProviderRaw({ children, config, enabled = true }) {
5198
5436
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AccountsProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AuthProviderInternal, { config, children }) });
5199
5437
  }
5200
5438
  __name(AuthProviderRaw, "AuthProviderRaw");
5201
- var AuthProvider = (0, import_react18.memo)(AuthProviderRaw);
5439
+ var AuthProvider = (0, import_react20.memo)(AuthProviderRaw);
5202
5440
  var defaultAuthState = {
5203
5441
  user: null,
5204
5442
  isLoading: false,
@@ -5254,7 +5492,7 @@ var defaultAuthState = {
5254
5492
  }, "uploadAvatar")
5255
5493
  };
5256
5494
  var useAuth = /* @__PURE__ */ __name(() => {
5257
- const context = (0, import_react18.useContext)(AuthContext);
5495
+ const context = (0, import_react20.useContext)(AuthContext);
5258
5496
  if (context === void 0) {
5259
5497
  if (isBrowser2 && isDev) {
5260
5498
  authLogger.debug("useAuth called outside AuthProvider, returning default state");