@burdenoff/microfe-auth 2026.510.127

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 (301) hide show
  1. package/README.md +12 -0
  2. package/dist/_virtual/_rolldown/runtime.js +13 -0
  3. package/dist/auth/AuthRoot.d.ts +30 -0
  4. package/dist/auth/AuthRoot.d.ts.map +1 -0
  5. package/dist/auth/AuthRoot.js +82 -0
  6. package/dist/auth/AuthRoot.js.map +1 -0
  7. package/dist/auth/AuthRoutes.d.ts +29 -0
  8. package/dist/auth/AuthRoutes.d.ts.map +1 -0
  9. package/dist/auth/AuthRoutes.js +271 -0
  10. package/dist/auth/AuthRoutes.js.map +1 -0
  11. package/dist/auth/components/AuthIcons.d.ts +17 -0
  12. package/dist/auth/components/AuthIcons.d.ts.map +1 -0
  13. package/dist/auth/components/AuthIcons.js +197 -0
  14. package/dist/auth/components/AuthIcons.js.map +1 -0
  15. package/dist/auth/components/AuthLayout.d.ts +17 -0
  16. package/dist/auth/components/AuthLayout.d.ts.map +1 -0
  17. package/dist/auth/components/AuthLayout.js +237 -0
  18. package/dist/auth/components/AuthLayout.js.map +1 -0
  19. package/dist/auth/components/CaptchaV2.d.ts +16 -0
  20. package/dist/auth/components/CaptchaV2.d.ts.map +1 -0
  21. package/dist/auth/components/CaptchaV2.js +47 -0
  22. package/dist/auth/components/CaptchaV2.js.map +1 -0
  23. package/dist/auth/components/ConfirmActionDialog.d.ts +16 -0
  24. package/dist/auth/components/ConfirmActionDialog.d.ts.map +1 -0
  25. package/dist/auth/components/ConfirmActionDialog.js +68 -0
  26. package/dist/auth/components/ConfirmActionDialog.js.map +1 -0
  27. package/dist/auth/components/index.d.ts +4 -0
  28. package/dist/auth/components/index.d.ts.map +1 -0
  29. package/dist/auth/components/profile/UserProfileMenu.d.ts +42 -0
  30. package/dist/auth/components/profile/UserProfileMenu.d.ts.map +1 -0
  31. package/dist/auth/components/profile/UserProfileMenu.js +91 -0
  32. package/dist/auth/components/profile/UserProfileMenu.js.map +1 -0
  33. package/dist/auth/components/workspace/WorkspaceSelector.d.ts +76 -0
  34. package/dist/auth/components/workspace/WorkspaceSelector.d.ts.map +1 -0
  35. package/dist/auth/components/workspace/WorkspaceSelector.js +240 -0
  36. package/dist/auth/components/workspace/WorkspaceSelector.js.map +1 -0
  37. package/dist/auth/constants/permissions.d.ts +30 -0
  38. package/dist/auth/constants/permissions.d.ts.map +1 -0
  39. package/dist/auth/constants/permissions.js +18 -0
  40. package/dist/auth/constants/permissions.js.map +1 -0
  41. package/dist/auth/constants/sessionKeys.d.ts +18 -0
  42. package/dist/auth/constants/sessionKeys.d.ts.map +1 -0
  43. package/dist/auth/constants/sessionKeys.js +6 -0
  44. package/dist/auth/constants/sessionKeys.js.map +1 -0
  45. package/dist/auth/hooks/index.d.ts +18 -0
  46. package/dist/auth/hooks/index.d.ts.map +1 -0
  47. package/dist/auth/hooks/index.js +16 -0
  48. package/dist/auth/hooks/useAccountOperations.d.ts +19 -0
  49. package/dist/auth/hooks/useAccountOperations.d.ts.map +1 -0
  50. package/dist/auth/hooks/useAccountOperations.js +52 -0
  51. package/dist/auth/hooks/useAccountOperations.js.map +1 -0
  52. package/dist/auth/hooks/useApiKeyOperations.d.ts +22 -0
  53. package/dist/auth/hooks/useApiKeyOperations.d.ts.map +1 -0
  54. package/dist/auth/hooks/useApiKeyOperations.js +4 -0
  55. package/dist/auth/hooks/useAppOperations.d.ts +26 -0
  56. package/dist/auth/hooks/useAppOperations.d.ts.map +1 -0
  57. package/dist/auth/hooks/useAppOperations.js +4 -0
  58. package/dist/auth/hooks/useAuthOperations.d.ts +57 -0
  59. package/dist/auth/hooks/useAuthOperations.d.ts.map +1 -0
  60. package/dist/auth/hooks/useAuthOperations.js +236 -0
  61. package/dist/auth/hooks/useAuthOperations.js.map +1 -0
  62. package/dist/auth/hooks/useAuthPermissions.d.ts +20 -0
  63. package/dist/auth/hooks/useAuthPermissions.d.ts.map +1 -0
  64. package/dist/auth/hooks/useAuthPermissions.js +22 -0
  65. package/dist/auth/hooks/useAuthPermissions.js.map +1 -0
  66. package/dist/auth/hooks/useCaptchaV3.d.ts +13 -0
  67. package/dist/auth/hooks/useCaptchaV3.d.ts.map +1 -0
  68. package/dist/auth/hooks/useCaptchaV3.js +19 -0
  69. package/dist/auth/hooks/useCaptchaV3.js.map +1 -0
  70. package/dist/auth/hooks/useContextSwitcherData.d.ts +106 -0
  71. package/dist/auth/hooks/useContextSwitcherData.d.ts.map +1 -0
  72. package/dist/auth/hooks/useContextSwitcherData.js +466 -0
  73. package/dist/auth/hooks/useContextSwitcherData.js.map +1 -0
  74. package/dist/auth/hooks/useDelegationOperations.d.ts +25 -0
  75. package/dist/auth/hooks/useDelegationOperations.d.ts.map +1 -0
  76. package/dist/auth/hooks/useDelegationOperations.js +4 -0
  77. package/dist/auth/hooks/useMfaOperations.d.ts +18 -0
  78. package/dist/auth/hooks/useMfaOperations.d.ts.map +1 -0
  79. package/dist/auth/hooks/useMfaOperations.js +103 -0
  80. package/dist/auth/hooks/useMfaOperations.js.map +1 -0
  81. package/dist/auth/hooks/useMyWorkspaces.d.ts +45 -0
  82. package/dist/auth/hooks/useMyWorkspaces.d.ts.map +1 -0
  83. package/dist/auth/hooks/useMyWorkspaces.js +140 -0
  84. package/dist/auth/hooks/useMyWorkspaces.js.map +1 -0
  85. package/dist/auth/hooks/useOAuthOperations.d.ts +19 -0
  86. package/dist/auth/hooks/useOAuthOperations.d.ts.map +1 -0
  87. package/dist/auth/hooks/useOAuthOperations.js +103 -0
  88. package/dist/auth/hooks/useOAuthOperations.js.map +1 -0
  89. package/dist/auth/hooks/usePasswordOperations.d.ts +13 -0
  90. package/dist/auth/hooks/usePasswordOperations.d.ts.map +1 -0
  91. package/dist/auth/hooks/usePasswordOperations.js +56 -0
  92. package/dist/auth/hooks/usePasswordOperations.js.map +1 -0
  93. package/dist/auth/hooks/useSessionOperations.d.ts +41 -0
  94. package/dist/auth/hooks/useSessionOperations.d.ts.map +1 -0
  95. package/dist/auth/hooks/useSessionOperations.js +59 -0
  96. package/dist/auth/hooks/useSessionOperations.js.map +1 -0
  97. package/dist/auth/hooks/useSsoOperations.d.ts +65 -0
  98. package/dist/auth/hooks/useSsoOperations.d.ts.map +1 -0
  99. package/dist/auth/hooks/useSsoOperations.js +236 -0
  100. package/dist/auth/hooks/useSsoOperations.js.map +1 -0
  101. package/dist/auth/hooks/useTokenRefresh.d.ts +56 -0
  102. package/dist/auth/hooks/useTokenRefresh.d.ts.map +1 -0
  103. package/dist/auth/hooks/useTokenRefresh.js +53 -0
  104. package/dist/auth/hooks/useTokenRefresh.js.map +1 -0
  105. package/dist/auth/hooks/useUserOperations.d.ts +32 -0
  106. package/dist/auth/hooks/useUserOperations.d.ts.map +1 -0
  107. package/dist/auth/hooks/useUserOperations.js +100 -0
  108. package/dist/auth/hooks/useUserOperations.js.map +1 -0
  109. package/dist/auth/hooks/useWorkspaceOperations.d.ts +35 -0
  110. package/dist/auth/hooks/useWorkspaceOperations.d.ts.map +1 -0
  111. package/dist/auth/hooks/useWorkspaceOperations.js +35 -0
  112. package/dist/auth/hooks/useWorkspaceOperations.js.map +1 -0
  113. package/dist/auth/hooks/useWorkspaceToken.d.ts +56 -0
  114. package/dist/auth/hooks/useWorkspaceToken.d.ts.map +1 -0
  115. package/dist/auth/hooks/useWorkspaceToken.js +94 -0
  116. package/dist/auth/hooks/useWorkspaceToken.js.map +1 -0
  117. package/dist/auth/index.d.ts +63 -0
  118. package/dist/auth/index.d.ts.map +1 -0
  119. package/dist/auth/index.js +18 -0
  120. package/dist/auth/pages/ApiKeysPage.d.ts +5 -0
  121. package/dist/auth/pages/ApiKeysPage.d.ts.map +1 -0
  122. package/dist/auth/pages/AppsPage.d.ts +5 -0
  123. package/dist/auth/pages/AppsPage.d.ts.map +1 -0
  124. package/dist/auth/pages/AuditLogPage.d.ts +5 -0
  125. package/dist/auth/pages/AuditLogPage.d.ts.map +1 -0
  126. package/dist/auth/pages/AuditLogPage.js +129 -0
  127. package/dist/auth/pages/AuditLogPage.js.map +1 -0
  128. package/dist/auth/pages/DelegationsPage.d.ts +5 -0
  129. package/dist/auth/pages/DelegationsPage.d.ts.map +1 -0
  130. package/dist/auth/pages/EmailVerifyPage.d.ts +5 -0
  131. package/dist/auth/pages/EmailVerifyPage.d.ts.map +1 -0
  132. package/dist/auth/pages/EmailVerifyPage.js +166 -0
  133. package/dist/auth/pages/EmailVerifyPage.js.map +1 -0
  134. package/dist/auth/pages/LoginPage.d.ts +6 -0
  135. package/dist/auth/pages/LoginPage.d.ts.map +1 -0
  136. package/dist/auth/pages/LoginPage.js +575 -0
  137. package/dist/auth/pages/LoginPage.js.map +1 -0
  138. package/dist/auth/pages/MagicLinkPage.d.ts +6 -0
  139. package/dist/auth/pages/MagicLinkPage.d.ts.map +1 -0
  140. package/dist/auth/pages/MagicLinkPage.js +219 -0
  141. package/dist/auth/pages/MagicLinkPage.js.map +1 -0
  142. package/dist/auth/pages/MfaSetupPage.d.ts +5 -0
  143. package/dist/auth/pages/MfaSetupPage.d.ts.map +1 -0
  144. package/dist/auth/pages/MfaSetupPage.js +341 -0
  145. package/dist/auth/pages/MfaSetupPage.js.map +1 -0
  146. package/dist/auth/pages/MfaVerifyPage.d.ts +7 -0
  147. package/dist/auth/pages/MfaVerifyPage.d.ts.map +1 -0
  148. package/dist/auth/pages/MfaVerifyPage.js +189 -0
  149. package/dist/auth/pages/MfaVerifyPage.js.map +1 -0
  150. package/dist/auth/pages/OAuthCallbackPage.d.ts +7 -0
  151. package/dist/auth/pages/OAuthCallbackPage.d.ts.map +1 -0
  152. package/dist/auth/pages/OAuthCallbackPage.js +100 -0
  153. package/dist/auth/pages/OAuthCallbackPage.js.map +1 -0
  154. package/dist/auth/pages/PasswordResetPage.d.ts +6 -0
  155. package/dist/auth/pages/PasswordResetPage.d.ts.map +1 -0
  156. package/dist/auth/pages/PasswordResetPage.js +352 -0
  157. package/dist/auth/pages/PasswordResetPage.js.map +1 -0
  158. package/dist/auth/pages/ReactivatePage.d.ts +6 -0
  159. package/dist/auth/pages/ReactivatePage.d.ts.map +1 -0
  160. package/dist/auth/pages/ReactivatePage.js +217 -0
  161. package/dist/auth/pages/ReactivatePage.js.map +1 -0
  162. package/dist/auth/pages/RegisterPage.d.ts +5 -0
  163. package/dist/auth/pages/RegisterPage.d.ts.map +1 -0
  164. package/dist/auth/pages/RegisterPage.js +439 -0
  165. package/dist/auth/pages/RegisterPage.js.map +1 -0
  166. package/dist/auth/pages/SSORelayCallbackPage.d.ts +8 -0
  167. package/dist/auth/pages/SSORelayCallbackPage.d.ts.map +1 -0
  168. package/dist/auth/pages/SSORelayCallbackPage.js +48 -0
  169. package/dist/auth/pages/SSORelayCallbackPage.js.map +1 -0
  170. package/dist/auth/pages/SSORelayPage.d.ts +18 -0
  171. package/dist/auth/pages/SSORelayPage.d.ts.map +1 -0
  172. package/dist/auth/pages/SSORelayPage.js +134 -0
  173. package/dist/auth/pages/SSORelayPage.js.map +1 -0
  174. package/dist/auth/pages/SecurityPage.d.ts +5 -0
  175. package/dist/auth/pages/SecurityPage.d.ts.map +1 -0
  176. package/dist/auth/pages/SecurityPage.js +587 -0
  177. package/dist/auth/pages/SecurityPage.js.map +1 -0
  178. package/dist/auth/pages/SessionBridgePage.d.ts +14 -0
  179. package/dist/auth/pages/SessionBridgePage.d.ts.map +1 -0
  180. package/dist/auth/pages/SessionBridgePage.js +231 -0
  181. package/dist/auth/pages/SessionBridgePage.js.map +1 -0
  182. package/dist/auth/pages/SessionsPage.d.ts +5 -0
  183. package/dist/auth/pages/SessionsPage.d.ts.map +1 -0
  184. package/dist/auth/pages/SessionsPage.js +258 -0
  185. package/dist/auth/pages/SessionsPage.js.map +1 -0
  186. package/dist/auth/pages/SsoCallbackPage.d.ts +8 -0
  187. package/dist/auth/pages/SsoCallbackPage.d.ts.map +1 -0
  188. package/dist/auth/pages/SsoCallbackPage.js +188 -0
  189. package/dist/auth/pages/SsoCallbackPage.js.map +1 -0
  190. package/dist/auth/pages/SsoConfigPage.d.ts +6 -0
  191. package/dist/auth/pages/SsoConfigPage.d.ts.map +1 -0
  192. package/dist/auth/pages/SsoConfigPage.js +1144 -0
  193. package/dist/auth/pages/SsoConfigPage.js.map +1 -0
  194. package/dist/auth/pages/SsoLoginPage.d.ts +7 -0
  195. package/dist/auth/pages/SsoLoginPage.d.ts.map +1 -0
  196. package/dist/auth/pages/SsoLoginPage.js +236 -0
  197. package/dist/auth/pages/SsoLoginPage.js.map +1 -0
  198. package/dist/auth/pages/UserDetailsPage.d.ts +11 -0
  199. package/dist/auth/pages/UserDetailsPage.d.ts.map +1 -0
  200. package/dist/auth/pages/UserDetailsPage.js +338 -0
  201. package/dist/auth/pages/UserDetailsPage.js.map +1 -0
  202. package/dist/auth/pages/UserProfilePage.d.ts +5 -0
  203. package/dist/auth/pages/UserProfilePage.d.ts.map +1 -0
  204. package/dist/auth/pages/UserProfilePage.js +445 -0
  205. package/dist/auth/pages/UserProfilePage.js.map +1 -0
  206. package/dist/auth/pages/UsersPage.d.ts +5 -0
  207. package/dist/auth/pages/UsersPage.d.ts.map +1 -0
  208. package/dist/auth/pages/UsersPage.js +899 -0
  209. package/dist/auth/pages/UsersPage.js.map +1 -0
  210. package/dist/auth/providers/AuthProvider.d.ts +18 -0
  211. package/dist/auth/providers/AuthProvider.d.ts.map +1 -0
  212. package/dist/auth/providers/AuthProvider.js +36 -0
  213. package/dist/auth/providers/AuthProvider.js.map +1 -0
  214. package/dist/auth/providers/CaptchaProvider.d.ts +13 -0
  215. package/dist/auth/providers/CaptchaProvider.d.ts.map +1 -0
  216. package/dist/auth/providers/CaptchaProvider.js +21 -0
  217. package/dist/auth/providers/CaptchaProvider.js.map +1 -0
  218. package/dist/auth/store/authStore.d.ts +91 -0
  219. package/dist/auth/store/authStore.d.ts.map +1 -0
  220. package/dist/auth/store/authStore.js +314 -0
  221. package/dist/auth/store/authStore.js.map +1 -0
  222. package/dist/auth/types/index.d.ts +636 -0
  223. package/dist/auth/types/index.d.ts.map +1 -0
  224. package/dist/auth/utils/captchaConfig.d.ts +4 -0
  225. package/dist/auth/utils/captchaConfig.d.ts.map +1 -0
  226. package/dist/auth/utils/captchaConfig.js +13 -0
  227. package/dist/auth/utils/captchaConfig.js.map +1 -0
  228. package/dist/auth/utils/formatters.d.ts +37 -0
  229. package/dist/auth/utils/formatters.d.ts.map +1 -0
  230. package/dist/auth/utils/formatters.js +48 -0
  231. package/dist/auth/utils/formatters.js.map +1 -0
  232. package/dist/auth/utils/gatewayBaseUrls.d.ts +6 -0
  233. package/dist/auth/utils/gatewayBaseUrls.d.ts.map +1 -0
  234. package/dist/auth/utils/gatewayBaseUrls.js +18 -0
  235. package/dist/auth/utils/gatewayBaseUrls.js.map +1 -0
  236. package/dist/auth/utils/index.d.ts +3 -0
  237. package/dist/auth/utils/index.d.ts.map +1 -0
  238. package/dist/auth/utils/validation.d.ts +30 -0
  239. package/dist/auth/utils/validation.d.ts.map +1 -0
  240. package/dist/auth/utils/validation.js +15 -0
  241. package/dist/auth/utils/validation.js.map +1 -0
  242. package/dist/dev/main.d.ts +2 -0
  243. package/dist/dev/main.d.ts.map +1 -0
  244. package/dist/generated/global-operations.d.ts +2978 -0
  245. package/dist/generated/global-operations.d.ts.map +1 -0
  246. package/dist/generated/global-operations.js +944 -0
  247. package/dist/generated/global-operations.js.map +1 -0
  248. package/dist/generated/global-types.d.ts +21253 -0
  249. package/dist/generated/global-types.d.ts.map +1 -0
  250. package/dist/generated/wspace-operations.d.ts +2 -0
  251. package/dist/generated/wspace-operations.d.ts.map +1 -0
  252. package/dist/generated/wspace-types.d.ts +55214 -0
  253. package/dist/generated/wspace-types.d.ts.map +1 -0
  254. package/dist/index.d.ts +4 -0
  255. package/dist/index.d.ts.map +1 -0
  256. package/dist/index.js +20 -0
  257. package/dist/microfe-auth.css +3 -0
  258. package/dist/node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js +70 -0
  259. package/dist/node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js.map +1 -0
  260. package/dist/node_modules/object-assign/index.js +41 -0
  261. package/dist/node_modules/object-assign/index.js.map +1 -0
  262. package/dist/node_modules/prop-types/checkPropTypes.js +46 -0
  263. package/dist/node_modules/prop-types/checkPropTypes.js.map +1 -0
  264. package/dist/node_modules/prop-types/factoryWithThrowingShims.js +49 -0
  265. package/dist/node_modules/prop-types/factoryWithThrowingShims.js.map +1 -0
  266. package/dist/node_modules/prop-types/factoryWithTypeCheckers.js +272 -0
  267. package/dist/node_modules/prop-types/factoryWithTypeCheckers.js.map +1 -0
  268. package/dist/node_modules/prop-types/index.js +16 -0
  269. package/dist/node_modules/prop-types/index.js.map +1 -0
  270. package/dist/node_modules/prop-types/lib/ReactPropTypesSecret.js +10 -0
  271. package/dist/node_modules/prop-types/lib/ReactPropTypesSecret.js.map +1 -0
  272. package/dist/node_modules/prop-types/lib/has.js +10 -0
  273. package/dist/node_modules/prop-types/lib/has.js.map +1 -0
  274. package/dist/node_modules/qrcode.react/lib/esm/index.js +959 -0
  275. package/dist/node_modules/qrcode.react/lib/esm/index.js.map +1 -0
  276. package/dist/node_modules/react-async-script/lib/esm/async-script-loader.js +114 -0
  277. package/dist/node_modules/react-async-script/lib/esm/async-script-loader.js.map +1 -0
  278. package/dist/node_modules/react-google-recaptcha/lib/esm/index.js +8 -0
  279. package/dist/node_modules/react-google-recaptcha/lib/esm/index.js.map +1 -0
  280. package/dist/node_modules/react-google-recaptcha/lib/esm/recaptcha-wrapper.js +20 -0
  281. package/dist/node_modules/react-google-recaptcha/lib/esm/recaptcha-wrapper.js.map +1 -0
  282. package/dist/node_modules/react-google-recaptcha/lib/esm/recaptcha.js +148 -0
  283. package/dist/node_modules/react-google-recaptcha/lib/esm/recaptcha.js.map +1 -0
  284. package/dist/node_modules/react-google-recaptcha-v3/dist/react-google-recaptcha-v3.esm.js +445 -0
  285. package/dist/node_modules/react-google-recaptcha-v3/dist/react-google-recaptcha-v3.esm.js.map +1 -0
  286. package/dist/node_modules/react-is/cjs/react-is.development.js +84 -0
  287. package/dist/node_modules/react-is/cjs/react-is.development.js.map +1 -0
  288. package/dist/node_modules/react-is/cjs/react-is.production.min.js +64 -0
  289. package/dist/node_modules/react-is/cjs/react-is.production.min.js.map +1 -0
  290. package/dist/node_modules/react-is/index.js +12 -0
  291. package/dist/node_modules/react-is/index.js.map +1 -0
  292. package/dist/shared/hooks/index.d.ts +7 -0
  293. package/dist/shared/hooks/index.d.ts.map +1 -0
  294. package/dist/shared/index.d.ts +6 -0
  295. package/dist/shared/index.d.ts.map +1 -0
  296. package/dist/shared/types/index.d.ts +109 -0
  297. package/dist/shared/types/index.d.ts.map +1 -0
  298. package/dist/utils/nativeBridge.d.ts +3 -0
  299. package/dist/utils/nativeBridge.d.ts.map +1 -0
  300. package/dist/utils/nativeBridge.js +2 -0
  301. package/package.json +114 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UsersPage.js","names":[],"sources":["../../../src/auth/pages/UsersPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from \"react\";\nimport { useNavigate } from \"react-router-dom\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell\";\nimport { useAuthPermissions, useUserOperations } from \"../hooks\";\nimport { useAuthStore } from \"../store/authStore\";\nimport { ConfirmActionDialog } from \"../components/ConfirmActionDialog\";\nimport type {\n User,\n UserRole,\n UserStatus,\n UserFilterInput,\n PaginationInput,\n} from \"../types\";\nimport { SpinnerIcon, AlertIcon } from \"../components/AuthIcons\";\nimport { nativeImpact, nativeNotify } from \"../../utils/nativeBridge\";\n\ntype ViewMode = \"list\" | \"edit\" | \"view\";\n\ninterface FormData {\n username: string;\n firstName: string;\n lastName: string;\n name: string;\n phoneNumber: string;\n role: UserRole;\n status: UserStatus;\n emailVerified: boolean;\n}\n\nconst USER_ROLES: UserRole[] = [\n \"SUPER_ADMIN\",\n \"TENANT_ADMIN\",\n \"ORG_ADMIN\",\n \"WORKSPACE_ADMIN\",\n \"MEMBER\",\n \"GUEST\",\n];\n\nconst USER_STATUSES: UserStatus[] = [\n \"ACTIVE\",\n \"INACTIVE\",\n \"SUSPENDED\",\n \"DELETED\",\n];\n\n/**\n * Users CRUDL page for managing users (admin only)\n */\nexport function UsersPage() {\n const navigate = useNavigate();\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n const isAuthenticated = useAuthStore((state) => state.isAuthenticated);\n const currentUser = useAuthStore((state) => state.user);\n const {\n canViewUsers,\n canUpdateUsers,\n canDeleteUsers,\n isLoading: permissionsLoading,\n } = useAuthPermissions();\n const { listUsers, updateUser, deleteUser, hardDeleteUser, isLoading } =\n useUserOperations();\n\n const [users, setUsers] = useState<User[]>([]);\n const [totalCount, setTotalCount] = useState(0);\n const [hasMore, setHasMore] = useState(false);\n const [viewMode, setViewMode] = useState<ViewMode>(\"list\");\n const [selectedUser, setSelectedUser] = useState<User | null>(null);\n const [formData, setFormData] = useState<FormData>({\n username: \"\",\n firstName: \"\",\n lastName: \"\",\n name: \"\",\n phoneNumber: \"\",\n role: \"MEMBER\",\n status: \"ACTIVE\",\n emailVerified: false,\n });\n const [error, setError] = useState<string | null>(null);\n const [isUnauthorized, setIsUnauthorized] = useState(false);\n const [successMessage, setSuccessMessage] = useState<string | null>(null);\n const [pendingAction, setPendingAction] = useState<{\n type: \"deactivate\" | \"hard-delete\";\n user: User;\n } | null>(null);\n const [searchQuery, setSearchQuery] = useState(\"\");\n const [filterRole, setFilterRole] = useState<UserRole | \"\">(\"\");\n const [filterStatus, setFilterStatus] = useState<UserStatus | \"\">(\"\");\n const [currentPage, setCurrentPage] = useState(0);\n const pageSize = 10;\n\n const fetchUsers = useCallback(async () => {\n if (!isAuthenticated) return;\n\n try {\n setIsUnauthorized(false);\n const filter: UserFilterInput = {};\n if (searchQuery) filter.search = searchQuery;\n if (filterRole) filter.role = filterRole;\n if (filterStatus) filter.status = filterStatus;\n\n const pagination: PaginationInput = {\n offset: currentPage * pageSize,\n limit: pageSize,\n };\n\n const result = await listUsers(filter, pagination);\n setUsers(result.users);\n setTotalCount(result.totalCount);\n setHasMore(result.hasMore);\n setError(null);\n } catch (err) {\n // Ignore abort errors - they happen during component unmount/re-render\n if (\n err instanceof Error &&\n (err.name === \"AbortError\" || err.message.includes(\"aborted\"))\n ) {\n return;\n }\n const errorMessage =\n err instanceof Error ? err.message : \"Failed to fetch users\";\n // Check if it's an authorization error\n if (\n errorMessage.toLowerCase().includes(\"not authorized\") ||\n errorMessage.toLowerCase().includes(\"forbidden\")\n ) {\n setIsUnauthorized(true);\n setError(null);\n } else {\n setError(errorMessage);\n }\n }\n }, [\n listUsers,\n searchQuery,\n filterRole,\n filterStatus,\n currentPage,\n isAuthenticated,\n ]);\n\n useEffect(() => {\n fetchUsers();\n }, [fetchUsers]);\n\n const resetForm = () => {\n setFormData({\n username: \"\",\n firstName: \"\",\n lastName: \"\",\n name: \"\",\n phoneNumber: \"\",\n role: \"MEMBER\",\n status: \"ACTIVE\",\n emailVerified: false,\n });\n setSelectedUser(null);\n setError(null);\n setSuccessMessage(null);\n };\n\n const handleUpdate = async (e: React.FormEvent) => {\n e.preventDefault();\n if (!selectedUser) return;\n setError(null);\n\n try {\n await updateUser(selectedUser.id, {\n username: formData.username || undefined,\n firstName: formData.firstName || undefined,\n lastName: formData.lastName || undefined,\n name: formData.name || undefined,\n phoneNumber: formData.phoneNumber || undefined,\n role: formData.role,\n status: formData.status,\n emailVerified: formData.emailVerified,\n });\n setSuccessMessage(\"User updated successfully!\");\n setViewMode(\"list\");\n resetForm();\n fetchUsers();\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to update user\");\n }\n };\n\n const handleDelete = async (user: User) => {\n void nativeImpact(\"medium\");\n try {\n const result = await deleteUser(user.id);\n if (result.success) {\n void nativeNotify(\"success\");\n setSuccessMessage(`User \"${user.email}\" has been deactivated.`);\n setPendingAction(null);\n fetchUsers();\n } else {\n void nativeNotify(\"error\");\n setError(result.message);\n }\n } catch (err) {\n void nativeNotify(\"error\");\n setError(err instanceof Error ? err.message : \"Failed to delete user\");\n }\n };\n\n const handleHardDelete = async (user: User) => {\n try {\n const result = await hardDeleteUser(user.id);\n if (result.success) {\n setSuccessMessage(`User \"${user.email}\" has been permanently deleted.`);\n setPendingAction(null);\n fetchUsers();\n } else {\n setError(result.message);\n }\n } catch (err) {\n setError(\n err instanceof Error ? err.message : \"Failed to hard delete user\",\n );\n }\n };\n\n const startEdit = (user: User) => {\n setSelectedUser(user);\n setFormData({\n username: user.username || \"\",\n firstName: user.firstName || \"\",\n lastName: user.lastName || \"\",\n name: user.name || \"\",\n phoneNumber: user.phoneNumber || \"\",\n role: user.role,\n status: user.status,\n emailVerified: user.emailVerified,\n });\n setViewMode(\"edit\");\n setError(null);\n };\n\n const pendingActionDialog = (\n <ConfirmActionDialog\n open={pendingAction !== null}\n onOpenChange={(open) => {\n if (!open) {\n setPendingAction(null);\n }\n }}\n title={\n pendingAction?.type === \"hard-delete\"\n ? \"Permanently delete user?\"\n : \"Deactivate user?\"\n }\n description={\n pendingAction?.type === \"hard-delete\"\n ? pendingAction\n ? `This permanently deletes \"${pendingAction.user.email}\" and cannot be undone.`\n : \"\"\n : pendingAction\n ? `\"${pendingAction.user.email}\" will be prevented from signing in until reactivated.`\n : \"\"\n }\n confirmText={\n pendingAction?.type === \"hard-delete\"\n ? \"Delete permanently\"\n : \"Deactivate user\"\n }\n variant={pendingAction?.type === \"hard-delete\" ? \"danger\" : \"warning\"}\n onConfirm={async () => {\n if (!pendingAction) return;\n if (pendingAction.type === \"hard-delete\") {\n await handleHardDelete(pendingAction.user);\n return;\n }\n await handleDelete(pendingAction.user);\n }}\n />\n );\n\n const getRoleColor = (role: UserRole) => {\n switch (role) {\n case \"SUPER_ADMIN\":\n return \"bg-accent-purple-subtle text-accent-purple\";\n case \"TENANT_ADMIN\":\n return \"bg-status-info-bg-subtle text-status-info-text\";\n case \"ORG_ADMIN\":\n return \"bg-accent-indigo-subtle text-accent-indigo\";\n case \"WORKSPACE_ADMIN\":\n return \"bg-accent-cyan-subtle text-accent-cyan\";\n case \"MEMBER\":\n return \"bg-status-success-bg-subtle text-status-success-text\";\n case \"GUEST\":\n return \"bg-bg-sunken text-text-primary\";\n default:\n return \"bg-bg-sunken text-text-primary\";\n }\n };\n\n const getStatusColor = (status: UserStatus) => {\n switch (status) {\n case \"ACTIVE\":\n return \"bg-status-success-bg-subtle text-status-success-text\";\n case \"INACTIVE\":\n return \"bg-status-warning-bg-subtle text-status-warning-text\";\n case \"SUSPENDED\":\n return \"bg-status-warning-bg-subtle text-status-warning-text\";\n case \"DELETED\":\n return \"bg-status-error-bg-subtle text-status-error-text\";\n default:\n return \"bg-bg-sunken text-text-primary\";\n }\n };\n\n // Authentication check\n if (!isAuthenticated) {\n return (\n <div className=\"max-w-6xl mx-auto p-6\">\n <div className=\"text-center py-16 border-2 border-dashed border-border-subtle rounded-xl\">\n <div className=\"w-16 h-16 mx-auto mb-4 rounded-full bg-status-warning-bg-subtle flex items-center justify-center\">\n <AlertIcon className=\"w-8 h-8 text-status-warning-text\" />\n </div>\n <h2 className=\"text-xl font-semibold text-text-primary mb-2\">\n {tr(\"auth.users.authRequired\", \"Authentication Required\")}\n </h2>\n <p className=\"text-text-secondary\">Please sign in to manage users</p>\n </div>\n </div>\n );\n }\n\n // Role-based guard — only admin roles may access this page\n const ALLOWED_ROLES: UserRole[] = [\n \"SUPER_ADMIN\",\n \"TENANT_ADMIN\",\n \"ORG_ADMIN\",\n ];\n if (currentUser && !ALLOWED_ROLES.includes(currentUser.role)) {\n return (\n <div className=\"max-w-6xl mx-auto p-6\">\n <div className=\"text-center py-16 border-2 border-dashed border-border-subtle rounded-xl\">\n <div className=\"w-16 h-16 mx-auto mb-4 rounded-full bg-status-error-bg-subtle flex items-center justify-center\">\n <svg\n className=\"w-8 h-8 text-status-error-text\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636\"\n />\n </svg>\n </div>\n <h2 className=\"text-xl font-semibold text-text-primary mb-2\">\n You are not allowed to access this page\n </h2>\n <p className=\"text-text-secondary\">\n This page is restricted to administrators only. Contact your admin\n if you need access.\n </p>\n </div>\n </div>\n );\n }\n\n // Loading permissions\n if (permissionsLoading) {\n return (\n <div className=\"max-w-6xl mx-auto p-6\">\n <div className=\"text-center py-16\">\n <SpinnerIcon className=\"w-8 h-8 mx-auto text-text-secondary animate-spin\" />\n <p className=\"mt-4 text-text-secondary\">Loading permissions...</p>\n </div>\n </div>\n );\n }\n\n // Authorization check - user needs user:read permission\n if (!canViewUsers || isUnauthorized) {\n return (\n <div className=\"max-w-6xl mx-auto p-6\">\n <div className=\"text-center py-16 border-2 border-dashed border-border-subtle rounded-xl\">\n <div className=\"w-16 h-16 mx-auto mb-4 rounded-full bg-status-error-bg-subtle flex items-center justify-center\">\n <svg\n className=\"w-8 h-8 text-status-error-text\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636\"\n />\n </svg>\n </div>\n <h2 className=\"text-xl font-semibold text-text-primary mb-2\">\n Admin Access Required\n </h2>\n <p className=\"text-text-secondary mb-4\">\n You need administrator privileges to view and manage users.\n </p>\n <p className=\"text-sm text-text-secondary\">\n Required roles: Super Admin, Tenant Admin, or Org Admin\n </p>\n </div>\n </div>\n );\n }\n\n // List view\n if (viewMode === \"list\") {\n return (\n <div className=\"max-w-6xl mx-auto p-6\">\n {pendingActionDialog}\n {/* Header */}\n <div className=\"flex items-center justify-between mb-8\">\n <div>\n <h1 className=\"text-3xl font-semibold text-text-primary\">Users</h1>\n <p className=\"text-text-secondary mt-2\">\n Manage users in your organization ({totalCount} total)\n </p>\n </div>\n </div>\n\n {/* Success Message */}\n {successMessage && (\n <div className=\"mb-6 p-4 rounded-xl bg-status-success-bg-subtle border border-status-success-border\">\n <p className=\"text-status-success-text\">{successMessage}</p>\n <button\n onClick={() => setSuccessMessage(null)}\n className=\"mt-2 text-sm text-status-success-text hover:underline\"\n >\n Dismiss\n </button>\n </div>\n )}\n\n {/* Error Message */}\n {error && (\n <div className=\"mb-6 flex items-start gap-3 p-4 rounded-xl bg-status-error-bg-subtle border border-status-error-border\">\n <AlertIcon className=\"w-5 h-5 text-status-error-text flex-shrink-0 mt-0.5\" />\n <div className=\"flex-1\">\n <p className=\"text-sm text-status-error-text\">{error}</p>\n <button\n onClick={() => setError(null)}\n className=\"mt-2 text-sm text-status-error-text hover:underline\"\n >\n Dismiss\n </button>\n </div>\n </div>\n )}\n\n {/* Filters */}\n <div className=\"mb-6 p-4 rounded-xl border border-border-subtle bg-bg-surface\">\n <div className=\"flex flex-wrap gap-4\">\n <input\n type=\"text\"\n placeholder=\"Search by email, username, or name...\"\n value={searchQuery}\n onChange={(e) => {\n setSearchQuery(e.target.value);\n setCurrentPage(0);\n }}\n className=\"flex-1 min-w-[200px] px-4 py-2.5 border border-border-default rounded-xl bg-bg-surface text-text-primary placeholder-text-tertiary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all\"\n />\n <select\n value={filterRole}\n onChange={(e) => {\n setFilterRole(e.target.value as UserRole | \"\");\n setCurrentPage(0);\n }}\n className=\"px-4 py-2.5 border border-border-default rounded-xl bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all\"\n >\n <option value=\"\">All Roles</option>\n {USER_ROLES.map((role) => (\n <option key={role} value={role}>\n {role.replace(\"_\", \" \")}\n </option>\n ))}\n </select>\n <select\n value={filterStatus}\n onChange={(e) => {\n setFilterStatus(e.target.value as UserStatus | \"\");\n setCurrentPage(0);\n }}\n className=\"px-4 py-2.5 border border-border-default rounded-xl bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all\"\n >\n <option value=\"\">All Statuses</option>\n {USER_STATUSES.map((status) => (\n <option key={status} value={status}>\n {status}\n </option>\n ))}\n </select>\n </div>\n </div>\n\n {isLoading ? (\n <div className=\"flex items-center justify-center py-12\">\n <SpinnerIcon className=\"w-8 h-8 text-text-link animate-spin\" />\n <span className=\"ml-3 text-text-secondary\">Loading users...</span>\n </div>\n ) : users.length === 0 ? (\n <div className=\"text-center py-16 border-2 border-dashed border-border-subtle rounded-xl\">\n <div className=\"w-16 h-16 mx-auto mb-4 rounded-full bg-bg-sunken flex items-center justify-center\">\n <svg\n className=\"w-8 h-8 text-text-tertiary\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z\"\n />\n </svg>\n </div>\n <p className=\"text-text-secondary\">No users found</p>\n </div>\n ) : (\n <>\n {/* Users Table */}\n <div className=\"rounded-xl border border-border-subtle bg-bg-surface overflow-hidden shadow-sm\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full min-w-[800px]\">\n <thead>\n <tr className=\"border-b border-border-subtle bg-bg-canvas\">\n <th className=\"text-left py-4 px-4 text-sm font-medium text-text-secondary w-[280px]\">\n User\n </th>\n <th className=\"text-left py-4 px-4 text-sm font-medium text-text-secondary w-[130px]\">\n Role\n </th>\n <th className=\"text-left py-4 px-4 text-sm font-medium text-text-secondary w-[100px]\">\n Status\n </th>\n <th className=\"text-left py-4 px-4 text-sm font-medium text-text-secondary w-[80px]\">\n Verified\n </th>\n <th className=\"text-left py-4 px-4 text-sm font-medium text-text-secondary w-[100px]\">\n Last Login\n </th>\n <th className=\"text-right py-4 px-4 text-sm font-medium text-text-secondary w-[180px]\">\n Actions\n </th>\n </tr>\n </thead>\n <tbody>\n {users.map((user) => (\n <tr\n key={user.id}\n className=\"border-b border-border-subtle last:border-b-0 hover:bg-bg-sunken/50 transition-colors\"\n >\n <td className=\"py-4 px-4\">\n <div className=\"flex items-center gap-3 min-w-0\">\n <div className=\"auth-brand-badge flex h-10 w-10 shrink-0 items-center justify-center rounded-full font-medium\">\n {(user.name || user.username || user.email)\n .charAt(0)\n .toUpperCase()}\n </div>\n <div className=\"min-w-0 flex-1\">\n <p className=\"font-medium text-text-primary truncate\">\n {user.name || user.username}\n </p>\n <p className=\"text-sm text-text-secondary truncate\">\n {user.email}\n </p>\n </div>\n </div>\n </td>\n <td className=\"py-4 px-4\">\n <span\n className={`inline-block px-2.5 py-1 rounded-full text-xs font-medium whitespace-nowrap ${getRoleColor(user.role)}`}\n >\n {user.role.replace(\"_\", \" \")}\n </span>\n </td>\n <td className=\"py-4 px-4\">\n <span\n className={`inline-block px-2.5 py-1 rounded-full text-xs font-medium whitespace-nowrap ${getStatusColor(user.status)}`}\n >\n {user.status}\n </span>\n </td>\n <td className=\"py-4 px-4\">\n {user.emailVerified ? (\n <span className=\"inline-flex items-center gap-1 text-status-success-text whitespace-nowrap\">\n <svg\n className=\"w-4 h-4 flex-shrink-0\"\n fill=\"currentColor\"\n viewBox=\"0 0 20 20\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z\"\n clipRule=\"evenodd\"\n />\n </svg>\n <span className=\"text-sm\">Yes</span>\n </span>\n ) : (\n <span className=\"inline-flex items-center gap-1 text-status-warning-text whitespace-nowrap\">\n <svg\n className=\"w-4 h-4 flex-shrink-0\"\n fill=\"currentColor\"\n viewBox=\"0 0 20 20\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z\"\n clipRule=\"evenodd\"\n />\n </svg>\n <span className=\"text-sm\">No</span>\n </span>\n )}\n </td>\n <td className=\"py-4 px-4 text-sm text-text-secondary whitespace-nowrap\">\n {user.lastLoginAt\n ? new Date(user.lastLoginAt).toLocaleDateString()\n : \"Never\"}\n </td>\n <td className=\"py-4 px-4\">\n <div className=\"flex justify-end gap-1.5 flex-nowrap\">\n <button\n onClick={() => navigate(`/auth/users/${user.id}`)}\n className=\"px-2.5 py-1.5 rounded-lg text-xs font-medium border border-border-default text-text-primary bg-bg-surface hover:bg-bg-sunken transition-colors whitespace-nowrap flex-shrink-0\"\n >\n View\n </button>\n {canUpdateUsers && (\n <button\n onClick={() => startEdit(user)}\n className=\"px-2.5 py-1.5 rounded-lg text-xs font-medium border border-status-info-border text-text-link bg-bg-surface hover:bg-status-info-bg-subtle transition-colors whitespace-nowrap flex-shrink-0\"\n >\n Edit\n </button>\n )}\n {canDeleteUsers && user.status !== \"DELETED\" && (\n <button\n onClick={() =>\n setPendingAction({ type: \"deactivate\", user })\n }\n className=\"px-2.5 py-1.5 rounded-lg text-xs font-medium border border-status-error-border text-status-error-text bg-bg-surface hover:bg-status-error-bg-subtle transition-colors whitespace-nowrap flex-shrink-0\"\n >\n Delete\n </button>\n )}\n </div>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n\n {/* Pagination */}\n <div className=\"mt-6 flex items-center justify-between\">\n <p className=\"text-sm text-text-secondary\">\n Showing {currentPage * pageSize + 1} to{\" \"}\n {Math.min((currentPage + 1) * pageSize, totalCount)} of{\" \"}\n {totalCount} users\n </p>\n <div className=\"flex gap-2\">\n <button\n onClick={() =>\n setCurrentPage((prev) => Math.max(0, prev - 1))\n }\n disabled={currentPage === 0}\n className=\"px-4 py-2 rounded-lg border border-border-default text-text-primary bg-bg-surface disabled:opacity-50 disabled:cursor-not-allowed hover:bg-bg-sunken transition-colors\"\n >\n Previous\n </button>\n <button\n onClick={() => setCurrentPage((prev) => prev + 1)}\n disabled={!hasMore}\n className=\"px-4 py-2 rounded-lg border border-border-default text-text-primary bg-bg-surface disabled:opacity-50 disabled:cursor-not-allowed hover:bg-bg-sunken transition-colors\"\n >\n Next\n </button>\n </div>\n </div>\n </>\n )}\n </div>\n );\n }\n\n // View details\n if (viewMode === \"view\" && selectedUser) {\n return (\n <div className=\"max-w-4xl mx-auto p-6\">\n {pendingActionDialog}\n <button\n onClick={() => {\n setViewMode(\"list\");\n resetForm();\n }}\n className=\"mb-6 flex items-center gap-2 text-text-link hover:underline font-medium\"\n >\n <svg\n className=\"w-4 h-4\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M10 19l-7-7m0 0l7-7m-7 7h18\"\n />\n </svg>\n Back to Users\n </button>\n\n <div className=\"p-6 rounded-xl border border-border-subtle bg-bg-surface shadow-sm\">\n <div className=\"flex items-center gap-4 mb-8\">\n <div className=\"auth-brand-badge flex h-20 w-20 items-center justify-center rounded-full text-3xl font-semibold\">\n {(\n selectedUser.name ||\n selectedUser.username ||\n selectedUser.email\n )\n .charAt(0)\n .toUpperCase()}\n </div>\n <div>\n <h1 className=\"text-2xl font-semibold text-text-primary\">\n {selectedUser.name || selectedUser.username}\n </h1>\n <p className=\"text-text-secondary\">{selectedUser.email}</p>\n <div className=\"flex items-center gap-2 mt-2\">\n <span\n className={`px-2.5 py-1 rounded-full text-xs font-medium ${getRoleColor(selectedUser.role)}`}\n >\n {selectedUser.role.replace(\"_\", \" \")}\n </span>\n <span\n className={`px-2.5 py-1 rounded-full text-xs font-medium ${getStatusColor(selectedUser.status)}`}\n >\n {selectedUser.status}\n </span>\n </div>\n </div>\n </div>\n\n <div className=\"grid grid-cols-2 gap-6\">\n <div className=\"p-4 rounded-lg bg-bg-canvas/50\">\n <label className=\"block text-sm font-medium text-text-secondary mb-1\">\n Username\n </label>\n <p className=\"text-text-primary font-medium\">\n {selectedUser.username}\n </p>\n </div>\n\n <div className=\"p-4 rounded-lg bg-bg-canvas/50\">\n <label className=\"block text-sm font-medium text-text-secondary mb-1\">\n Email\n </label>\n <p className=\"text-text-primary font-medium\">\n {selectedUser.email}\n </p>\n </div>\n\n <div className=\"p-4 rounded-lg bg-bg-canvas/50\">\n <label className=\"block text-sm font-medium text-text-secondary mb-1\">\n Email Verified\n </label>\n <p className=\"text-text-primary font-medium\">\n {selectedUser.emailVerified ? (\n <span className=\"text-status-success-text\">Yes</span>\n ) : (\n <span className=\"text-status-warning-text\">No</span>\n )}\n </p>\n </div>\n\n <div className=\"p-4 rounded-lg bg-bg-canvas/50\">\n <label className=\"block text-sm font-medium text-text-secondary mb-1\">\n MFA Enabled\n </label>\n <p className=\"text-text-primary font-medium\">\n {selectedUser.mfaEnabled ? (\n <span className=\"text-status-success-text\">Yes</span>\n ) : (\n <span className=\"text-text-secondary\">No</span>\n )}\n </p>\n </div>\n\n {selectedUser.phoneNumber && (\n <div className=\"p-4 rounded-lg bg-bg-canvas/50\">\n <label className=\"block text-sm font-medium text-text-secondary mb-1\">\n Phone Number\n </label>\n <p className=\"text-text-primary font-medium\">\n {selectedUser.phoneNumber}\n </p>\n </div>\n )}\n\n <div className=\"p-4 rounded-lg bg-bg-canvas/50\">\n <label className=\"block text-sm font-medium text-text-secondary mb-1\">\n Last Login\n </label>\n <p className=\"text-text-primary font-medium\">\n {selectedUser.lastLoginAt\n ? new Date(selectedUser.lastLoginAt).toLocaleString()\n : \"Never\"}\n </p>\n </div>\n\n <div className=\"p-4 rounded-lg bg-bg-canvas/50\">\n <label className=\"block text-sm font-medium text-text-secondary mb-1\">\n Created\n </label>\n <p className=\"text-text-primary font-medium\">\n {new Date(selectedUser.createdAt).toLocaleString()}\n </p>\n </div>\n\n <div className=\"p-4 rounded-lg bg-bg-canvas/50\">\n <label className=\"block text-sm font-medium text-text-secondary mb-1\">\n Last Updated\n </label>\n <p className=\"text-text-primary font-medium\">\n {new Date(selectedUser.updatedAt).toLocaleString()}\n </p>\n </div>\n </div>\n\n <div className=\"mt-8 pt-6 border-t border-border-subtle flex gap-3\">\n <button\n onClick={() => startEdit(selectedUser)}\n className=\"auth-primary-button px-4 py-2.5 font-medium\"\n >\n Edit User\n </button>\n {selectedUser.status !== \"DELETED\" && (\n <button\n onClick={() =>\n setPendingAction({ type: \"deactivate\", user: selectedUser })\n }\n className=\"px-4 py-2.5 rounded-xl border border-status-error-border text-status-error-text font-medium hover:bg-status-error-bg-subtle transition-colors\"\n >\n Delete User\n </button>\n )}\n {canDeleteUsers && selectedUser.status === \"DELETED\" && (\n <button\n onClick={() =>\n setPendingAction({\n type: \"hard-delete\",\n user: selectedUser,\n })\n }\n className=\"px-4 py-2.5 rounded-xl bg-status-error-bg text-white font-medium hover:bg-status-error-bg-hover transition-colors\"\n >\n Permanently Delete\n </button>\n )}\n </div>\n </div>\n </div>\n );\n }\n\n // Edit form\n return (\n <div className=\"max-w-2xl mx-auto p-6\">\n {pendingActionDialog}\n <button\n onClick={() => {\n setViewMode(\"list\");\n resetForm();\n }}\n className=\"mb-6 flex items-center gap-2 text-text-link hover:underline font-medium\"\n >\n <svg\n className=\"w-4 h-4\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M10 19l-7-7m0 0l7-7m-7 7h18\"\n />\n </svg>\n Back to Users\n </button>\n\n <div className=\"p-6 rounded-xl border border-border-subtle bg-bg-surface shadow-sm\">\n <h1 className=\"text-2xl font-semibold text-text-primary mb-2\">\n Edit User\n </h1>\n\n {selectedUser && (\n <p className=\"text-text-secondary mb-6\">\n Editing: <strong>{selectedUser.email}</strong>\n </p>\n )}\n\n {error && (\n <div className=\"mb-6 flex items-start gap-3 p-4 rounded-xl bg-status-error-bg-subtle border border-status-error-border\">\n <AlertIcon className=\"w-5 h-5 text-status-error-text flex-shrink-0 mt-0.5\" />\n <div className=\"flex-1\">\n <p className=\"text-sm text-status-error-text\">{error}</p>\n </div>\n </div>\n )}\n\n <form onSubmit={handleUpdate} className=\"space-y-6\">\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-2\">\n Username\n </label>\n <input\n type=\"text\"\n value={formData.username}\n onChange={(e) =>\n setFormData({ ...formData, username: e.target.value })\n }\n className=\"block w-full px-4 py-3 border border-border-default rounded-xl bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all\"\n />\n </div>\n\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-2\">\n Name\n </label>\n <input\n type=\"text\"\n value={formData.name}\n onChange={(e) =>\n setFormData({ ...formData, name: e.target.value })\n }\n className=\"block w-full px-4 py-3 border border-border-default rounded-xl bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all\"\n />\n </div>\n </div>\n\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-2\">\n First Name\n </label>\n <input\n type=\"text\"\n value={formData.firstName}\n onChange={(e) =>\n setFormData({ ...formData, firstName: e.target.value })\n }\n className=\"block w-full px-4 py-3 border border-border-default rounded-xl bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all\"\n />\n </div>\n\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-2\">\n Last Name\n </label>\n <input\n type=\"text\"\n value={formData.lastName}\n onChange={(e) =>\n setFormData({ ...formData, lastName: e.target.value })\n }\n className=\"block w-full px-4 py-3 border border-border-default rounded-xl bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all\"\n />\n </div>\n </div>\n\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-2\">\n Phone Number\n </label>\n <input\n type=\"tel\"\n value={formData.phoneNumber}\n onChange={(e) =>\n setFormData({ ...formData, phoneNumber: e.target.value })\n }\n className=\"block w-full px-4 py-3 border border-border-default rounded-xl bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all\"\n />\n </div>\n\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-2\">\n Role\n </label>\n <select\n value={formData.role}\n onChange={(e) =>\n setFormData({ ...formData, role: e.target.value as UserRole })\n }\n className=\"block w-full px-4 py-3 border border-border-default rounded-xl bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all\"\n >\n {USER_ROLES.map((role) => (\n <option key={role} value={role}>\n {role.replace(\"_\", \" \")}\n </option>\n ))}\n </select>\n </div>\n\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-2\">\n Status\n </label>\n <select\n value={formData.status}\n onChange={(e) =>\n setFormData({\n ...formData,\n status: e.target.value as UserStatus,\n })\n }\n className=\"block w-full px-4 py-3 border border-border-default rounded-xl bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all\"\n >\n {USER_STATUSES.map((status) => (\n <option key={status} value={status}>\n {status}\n </option>\n ))}\n </select>\n </div>\n </div>\n\n <div className=\"flex items-center gap-3 p-4 rounded-xl bg-bg-canvas/50\">\n <input\n type=\"checkbox\"\n id=\"emailVerified\"\n checked={formData.emailVerified}\n onChange={(e) =>\n setFormData({ ...formData, emailVerified: e.target.checked })\n }\n className=\"w-5 h-5 rounded border-border-default text-text-link focus:ring-action-primary-bg\"\n />\n <label\n htmlFor=\"emailVerified\"\n className=\"text-sm font-medium text-text-primary\"\n >\n Email Verified\n </label>\n </div>\n\n <div className=\"flex gap-3 pt-4\">\n <button\n type=\"submit\"\n disabled={isLoading}\n className=\"auth-primary-button flex items-center gap-2 px-6 py-3 font-medium\"\n >\n {isLoading ? (\n <>\n <SpinnerIcon className=\"w-4 h-4 animate-spin\" />\n Saving...\n </>\n ) : (\n \"Save Changes\"\n )}\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setViewMode(\"list\");\n resetForm();\n }}\n className=\"px-6 py-3 rounded-xl border border-border-default text-text-primary font-medium hover:bg-bg-sunken transition-colors\"\n >\n Cancel\n </button>\n </div>\n </form>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { FC, PropsWithChildren } from 'react';
2
+ import { AuthRootProps } from '../types';
3
+
4
+ /**
5
+ * Hook to access Auth context
6
+ */
7
+ export declare const useAuth: () => AuthRootProps;
8
+ /**
9
+ * Provider component for Auth microfrontend
10
+ * Sets up routing and context.
11
+ *
12
+ * NOTE: Apollo client is provided by the app shell's MultiGatewayProvider +
13
+ * GatewayRoute. Auth routes are wrapped with <GatewayRoute gateway="global">
14
+ * so all useQuery/useMutation calls automatically use the global gateway client.
15
+ * This MFE does NOT create its own Apollo client.
16
+ */
17
+ export declare const AuthProvider: FC<PropsWithChildren<AuthRootProps>>;
18
+ //# sourceMappingURL=AuthProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthProvider.d.ts","sourceRoot":"","sources":["../../../src/auth/providers/AuthProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAInD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAS9C;;GAEG;AACH,eAAO,MAAM,OAAO,qBAMnB,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAgD7D,CAAC"}
@@ -0,0 +1,36 @@
1
+ import { createContext as e, useContext as t } from "react";
2
+ import { MemoryRouter as n } from "react-router-dom";
3
+ import { PermissionProvider as r } from "@burdenoff/fe-libs/shared/providers/shell";
4
+ import { jsx as i } from "react/jsx-runtime";
5
+ //#region src/auth/providers/AuthProvider.tsx
6
+ var a = e(null), o = () => {
7
+ let e = t(a);
8
+ if (!e) throw Error("useAuth must be used within AuthProvider");
9
+ return e;
10
+ }, s = ({ children: e, basePath: t, navigate: o, currentUser: s, workspaceId: c, tenantId: l, organizationId: u, apiGatewayUrl: d, authToken: f, productName: p, onAuthSuccess: m, onLogout: h }) => {
11
+ let g = {
12
+ basePath: t,
13
+ navigate: o,
14
+ currentUser: s,
15
+ workspaceId: c,
16
+ tenantId: l,
17
+ organizationId: u,
18
+ apiGatewayUrl: d,
19
+ authToken: f,
20
+ productName: p,
21
+ onAuthSuccess: m,
22
+ onLogout: h
23
+ }, _ = u ?? l ?? null, v = /* @__PURE__ */ i(a.Provider, {
24
+ value: g,
25
+ children: /* @__PURE__ */ i(r, {
26
+ scopeId: _,
27
+ gateway: "global",
28
+ children: e
29
+ })
30
+ });
31
+ return t ? v : /* @__PURE__ */ i(n, { children: v });
32
+ };
33
+ //#endregion
34
+ export { s as AuthProvider, o as useAuth };
35
+
36
+ //# sourceMappingURL=AuthProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthProvider.js","names":[],"sources":["../../../src/auth/providers/AuthProvider.tsx"],"sourcesContent":["import type { FC, PropsWithChildren } from \"react\";\nimport { createContext, useContext } from \"react\";\nimport { MemoryRouter } from \"react-router-dom\";\nimport { PermissionProvider } from \"@burdenoff/fe-libs/shared/providers/shell\";\nimport type { AuthRootProps } from \"../types\";\n\n/**\n * Context value for Auth microfrontend\n */\ntype AuthContextValue = AuthRootProps;\n\nconst AuthContext = createContext<AuthContextValue | null>(null);\n\n/**\n * Hook to access Auth context\n */\nexport const useAuth = () => {\n const context = useContext(AuthContext);\n if (!context) {\n throw new Error(\"useAuth must be used within AuthProvider\");\n }\n return context;\n};\n\n/**\n * Provider component for Auth microfrontend\n * Sets up routing and context.\n *\n * NOTE: Apollo client is provided by the app shell's MultiGatewayProvider +\n * GatewayRoute. Auth routes are wrapped with <GatewayRoute gateway=\"global\">\n * so all useQuery/useMutation calls automatically use the global gateway client.\n * This MFE does NOT create its own Apollo client.\n */\nexport const AuthProvider: FC<PropsWithChildren<AuthRootProps>> = ({\n children,\n basePath,\n navigate,\n currentUser,\n workspaceId,\n tenantId,\n organizationId,\n apiGatewayUrl,\n authToken,\n productName,\n onAuthSuccess,\n onLogout,\n}) => {\n const contextValue: AuthContextValue = {\n basePath,\n navigate,\n currentUser,\n workspaceId,\n tenantId,\n organizationId,\n apiGatewayUrl,\n authToken,\n productName,\n onAuthSuccess,\n onLogout,\n };\n\n // global-rbac has no tenant scope; org roles are scoped to organizationId.\n const permissionScopeId = organizationId ?? tenantId ?? null;\n\n const content = (\n <AuthContext.Provider value={contextValue}>\n <PermissionProvider scopeId={permissionScopeId} gateway=\"global\">\n {children}\n </PermissionProvider>\n </AuthContext.Provider>\n );\n\n // When integrated into a shell (basePath provided), the shell provides\n // BrowserRouter AND ApolloProvider — just render the context\n if (basePath) {\n return content;\n }\n\n // Standalone mode: create MemoryRouter for independent operation\n // (Apollo client must be provided externally or via a dev harness)\n return <MemoryRouter>{content}</MemoryRouter>;\n};\n"],"mappings":";;;;;AAWA,IAAM,IAAc,EAAuC,KAAK,EAKnD,UAAgB;CAC3B,IAAM,IAAU,EAAW,EAAY;AACvC,KAAI,CAAC,EACH,OAAU,MAAM,2CAA2C;AAE7D,QAAO;GAYI,KAAsD,EACjE,aACA,aACA,aACA,gBACA,gBACA,aACA,mBACA,kBACA,cACA,gBACA,kBACA,kBACI;CACJ,IAAM,IAAiC;EACrC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,EAGK,IAAoB,KAAkB,KAAY,MAElD,IACJ,kBAAC,EAAY,UAAb;EAAsB,OAAO;YAC3B,kBAAC,GAAD;GAAoB,SAAS;GAAmB,SAAQ;GACrD;GACkB,CAAA;EACA,CAAA;AAWzB,QANI,IACK,IAKF,kBAAC,GAAD,EAAA,UAAe,GAAuB,CAAA"}
@@ -0,0 +1,13 @@
1
+ import { ReactNode } from 'react';
2
+
3
+ interface CaptchaProviderProps {
4
+ children: ReactNode;
5
+ }
6
+ /**
7
+ * Provides reCAPTCHA v3 context for invisible captcha.
8
+ * Only loads the Google reCAPTCHA script when VITE_CAPTCHA_ENABLED is "true".
9
+ * Otherwise, renders children directly without loading any scripts.
10
+ */
11
+ export declare function CaptchaProvider({ children }: CaptchaProviderProps): import("react/jsx-runtime").JSX.Element;
12
+ export {};
13
+ //# sourceMappingURL=CaptchaProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CaptchaProvider.d.ts","sourceRoot":"","sources":["../../../src/auth/providers/CaptchaProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvD,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAwBD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,EAAE,oBAAoB,2CAUjE"}
@@ -0,0 +1,21 @@
1
+ import { getRecaptchaSiteKey as e, isCaptchaEnabled as t } from "../utils/captchaConfig.js";
2
+ import { Suspense as n, lazy as r } from "react";
3
+ import { Fragment as i, jsx as a } from "react/jsx-runtime";
4
+ //#region src/auth/providers/CaptchaProvider.tsx
5
+ var o = r(() => import("../../node_modules/react-google-recaptcha-v3/dist/react-google-recaptcha-v3.esm.js").then((t) => ({ default: function({ children: n }) {
6
+ let r = e();
7
+ return r ? /* @__PURE__ */ a(t.GoogleReCaptchaProvider, {
8
+ reCaptchaKey: r,
9
+ children: n
10
+ }) : (console.warn("[captcha-v3] reCAPTCHA site key is not configured"), /* @__PURE__ */ a(i, { children: n }));
11
+ } })));
12
+ function s({ children: e }) {
13
+ return t() ? /* @__PURE__ */ a(n, {
14
+ fallback: /* @__PURE__ */ a(i, { children: e }),
15
+ children: /* @__PURE__ */ a(o, { children: e })
16
+ }) : /* @__PURE__ */ a(i, { children: e });
17
+ }
18
+ //#endregion
19
+ export { s as CaptchaProvider };
20
+
21
+ //# sourceMappingURL=CaptchaProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CaptchaProvider.js","names":[],"sources":["../../../src/auth/providers/CaptchaProvider.tsx"],"sourcesContent":["import { lazy, Suspense, type ReactNode } from \"react\";\nimport { getRecaptchaSiteKey, isCaptchaEnabled } from \"../utils/captchaConfig\";\n\ninterface CaptchaProviderProps {\n children: ReactNode;\n}\n\n/**\n * Lazily loaded v3 provider wrapper.\n * Only loaded when CAPTCHA_ENABLED is true.\n */\nconst LazyV3Provider = lazy(() =>\n import(\"react-google-recaptcha-v3\").then((mod) => ({\n default: function V3ProviderWrapper({ children }: CaptchaProviderProps) {\n const siteKey = getRecaptchaSiteKey();\n if (!siteKey) {\n console.warn(\"[captcha-v3] reCAPTCHA site key is not configured\");\n return <>{children}</>;\n }\n\n return (\n <mod.GoogleReCaptchaProvider reCaptchaKey={siteKey}>\n {children}\n </mod.GoogleReCaptchaProvider>\n );\n },\n })),\n);\n\n/**\n * Provides reCAPTCHA v3 context for invisible captcha.\n * Only loads the Google reCAPTCHA script when VITE_CAPTCHA_ENABLED is \"true\".\n * Otherwise, renders children directly without loading any scripts.\n */\nexport function CaptchaProvider({ children }: CaptchaProviderProps) {\n if (!isCaptchaEnabled()) {\n return <>{children}</>;\n }\n\n return (\n <Suspense fallback={<>{children}</>}>\n <LazyV3Provider>{children}</LazyV3Provider>\n </Suspense>\n );\n}\n"],"mappings":";;;;AAWA,IAAM,IAAiB,QACrB,OAAO,sFAA6B,MAAM,OAAS,EACjD,SAAS,SAA2B,EAAE,eAAkC;CACtE,IAAM,IAAU,GAAqB;AAMrC,QALK,IAMH,kBAAC,EAAI,yBAAL;EAA6B,cAAc;EACxC;EAC2B,CAAA,IAP9B,QAAQ,KAAK,oDAAoD,EAC1D,kBAAA,GAAA,EAAG,aAAY,CAAA;GAS3B,EAAE,CACJ;AAOD,SAAgB,EAAgB,EAAE,eAAkC;AAKlE,QAJK,GAAkB,GAKrB,kBAAC,GAAD;EAAU,UAAU,kBAAA,GAAA,EAAG,aAAY,CAAA;YACjC,kBAAC,GAAD,EAAiB,aAA0B,CAAA;EAClC,CAAA,GANJ,kBAAA,GAAA,EAAG,aAAY,CAAA"}
@@ -0,0 +1,91 @@
1
+ import { User, Session, MfaDevice, OAuthAccount, TrustedDevice, SecurityAudit, ApiKey, App, AppUserDelegation, Workspace, Organization, Project } from '../types';
2
+
3
+ interface AuthState {
4
+ user: User | null;
5
+ accessToken: string | null;
6
+ refreshToken: string | null;
7
+ isAuthenticated: boolean;
8
+ organizations: Organization[];
9
+ currentOrganizationId: string | null;
10
+ isLoadingOrganizations: boolean;
11
+ workspaces: Workspace[];
12
+ currentWorkspaceId: string | null;
13
+ workspaceToken: string | null;
14
+ isLoadingWorkspaces: boolean;
15
+ projects: Project[];
16
+ currentProjectId: string | null;
17
+ isLoadingProjects: boolean;
18
+ mfaRequired: boolean;
19
+ mfaChallengeId: string | null;
20
+ mfaDevices: MfaDevice[];
21
+ activeSessions: Session[];
22
+ currentSessionId: string | null;
23
+ linkedAccounts: OAuthAccount[];
24
+ trustedDevices: TrustedDevice[];
25
+ securityEvents: SecurityAudit[];
26
+ apiKeys: ApiKey[];
27
+ apps: App[];
28
+ currentApp: App | null;
29
+ delegations: AppUserDelegation[];
30
+ grantedDelegations: AppUserDelegation[];
31
+ isLoading: boolean;
32
+ error: string | null;
33
+ errorCode: string | null;
34
+ setUser: (user: User | null) => void;
35
+ setAccessToken: (token: string | null) => void;
36
+ setAuthTokens: (accessToken: string, refreshToken: string) => void;
37
+ setAuthenticated: (isAuthenticated: boolean) => void;
38
+ clearAuth: () => void;
39
+ setOrganizations: (organizations: Organization[]) => void;
40
+ setCurrentOrganizationId: (orgId: string | null) => void;
41
+ setLoadingOrganizations: (loading: boolean) => void;
42
+ setWorkspaces: (workspaces: Workspace[]) => void;
43
+ setCurrentWorkspaceId: (workspaceId: string | null) => void;
44
+ setWorkspaceToken: (token: string | null) => void;
45
+ setLoadingWorkspaces: (loading: boolean) => void;
46
+ clearWorkspace: () => void;
47
+ setProjects: (projects: Project[]) => void;
48
+ setCurrentProjectId: (projectId: string | null) => void;
49
+ setLoadingProjects: (loading: boolean) => void;
50
+ clearProject: () => void;
51
+ clearContext: () => void;
52
+ loadFromProfile: (profileId: string) => void;
53
+ setMfaRequired: (required: boolean, challengeId?: string) => void;
54
+ setMfaDevices: (devices: MfaDevice[]) => void;
55
+ removeMfaDevice: (deviceId: string) => void;
56
+ setActiveSessions: (sessions: Session[]) => void;
57
+ removeSession: (sessionId: string) => void;
58
+ setLinkedAccounts: (accounts: OAuthAccount[]) => void;
59
+ removeLinkedAccount: (accountId: string) => void;
60
+ setTrustedDevices: (devices: TrustedDevice[]) => void;
61
+ removeTrustedDevice: (deviceId: string) => void;
62
+ setSecurityEvents: (events: SecurityAudit[]) => void;
63
+ setApiKeys: (keys: ApiKey[]) => void;
64
+ removeApiKey: (keyId: string) => void;
65
+ setApps: (apps: App[]) => void;
66
+ setCurrentApp: (app: App | null) => void;
67
+ addApp: (app: App) => void;
68
+ updateApp: (app: App) => void;
69
+ removeApp: (appId: string) => void;
70
+ setDelegations: (delegations: AppUserDelegation[]) => void;
71
+ setGrantedDelegations: (delegations: AppUserDelegation[]) => void;
72
+ addDelegation: (delegation: AppUserDelegation) => void;
73
+ removeDelegation: (delegationId: string) => void;
74
+ setLoading: (loading: boolean) => void;
75
+ setError: (error: string | null, errorCode?: string | null) => void;
76
+ }
77
+ export declare const useAuthStore: import('zustand').UseBoundStore<Omit<import('zustand').StoreApi<AuthState>, "setState" | "persist"> & {
78
+ setState(partial: AuthState | Partial<AuthState> | ((state: AuthState) => AuthState | Partial<AuthState>), replace?: false | undefined): unknown;
79
+ setState(state: AuthState | ((state: AuthState) => AuthState), replace: true): unknown;
80
+ persist: {
81
+ setOptions: (options: Partial<import('zustand/middleware').PersistOptions<AuthState, unknown, unknown>>) => void;
82
+ clearStorage: () => void;
83
+ rehydrate: () => Promise<void> | void;
84
+ hasHydrated: () => boolean;
85
+ onHydrate: (fn: (state: AuthState) => void) => () => void;
86
+ onFinishHydration: (fn: (state: AuthState) => void) => () => void;
87
+ getOptions: () => Partial<import('zustand/middleware').PersistOptions<AuthState, unknown, unknown>>;
88
+ };
89
+ }>;
90
+ export {};
91
+ //# sourceMappingURL=authStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authStore.d.ts","sourceRoot":"","sources":["../../../src/auth/store/authStore.ts"],"names":[],"mappings":"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"}