@alepha/ui 0.14.3 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/admin/index.d.ts.map +1 -1
  2. package/dist/admin/index.js +1 -1
  3. package/dist/admin/index.js.map +1 -1
  4. package/dist/auth/Login-Cjxv3EDi.js.map +1 -1
  5. package/dist/auth/{Register-BKBIpHhW.js → Register-CGlbQ50l.js} +5 -2
  6. package/dist/auth/Register-CGlbQ50l.js.map +1 -0
  7. package/dist/auth/Register-CWdkXWkc.js +4 -0
  8. package/dist/auth/ResetPassword-DvqD_1SJ.js.map +1 -1
  9. package/dist/auth/index.d.ts +24 -20
  10. package/dist/auth/index.d.ts.map +1 -1
  11. package/dist/auth/index.js +10 -10
  12. package/dist/auth/index.js.map +1 -1
  13. package/dist/core/index.d.ts +186 -186
  14. package/dist/core/index.d.ts.map +1 -1
  15. package/dist/demo/{DemoLogin--wE44i23.js → DemoLogin-DvltFTER.js} +2 -1
  16. package/dist/demo/DemoLogin-DvltFTER.js.map +1 -0
  17. package/dist/demo/{DemoRegister-BtrMksx6.js → DemoRegister-Vu6ZPWib.js} +6 -2
  18. package/dist/demo/DemoRegister-Vu6ZPWib.js.map +1 -0
  19. package/dist/demo/{DemoResetPassword-DVXiiiX7.js → DemoResetPassword-BFwmqwec.js} +2 -1
  20. package/dist/demo/DemoResetPassword-BFwmqwec.js.map +1 -0
  21. package/dist/demo/index.d.ts +12 -12
  22. package/dist/demo/index.d.ts.map +1 -1
  23. package/dist/demo/index.js +3 -3
  24. package/dist/json/index.d.ts +18 -19
  25. package/dist/json/index.d.ts.map +1 -1
  26. package/package.json +11 -11
  27. package/src/admin/AdminRouter.ts +1 -1
  28. package/src/auth/AuthRouter.ts +10 -10
  29. package/src/auth/components/Login.tsx +2 -2
  30. package/src/auth/components/Register.tsx +8 -3
  31. package/src/auth/components/ResetPassword.tsx +2 -2
  32. package/src/demo/components/auth/DemoLogin.tsx +4 -3
  33. package/src/demo/components/auth/DemoRegister.tsx +4 -3
  34. package/src/demo/components/auth/DemoResetPassword.tsx +3 -2
  35. package/dist/auth/Register-BKBIpHhW.js.map +0 -1
  36. package/dist/auth/Register-CtdvihIM.js +0 -4
  37. package/dist/demo/DemoLogin--wE44i23.js.map +0 -1
  38. package/dist/demo/DemoRegister-BtrMksx6.js.map +0 -1
  39. package/dist/demo/DemoResetPassword-DVXiiiX7.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/admin/AdminRouter.ts","../../src/admin/components/AdminLayout.tsx","../../src/admin/components/audits/AdminAudits.tsx","../../src/admin/components/files/AdminFiles.tsx","../../src/admin/components/jobs/AdminJobs.tsx","../../src/admin/components/notifications/AdminNotifications.tsx","../../src/admin/components/parameters/AdminParameters.tsx","../../src/admin/components/sessions/AdminSessions.tsx","../../src/admin/components/users/AdminUserAudits.tsx","../../src/admin/components/users/AdminUserCreate.tsx","../../src/admin/components/users/AdminUserDetails.tsx","../../src/admin/components/users/AdminUserLayout.tsx","../../src/admin/components/users/AdminUserSessions.tsx","../../src/admin/components/users/AdminUserSettings.tsx","../../src/admin/components/users/AdminUsers.tsx","../../src/admin/components/verifications/AdminVerifications.tsx","../../src/admin/MainRouter.ts","../../src/admin/index.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/admin/AdminRouter.ts","../../src/admin/components/AdminLayout.tsx","../../src/admin/components/audits/AdminAudits.tsx","../../src/admin/components/files/AdminFiles.tsx","../../src/admin/components/jobs/AdminJobs.tsx","../../src/admin/components/notifications/AdminNotifications.tsx","../../src/admin/components/parameters/AdminParameters.tsx","../../src/admin/components/sessions/AdminSessions.tsx","../../src/admin/components/users/AdminUserAudits.tsx","../../src/admin/components/users/AdminUserCreate.tsx","../../src/admin/components/users/AdminUserDetails.tsx","../../src/admin/components/users/AdminUserLayout.tsx","../../src/admin/components/users/AdminUserSessions.tsx","../../src/admin/components/users/AdminUserSettings.tsx","../../src/admin/components/users/AdminUsers.tsx","../../src/admin/components/verifications/AdminVerifications.tsx","../../src/admin/MainRouter.ts","../../src/admin/index.ts"],"mappings":"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"}
@@ -47,7 +47,7 @@ var AdminRouter = class {
47
47
  can: () => this.userCtrl.findUsers.can(),
48
48
  lazy: () => import("./AdminLayout-BnSmtA4x.js"),
49
49
  props: () => ({ adminShellProps: this.adminShellProps() }),
50
- resolve: ({ user, url }) => {
50
+ loader: ({ user, url }) => {
51
51
  if (!user) throw this.onNotAuthorized(url);
52
52
  return {};
53
53
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["filters"],"sources":["../../src/admin/AdminRouter.ts","../../src/admin/MainRouter.ts","../../src/admin/components/jobs/AdminJobs.tsx","../../src/admin/components/verifications/AdminVerifications.tsx","../../src/admin/index.ts"],"sourcesContent":["import { ReactAuth } from \"@alepha/react/auth\";\nimport { $page, ReactRouter, Redirection } from \"@alepha/react/router\";\nimport type { AdminShellProps } from \"@alepha/ui\";\nimport { AuthRouter } from \"@alepha/ui/auth\";\nimport {\n IconBell,\n IconDevices,\n IconFile,\n IconHistory,\n IconPlus,\n IconSettings,\n IconUser,\n IconUsers,\n} from \"@tabler/icons-react\";\nimport { $inject } from \"alepha\";\nimport type { AdminAuditController } from \"alepha/api/audits\";\nimport type { FileController } from \"alepha/api/files\";\nimport type { AdminNotificationController } from \"alepha/api/notifications\";\nimport type { AdminConfigController } from \"alepha/api/parameters\";\nimport type {\n AdminSessionController,\n AdminUserController,\n} from \"alepha/api/users\";\nimport { $client } from \"alepha/server/links\";\n\nexport class AdminRouter {\n protected readonly router = $inject(ReactRouter);\n protected readonly authRouter = $inject(AuthRouter);\n protected readonly auth = $inject(ReactAuth);\n protected readonly userCtrl = $client<AdminUserController>();\n protected readonly sessionCtrl = $client<AdminSessionController>();\n protected readonly notificationCtrl = $client<AdminNotificationController>();\n protected readonly fileCtrl = $client<FileController>();\n protected readonly configCtrl = $client<AdminConfigController>();\n protected readonly auditCtrl = $client<AdminAuditController>();\n\n protected adminShellProps(): AdminShellProps {\n return {};\n }\n\n protected onNotAuthorized(url: URL) {\n return new Redirection(\n this.router.path(this.authRouter.login.name, {\n query: {\n r: url.pathname,\n },\n }),\n );\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Layout\n // ─────────────────────────────────────────────────────────────────────────────\n\n public readonly adminLayout = $page({\n path: \"/admin\",\n label: \"Admin\",\n can: () => this.userCtrl.findUsers.can(),\n lazy: () => import(\"./components/AdminLayout.tsx\"),\n props: () => ({\n adminShellProps: this.adminShellProps(),\n }),\n resolve: ({ user, url }) => {\n if (!user) {\n throw this.onNotAuthorized(url);\n }\n return {};\n },\n });\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Users\n // ─────────────────────────────────────────────────────────────────────────────\n\n public readonly adminUsers = $page({\n icon: IconUsers,\n parent: this.adminLayout,\n path: \"/users\",\n label: \"Users\",\n description: \"Manage application users and their roles.\",\n lazy: () => import(\"./components/users/AdminUsers.tsx\"),\n can: () => this.userCtrl.findUsers.can(),\n });\n\n public readonly adminUserCreate = $page({\n icon: IconPlus,\n parent: this.adminLayout,\n path: \"/users/create\",\n label: \"Create User\",\n description: \"Create a new user account.\",\n lazy: () => import(\"./components/users/AdminUserCreate.tsx\"),\n can: () => this.userCtrl.createUser.can(),\n });\n\n public readonly adminUserLayout = $page({\n icon: IconUser,\n parent: this.adminLayout,\n path: \"/users/:userId\",\n label: \"User\",\n lazy: () => import(\"./components/users/AdminUserLayout.tsx\"),\n can: () => this.userCtrl.getUser.can(),\n });\n\n public readonly adminUserDetails = $page({\n parent: this.adminUserLayout,\n path: \"/details\",\n label: \"Details\",\n lazy: () => import(\"./components/users/AdminUserDetails.tsx\"),\n });\n\n public readonly adminUserSessions = $page({\n parent: this.adminUserLayout,\n path: \"/sessions\",\n label: \"Sessions\",\n lazy: () => import(\"./components/users/AdminUserSessions.tsx\"),\n });\n\n public readonly adminUserSettings = $page({\n parent: this.adminUserLayout,\n path: \"/settings\",\n label: \"Settings\",\n lazy: () => import(\"./components/users/AdminUserSettings.tsx\"),\n });\n\n public readonly adminUserAudits = $page({\n parent: this.adminUserLayout,\n path: \"/audits\",\n label: \"Audit Log\",\n lazy: () => import(\"./components/users/AdminUserAudits.tsx\"),\n can: () => this.auditCtrl.findByUser.can(),\n });\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Audits (Global)\n // ─────────────────────────────────────────────────────────────────────────────\n\n public readonly adminAudits = $page({\n icon: IconHistory,\n parent: this.adminLayout,\n path: \"/audits\",\n label: \"Audit Log\",\n description: \"View system-wide audit trail and activity logs.\",\n lazy: () => import(\"./components/audits/AdminAudits.tsx\"),\n can: () => this.auditCtrl.findAudits.can(),\n });\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Sessions\n // ─────────────────────────────────────────────────────────────────────────────\n\n public readonly adminSessions = $page({\n icon: IconDevices,\n parent: this.adminLayout,\n path: \"/sessions\",\n label: \"Sessions\",\n description: \"View and manage all active sessions.\",\n lazy: () => import(\"./components/sessions/AdminSessions.tsx\"),\n can: () => this.sessionCtrl.findSessions.can(),\n });\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Notifications\n // ─────────────────────────────────────────────────────────────────────────────\n\n public readonly adminNotifications = $page({\n icon: IconBell,\n parent: this.adminLayout,\n path: \"/notifications\",\n label: \"Notifications\",\n description: \"View notification history and status.\",\n lazy: () => import(\"./components/notifications/AdminNotifications.tsx\"),\n can: () => this.notificationCtrl.findNotifications.can(),\n });\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Files\n // ─────────────────────────────────────────────────────────────────────────────\n\n public readonly adminFiles = $page({\n icon: IconFile,\n parent: this.adminLayout,\n path: \"/files\",\n label: \"Files\",\n description: \"Manage uploaded files and storage.\",\n lazy: () => import(\"./components/files/AdminFiles.tsx\"),\n can: () => this.fileCtrl.findFiles.can(),\n });\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Parameters\n // ─────────────────────────────────────────────────────────────────────────────\n\n public readonly adminParameters = $page({\n icon: IconSettings,\n parent: this.adminLayout,\n path: \"/parameters\",\n label: \"Parameters\",\n description: \"View and manage application configuration parameters.\",\n lazy: () => import(\"./components/parameters/AdminParameters.tsx\"),\n can: () => this.configCtrl.getConfigTree.can(),\n });\n}\n","import { $page } from \"@alepha/react/router\";\nimport { AlephaMantineProvider } from \"@alepha/ui\";\nimport { AuthRouter } from \"@alepha/ui/auth\";\nimport { $inject } from \"alepha\";\nimport { AdminRouter } from \"./AdminRouter.ts\";\n\n/**\n * Main application router that combines Auth and Admin routers.\n *\n * We assume that the main application router will always have Admin and Auth routers.\n *\n * This is basically a convenience class to avoid having to inject these routers everywhere.\n * Code is lightweight enough that we can just copy it if needed.\n */\nexport class MainRouter {\n auth = $inject(AuthRouter);\n admin = $inject(AdminRouter);\n\n layout = $page({\n component: AlephaMantineProvider,\n children: () => [this.auth.layout, this.admin.adminLayout],\n });\n}\n","import { useClient } from \"@alepha/react\";\nimport { useI18n } from \"@alepha/react/i18n\";\nimport { DataTable, Flex, Text } from \"@alepha/ui\";\nimport { Badge } from \"@mantine/core\";\nimport {\n IconCheck,\n IconClock,\n IconPlayerPlay,\n IconX,\n} from \"@tabler/icons-react\";\nimport { type Page, t } from \"alepha\";\nimport {\n type AdminJobController,\n type JobExecutionEntity,\n jobExecutions,\n} from \"alepha/api/jobs\";\n\nconst AdminJobs = () => {\n const client = useClient<AdminJobController>();\n const { l } = useI18n();\n\n const filters = t.object({\n job: t.optional(\n t.string({\n $control: {\n query: t.pick(jobExecutions.schema, [\"job\"]),\n },\n }),\n ),\n status: t.optional(t.enum([\"STARTED\", \"FAILED\", \"COMPLETED\"])),\n });\n\n const getStatusColor = (status: string) => {\n switch (status) {\n case \"COMPLETED\":\n return \"green\";\n case \"FAILED\":\n return \"red\";\n case \"STARTED\":\n return \"blue\";\n default:\n return \"gray\";\n }\n };\n\n const getStatusIcon = (status: string) => {\n switch (status) {\n case \"COMPLETED\":\n return <IconCheck size={12} />;\n case \"FAILED\":\n return <IconX size={12} />;\n case \"STARTED\":\n return <IconPlayerPlay size={12} />;\n default:\n return <IconClock size={12} />;\n }\n };\n\n const formatDuration = (\n start: Date | string,\n end?: Date | string | null,\n ): string => {\n const startTime = new Date(start).getTime();\n const endTime = end ? new Date(end).getTime() : Date.now();\n const duration = endTime - startTime;\n\n if (duration < 1000) return `${duration}ms`;\n if (duration < 60000) return `${(duration / 1000).toFixed(1)}s`;\n return `${Math.floor(duration / 60000)}m ${Math.floor((duration % 60000) / 1000)}s`;\n };\n\n return (\n <Flex flex={1} direction={\"column\"}>\n <DataTable<JobExecutionEntity, typeof filters>\n submitOnInit\n defaultSize={10}\n typeFormProps={{\n skipSubmitButton: true,\n columns: 3,\n }}\n tableProps={{\n horizontalSpacing: \"xs\",\n verticalSpacing: \"xs\",\n }}\n onFilterChange={(key, _value, form) => {\n if (key === \"job\" || key === \"status\") {\n return form.submit();\n }\n }}\n filters={filters}\n items={async (filters) => {\n const response = await client.getJobExecutions({\n query: filters,\n });\n\n return response as Page<JobExecutionEntity>;\n }}\n columns={{\n job: {\n label: \"Job\",\n value: (item) => (\n <Text size=\"sm\" fw={500}>\n {item.job}\n </Text>\n ),\n },\n status: {\n label: \"Status\",\n fit: true,\n value: (item) => (\n <Badge\n size=\"sm\"\n variant=\"light\"\n color={getStatusColor(item.status)}\n leftSection={getStatusIcon(item.status)}\n >\n {item.status}\n </Badge>\n ),\n },\n duration: {\n label: \"Duration\",\n fit: true,\n value: (item) => (\n <Text size=\"xs\" c=\"dimmed\" ff=\"monospace\">\n {formatDuration(item.createdAt, item.finishedAt)}\n </Text>\n ),\n },\n error: {\n label: \"Error\",\n value: (item) =>\n item.error ? (\n <Text size=\"xs\" c=\"red\" lineClamp={1}>\n {item.error}\n </Text>\n ) : (\n <Text size=\"xs\" c=\"dimmed\">\n -\n </Text>\n ),\n },\n createdAt: {\n label: \"Started\",\n fit: true,\n value: (item) => (\n <Text size=\"xs\" c=\"dimmed\">\n {l(item.createdAt, { date: \"fromNow\" })}\n </Text>\n ),\n },\n }}\n />\n </Flex>\n );\n};\n\nexport default AdminJobs;\n","import { Flex, Text } from \"@alepha/ui\";\nimport { Stack } from \"@mantine/core\";\nimport { IconShieldCheck } from \"@tabler/icons-react\";\n\nconst AdminVerifications = () => {\n return (\n <Flex flex={1} justify=\"center\" align=\"center\">\n <Stack align=\"center\" gap=\"xs\">\n <IconShieldCheck\n size={48}\n stroke={1.5}\n color=\"var(--mantine-color-dimmed)\"\n />\n <Text c=\"dimmed\">Verification Management</Text>\n <Text size=\"xs\" c=\"dimmed\" ta=\"center\" maw={400}>\n Verifications are automatically managed by the system. Email and SMS\n verification codes are generated and validated through the\n verification API endpoints.\n </Text>\n </Stack>\n </Flex>\n );\n};\n\nexport default AdminVerifications;\n","import { AlephaUI } from \"@alepha/ui\";\nimport { AlephaUIAuth } from \"@alepha/ui/auth\";\nimport { $module } from \"alepha\";\nimport { AdminRouter } from \"./AdminRouter.ts\";\nimport { MainRouter } from \"./MainRouter.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport { AdminRouter } from \"./AdminRouter.ts\";\n// Layout\nexport { default as AdminLayout } from \"./components/AdminLayout.tsx\";\n// Audits\nexport { default as AdminAudits } from \"./components/audits/AdminAudits.tsx\";\n// Files\nexport { default as AdminFiles } from \"./components/files/AdminFiles.tsx\";\n// Jobs\nexport { default as AdminJobs } from \"./components/jobs/AdminJobs.tsx\";\n// Notifications\nexport { default as AdminNotifications } from \"./components/notifications/AdminNotifications.tsx\";\n// Parameters\nexport { default as AdminParameters } from \"./components/parameters/AdminParameters.tsx\";\n// Sessions\nexport { default as AdminSessions } from \"./components/sessions/AdminSessions.tsx\";\n// Users\nexport { default as AdminUserAudits } from \"./components/users/AdminUserAudits.tsx\";\nexport { default as AdminUserCreate } from \"./components/users/AdminUserCreate.tsx\";\nexport { default as AdminUserDetails } from \"./components/users/AdminUserDetails.tsx\";\nexport { default as AdminUserLayout } from \"./components/users/AdminUserLayout.tsx\";\nexport { default as AdminUserSessions } from \"./components/users/AdminUserSessions.tsx\";\nexport { default as AdminUserSettings } from \"./components/users/AdminUserSettings.tsx\";\nexport { default as AdminUsers } from \"./components/users/AdminUsers.tsx\";\n// Verifications\nexport { default as AdminVerifications } from \"./components/verifications/AdminVerifications.tsx\";\nexport { MainRouter } from \"./MainRouter.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Admin panel UI Module\n *\n * @module alepha.ui.admin\n */\nexport const AlephaUIAdmin = $module({\n name: \"alepha.ui.admin\",\n services: [AlephaUI, AlephaUIAuth, AdminRouter, MainRouter],\n register: (alepha) => {\n alepha.with(AdminRouter);\n },\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["filters"],"sources":["../../src/admin/AdminRouter.ts","../../src/admin/MainRouter.ts","../../src/admin/components/jobs/AdminJobs.tsx","../../src/admin/components/verifications/AdminVerifications.tsx","../../src/admin/index.ts"],"sourcesContent":["import { ReactAuth } from \"@alepha/react/auth\";\nimport { $page, ReactRouter, Redirection } from \"@alepha/react/router\";\nimport type { AdminShellProps } from \"@alepha/ui\";\nimport { AuthRouter } from \"@alepha/ui/auth\";\nimport {\n IconBell,\n IconDevices,\n IconFile,\n IconHistory,\n IconPlus,\n IconSettings,\n IconUser,\n IconUsers,\n} from \"@tabler/icons-react\";\nimport { $inject } from \"alepha\";\nimport type { AdminAuditController } from \"alepha/api/audits\";\nimport type { FileController } from \"alepha/api/files\";\nimport type { AdminNotificationController } from \"alepha/api/notifications\";\nimport type { AdminConfigController } from \"alepha/api/parameters\";\nimport type {\n AdminSessionController,\n AdminUserController,\n} from \"alepha/api/users\";\nimport { $client } from \"alepha/server/links\";\n\nexport class AdminRouter {\n protected readonly router = $inject(ReactRouter);\n protected readonly authRouter = $inject(AuthRouter);\n protected readonly auth = $inject(ReactAuth);\n protected readonly userCtrl = $client<AdminUserController>();\n protected readonly sessionCtrl = $client<AdminSessionController>();\n protected readonly notificationCtrl = $client<AdminNotificationController>();\n protected readonly fileCtrl = $client<FileController>();\n protected readonly configCtrl = $client<AdminConfigController>();\n protected readonly auditCtrl = $client<AdminAuditController>();\n\n protected adminShellProps(): AdminShellProps {\n return {};\n }\n\n protected onNotAuthorized(url: URL) {\n return new Redirection(\n this.router.path(this.authRouter.login.name, {\n query: {\n r: url.pathname,\n },\n }),\n );\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Layout\n // ─────────────────────────────────────────────────────────────────────────────\n\n public readonly adminLayout = $page({\n path: \"/admin\",\n label: \"Admin\",\n can: () => this.userCtrl.findUsers.can(),\n lazy: () => import(\"./components/AdminLayout.tsx\"),\n props: () => ({\n adminShellProps: this.adminShellProps(),\n }),\n loader: ({ user, url }) => {\n if (!user) {\n throw this.onNotAuthorized(url);\n }\n return {};\n },\n });\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Users\n // ─────────────────────────────────────────────────────────────────────────────\n\n public readonly adminUsers = $page({\n icon: IconUsers,\n parent: this.adminLayout,\n path: \"/users\",\n label: \"Users\",\n description: \"Manage application users and their roles.\",\n lazy: () => import(\"./components/users/AdminUsers.tsx\"),\n can: () => this.userCtrl.findUsers.can(),\n });\n\n public readonly adminUserCreate = $page({\n icon: IconPlus,\n parent: this.adminLayout,\n path: \"/users/create\",\n label: \"Create User\",\n description: \"Create a new user account.\",\n lazy: () => import(\"./components/users/AdminUserCreate.tsx\"),\n can: () => this.userCtrl.createUser.can(),\n });\n\n public readonly adminUserLayout = $page({\n icon: IconUser,\n parent: this.adminLayout,\n path: \"/users/:userId\",\n label: \"User\",\n lazy: () => import(\"./components/users/AdminUserLayout.tsx\"),\n can: () => this.userCtrl.getUser.can(),\n });\n\n public readonly adminUserDetails = $page({\n parent: this.adminUserLayout,\n path: \"/details\",\n label: \"Details\",\n lazy: () => import(\"./components/users/AdminUserDetails.tsx\"),\n });\n\n public readonly adminUserSessions = $page({\n parent: this.adminUserLayout,\n path: \"/sessions\",\n label: \"Sessions\",\n lazy: () => import(\"./components/users/AdminUserSessions.tsx\"),\n });\n\n public readonly adminUserSettings = $page({\n parent: this.adminUserLayout,\n path: \"/settings\",\n label: \"Settings\",\n lazy: () => import(\"./components/users/AdminUserSettings.tsx\"),\n });\n\n public readonly adminUserAudits = $page({\n parent: this.adminUserLayout,\n path: \"/audits\",\n label: \"Audit Log\",\n lazy: () => import(\"./components/users/AdminUserAudits.tsx\"),\n can: () => this.auditCtrl.findByUser.can(),\n });\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Audits (Global)\n // ─────────────────────────────────────────────────────────────────────────────\n\n public readonly adminAudits = $page({\n icon: IconHistory,\n parent: this.adminLayout,\n path: \"/audits\",\n label: \"Audit Log\",\n description: \"View system-wide audit trail and activity logs.\",\n lazy: () => import(\"./components/audits/AdminAudits.tsx\"),\n can: () => this.auditCtrl.findAudits.can(),\n });\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Sessions\n // ─────────────────────────────────────────────────────────────────────────────\n\n public readonly adminSessions = $page({\n icon: IconDevices,\n parent: this.adminLayout,\n path: \"/sessions\",\n label: \"Sessions\",\n description: \"View and manage all active sessions.\",\n lazy: () => import(\"./components/sessions/AdminSessions.tsx\"),\n can: () => this.sessionCtrl.findSessions.can(),\n });\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Notifications\n // ─────────────────────────────────────────────────────────────────────────────\n\n public readonly adminNotifications = $page({\n icon: IconBell,\n parent: this.adminLayout,\n path: \"/notifications\",\n label: \"Notifications\",\n description: \"View notification history and status.\",\n lazy: () => import(\"./components/notifications/AdminNotifications.tsx\"),\n can: () => this.notificationCtrl.findNotifications.can(),\n });\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Files\n // ─────────────────────────────────────────────────────────────────────────────\n\n public readonly adminFiles = $page({\n icon: IconFile,\n parent: this.adminLayout,\n path: \"/files\",\n label: \"Files\",\n description: \"Manage uploaded files and storage.\",\n lazy: () => import(\"./components/files/AdminFiles.tsx\"),\n can: () => this.fileCtrl.findFiles.can(),\n });\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Parameters\n // ─────────────────────────────────────────────────────────────────────────────\n\n public readonly adminParameters = $page({\n icon: IconSettings,\n parent: this.adminLayout,\n path: \"/parameters\",\n label: \"Parameters\",\n description: \"View and manage application configuration parameters.\",\n lazy: () => import(\"./components/parameters/AdminParameters.tsx\"),\n can: () => this.configCtrl.getConfigTree.can(),\n });\n}\n","import { $page } from \"@alepha/react/router\";\nimport { AlephaMantineProvider } from \"@alepha/ui\";\nimport { AuthRouter } from \"@alepha/ui/auth\";\nimport { $inject } from \"alepha\";\nimport { AdminRouter } from \"./AdminRouter.ts\";\n\n/**\n * Main application router that combines Auth and Admin routers.\n *\n * We assume that the main application router will always have Admin and Auth routers.\n *\n * This is basically a convenience class to avoid having to inject these routers everywhere.\n * Code is lightweight enough that we can just copy it if needed.\n */\nexport class MainRouter {\n auth = $inject(AuthRouter);\n admin = $inject(AdminRouter);\n\n layout = $page({\n component: AlephaMantineProvider,\n children: () => [this.auth.layout, this.admin.adminLayout],\n });\n}\n","import { useClient } from \"@alepha/react\";\nimport { useI18n } from \"@alepha/react/i18n\";\nimport { DataTable, Flex, Text } from \"@alepha/ui\";\nimport { Badge } from \"@mantine/core\";\nimport {\n IconCheck,\n IconClock,\n IconPlayerPlay,\n IconX,\n} from \"@tabler/icons-react\";\nimport { type Page, t } from \"alepha\";\nimport {\n type AdminJobController,\n type JobExecutionEntity,\n jobExecutions,\n} from \"alepha/api/jobs\";\n\nconst AdminJobs = () => {\n const client = useClient<AdminJobController>();\n const { l } = useI18n();\n\n const filters = t.object({\n job: t.optional(\n t.string({\n $control: {\n query: t.pick(jobExecutions.schema, [\"job\"]),\n },\n }),\n ),\n status: t.optional(t.enum([\"STARTED\", \"FAILED\", \"COMPLETED\"])),\n });\n\n const getStatusColor = (status: string) => {\n switch (status) {\n case \"COMPLETED\":\n return \"green\";\n case \"FAILED\":\n return \"red\";\n case \"STARTED\":\n return \"blue\";\n default:\n return \"gray\";\n }\n };\n\n const getStatusIcon = (status: string) => {\n switch (status) {\n case \"COMPLETED\":\n return <IconCheck size={12} />;\n case \"FAILED\":\n return <IconX size={12} />;\n case \"STARTED\":\n return <IconPlayerPlay size={12} />;\n default:\n return <IconClock size={12} />;\n }\n };\n\n const formatDuration = (\n start: Date | string,\n end?: Date | string | null,\n ): string => {\n const startTime = new Date(start).getTime();\n const endTime = end ? new Date(end).getTime() : Date.now();\n const duration = endTime - startTime;\n\n if (duration < 1000) return `${duration}ms`;\n if (duration < 60000) return `${(duration / 1000).toFixed(1)}s`;\n return `${Math.floor(duration / 60000)}m ${Math.floor((duration % 60000) / 1000)}s`;\n };\n\n return (\n <Flex flex={1} direction={\"column\"}>\n <DataTable<JobExecutionEntity, typeof filters>\n submitOnInit\n defaultSize={10}\n typeFormProps={{\n skipSubmitButton: true,\n columns: 3,\n }}\n tableProps={{\n horizontalSpacing: \"xs\",\n verticalSpacing: \"xs\",\n }}\n onFilterChange={(key, _value, form) => {\n if (key === \"job\" || key === \"status\") {\n return form.submit();\n }\n }}\n filters={filters}\n items={async (filters) => {\n const response = await client.getJobExecutions({\n query: filters,\n });\n\n return response as Page<JobExecutionEntity>;\n }}\n columns={{\n job: {\n label: \"Job\",\n value: (item) => (\n <Text size=\"sm\" fw={500}>\n {item.job}\n </Text>\n ),\n },\n status: {\n label: \"Status\",\n fit: true,\n value: (item) => (\n <Badge\n size=\"sm\"\n variant=\"light\"\n color={getStatusColor(item.status)}\n leftSection={getStatusIcon(item.status)}\n >\n {item.status}\n </Badge>\n ),\n },\n duration: {\n label: \"Duration\",\n fit: true,\n value: (item) => (\n <Text size=\"xs\" c=\"dimmed\" ff=\"monospace\">\n {formatDuration(item.createdAt, item.finishedAt)}\n </Text>\n ),\n },\n error: {\n label: \"Error\",\n value: (item) =>\n item.error ? (\n <Text size=\"xs\" c=\"red\" lineClamp={1}>\n {item.error}\n </Text>\n ) : (\n <Text size=\"xs\" c=\"dimmed\">\n -\n </Text>\n ),\n },\n createdAt: {\n label: \"Started\",\n fit: true,\n value: (item) => (\n <Text size=\"xs\" c=\"dimmed\">\n {l(item.createdAt, { date: \"fromNow\" })}\n </Text>\n ),\n },\n }}\n />\n </Flex>\n );\n};\n\nexport default AdminJobs;\n","import { Flex, Text } from \"@alepha/ui\";\nimport { Stack } from \"@mantine/core\";\nimport { IconShieldCheck } from \"@tabler/icons-react\";\n\nconst AdminVerifications = () => {\n return (\n <Flex flex={1} justify=\"center\" align=\"center\">\n <Stack align=\"center\" gap=\"xs\">\n <IconShieldCheck\n size={48}\n stroke={1.5}\n color=\"var(--mantine-color-dimmed)\"\n />\n <Text c=\"dimmed\">Verification Management</Text>\n <Text size=\"xs\" c=\"dimmed\" ta=\"center\" maw={400}>\n Verifications are automatically managed by the system. Email and SMS\n verification codes are generated and validated through the\n verification API endpoints.\n </Text>\n </Stack>\n </Flex>\n );\n};\n\nexport default AdminVerifications;\n","import { AlephaUI } from \"@alepha/ui\";\nimport { AlephaUIAuth } from \"@alepha/ui/auth\";\nimport { $module } from \"alepha\";\nimport { AdminRouter } from \"./AdminRouter.ts\";\nimport { MainRouter } from \"./MainRouter.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport { AdminRouter } from \"./AdminRouter.ts\";\n// Layout\nexport { default as AdminLayout } from \"./components/AdminLayout.tsx\";\n// Audits\nexport { default as AdminAudits } from \"./components/audits/AdminAudits.tsx\";\n// Files\nexport { default as AdminFiles } from \"./components/files/AdminFiles.tsx\";\n// Jobs\nexport { default as AdminJobs } from \"./components/jobs/AdminJobs.tsx\";\n// Notifications\nexport { default as AdminNotifications } from \"./components/notifications/AdminNotifications.tsx\";\n// Parameters\nexport { default as AdminParameters } from \"./components/parameters/AdminParameters.tsx\";\n// Sessions\nexport { default as AdminSessions } from \"./components/sessions/AdminSessions.tsx\";\n// Users\nexport { default as AdminUserAudits } from \"./components/users/AdminUserAudits.tsx\";\nexport { default as AdminUserCreate } from \"./components/users/AdminUserCreate.tsx\";\nexport { default as AdminUserDetails } from \"./components/users/AdminUserDetails.tsx\";\nexport { default as AdminUserLayout } from \"./components/users/AdminUserLayout.tsx\";\nexport { default as AdminUserSessions } from \"./components/users/AdminUserSessions.tsx\";\nexport { default as AdminUserSettings } from \"./components/users/AdminUserSettings.tsx\";\nexport { default as AdminUsers } from \"./components/users/AdminUsers.tsx\";\n// Verifications\nexport { default as AdminVerifications } from \"./components/verifications/AdminVerifications.tsx\";\nexport { MainRouter } from \"./MainRouter.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Admin panel UI Module\n *\n * @module alepha.ui.admin\n */\nexport const AlephaUIAdmin = $module({\n name: \"alepha.ui.admin\",\n services: [AlephaUI, AlephaUIAuth, AdminRouter, MainRouter],\n register: (alepha) => {\n alepha.with(AdminRouter);\n },\n});\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Login-Cjxv3EDi.js","names":["IconGoogle","IconGithub"],"sources":["../../src/auth/components/Login.tsx"],"sourcesContent":["import { useAuth } from \"@alepha/react/auth\";\nimport { FormValidationError, useForm } from \"@alepha/react/form\";\nimport { useI18n } from \"@alepha/react/i18n\";\nimport { useRouter } from \"@alepha/react/router\";\nimport { ActionButton, Control, capitalize } from \"@alepha/ui\";\nimport { Card, Flex, Group, Image, Stack, Text, Title } from \"@mantine/core\";\nimport { IconLock, IconUser } from \"@tabler/icons-react\";\nimport { AlephaError, t } from \"alepha\";\nimport type { UserRealmConfig } from \"alepha/api/users\";\nimport { HttpError } from \"alepha/server\";\nimport { useMemo } from \"react\";\nimport type { AuthI18n } from \"../AuthI18n.ts\";\nimport type { AuthRouter } from \"../AuthRouter.ts\";\nimport IconGithub from \"./icons/IconGithub.tsx\";\nimport IconGoogle from \"./icons/IconGoogle.tsx\";\n\nexport interface LoginProps {\n realmConfig: UserRealmConfig;\n}\n\nconst Login = (props: LoginProps) => {\n const auth = useAuth();\n const router = useRouter<AuthRouter>();\n const { tr } = useI18n<AuthI18n, \"en\">();\n const redirect = router.query.r || \"/\";\n\n const credentialsProvider = props.realmConfig.authenticationMethods.find(\n (it) => it.type === \"CREDENTIALS\",\n );\n\n const settings = props.realmConfig.settings;\n\n // Determine what login methods are available\n const loginMethods = useMemo(() => {\n const methods = [];\n if (settings.usernameEnabled !== false) methods.push(\"username\");\n if (settings.emailEnabled !== false) methods.push(\"email\");\n if (settings.phoneEnabled === true) methods.push(\"phone\");\n return methods;\n }, [settings]);\n\n // Create identifier title based on enabled methods\n const identifierTitle = useMemo(() => {\n if (loginMethods.length === 0) return tr(\"loginUsername\");\n if (loginMethods.length === 1) {\n if (loginMethods[0] === \"username\") return tr(\"loginUsername\");\n if (loginMethods[0] === \"email\") return tr(\"loginEmail\");\n if (loginMethods[0] === \"phone\") return tr(\"loginPhone\");\n }\n const labels = loginMethods.map((m) => {\n if (m === \"username\") return tr(\"loginUsername\").toLowerCase();\n if (m === \"email\") return tr(\"loginEmail\").toLowerCase();\n if (m === \"phone\") return tr(\"loginPhone\").toLowerCase();\n return m;\n });\n return capitalize(\n `${labels.slice(0, -1).join(\", \")} or ${labels[labels.length - 1]}`,\n );\n }, [loginMethods, tr]);\n\n const form = useForm({\n schema: t.object({\n identifier: t.string({\n minLength: 1,\n }),\n password: t.string({\n minLength: settings.passwordPolicy?.minLength || 6,\n }),\n }),\n handler: async (data) => {\n if (!credentialsProvider) {\n throw new AlephaError(\"Credentials provider not configured\");\n }\n\n try {\n await auth.login(credentialsProvider.name, {\n username: data.identifier,\n password: data.password,\n realm: props.realmConfig.realmName,\n });\n await router.go(router.query.r || \"/\");\n } catch (error) {\n if (\n error instanceof HttpError &&\n error.error === \"InvalidCredentialsError\"\n ) {\n throw new FormValidationError({\n message: \"Invalid identifier or password\",\n path: \"/password\",\n });\n }\n throw error;\n }\n },\n });\n\n const getAutoCompleteType = () => {\n if (loginMethods.includes(\"email\")) {\n return \"email\";\n }\n if (loginMethods.includes(\"username\")) {\n return \"username\";\n }\n if (loginMethods.includes(\"phone\")) {\n return \"tel\";\n }\n return \"username\";\n };\n\n const externalLoginMethods = props.realmConfig.authenticationMethods.filter(\n (method) => method.type !== \"CREDENTIALS\",\n );\n\n const showOrDivider = credentialsProvider && externalLoginMethods.length > 0;\n\n return (\n <Flex flex={1} justify={\"center\"} align={\"center\"}>\n <Stack gap={\"sm\"} w={360}>\n <Card withBorder p={\"lg\"} bg={\"var(--alepha-elevated)\"}>\n <Stack gap={\"md\"}>\n {/* Realm branding */}\n {(settings.logoUrl ||\n settings.displayName ||\n settings.description) && (\n <Stack gap={\"xs\"} align=\"center\" mb=\"xs\">\n {settings.logoUrl && (\n <Image\n src={settings.logoUrl}\n alt={settings.displayName || props.realmConfig.realmName}\n h={48}\n w=\"auto\"\n fit=\"contain\"\n />\n )}\n {settings.displayName && (\n <Title order={4} ta=\"center\">\n {settings.displayName}\n </Title>\n )}\n {settings.description && (\n <Text size=\"sm\" c=\"dimmed\" ta=\"center\">\n {settings.description}\n </Text>\n )}\n </Stack>\n )}\n\n {/* Credentials login form */}\n {credentialsProvider && (\n <>\n <form {...form.props}>\n <Stack flex={1} gap={\"md\"}>\n <Control\n title={identifierTitle}\n input={form.input.identifier}\n icon={IconUser}\n text={{\n autoComplete: getAutoCompleteType(),\n }}\n />\n <Control\n title={tr(\"loginPassword\")}\n input={form.input.password}\n icon={IconLock}\n password={{\n autoComplete: \"current-password\",\n }}\n />\n <ActionButton variant={\"filled\"} form={form}>\n {tr(\"loginSignIn\")}\n </ActionButton>\n </Stack>\n </form>\n {settings.resetPasswordAllowed && (\n <Text size=\"sm\" ta=\"center\">\n <ActionButton\n href={router.path(\"resetPassword\", {\n query: { realm: props.realmConfig.realmName },\n })}\n anchorProps={{ inherit: true }}\n >\n {tr(\"loginForgotPassword\")}\n </ActionButton>\n </Text>\n )}\n </>\n )}\n\n {/* OR divider - only when both credentials AND external methods exist */}\n {showOrDivider && (\n <Group align=\"center\" justify=\"center\" gap={\"md\"}>\n <Flex flex={1} h={\"1px\"} bg={\"var(--alepha-border)\"} />\n <Text size=\"xs\" c={\"dimmed\"}>\n {tr(\"loginOr\")}\n </Text>\n <Flex flex={1} h={\"1px\"} bg={\"var(--alepha-border)\"} />\n </Group>\n )}\n\n {/* External login methods */}\n {externalLoginMethods.length > 0 && (\n <Stack gap={\"sm\"}>\n {externalLoginMethods.map((method) => (\n <ActionButton\n variant={\"default\"}\n key={method.type}\n leftSection={leftSection(method.name.toLowerCase())}\n onClick={() =>\n auth.login(method.name, {\n redirect,\n realm: props.realmConfig.realmName,\n })\n }\n >\n {tr(\"loginContinueWith\", {\n args: [capitalize(method.name)],\n })}\n </ActionButton>\n ))}\n </Stack>\n )}\n\n {/* Registration link */}\n {settings.registrationAllowed && (\n <Text size=\"sm\" ta=\"center\">\n {tr(\"loginNoAccount\")}{\" \"}\n <ActionButton\n href={router.path(\"register\", {\n query: { realm: props.realmConfig.realmName },\n })}\n anchorProps={{ inherit: true }}\n >\n {tr(\"loginSignUp\")}\n </ActionButton>\n </Text>\n )}\n </Stack>\n </Card>\n <ActionButton variant={\"subtle\"} href={\"/\"}>\n {tr(\"loginCancel\")}\n </ActionButton>\n </Stack>\n </Flex>\n );\n};\n\nexport default Login;\n\nconst leftSection = (name: string) => {\n if (name === \"google\") {\n return <IconGoogle />;\n }\n\n if (name === \"github\") {\n return <IconGithub />;\n }\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"Login-Cjxv3EDi.js","names":["IconGoogle","IconGithub"],"sources":["../../src/auth/components/Login.tsx"],"sourcesContent":["import { useAuth } from \"@alepha/react/auth\";\nimport { FormValidationError, useForm } from \"@alepha/react/form\";\nimport { useI18n } from \"@alepha/react/i18n\";\nimport { useRouter } from \"@alepha/react/router\";\nimport { ActionButton, Control, capitalize } from \"@alepha/ui\";\nimport { Card, Flex, Group, Image, Stack, Text, Title } from \"@mantine/core\";\nimport { IconLock, IconUser } from \"@tabler/icons-react\";\nimport { AlephaError, t } from \"alepha\";\nimport type { RealmConfig } from \"alepha/api/users\";\nimport { HttpError } from \"alepha/server\";\nimport { useMemo } from \"react\";\nimport type { AuthI18n } from \"../AuthI18n.ts\";\nimport type { AuthRouter } from \"../AuthRouter.ts\";\nimport IconGithub from \"./icons/IconGithub.tsx\";\nimport IconGoogle from \"./icons/IconGoogle.tsx\";\n\nexport interface LoginProps {\n realmConfig: RealmConfig;\n}\n\nconst Login = (props: LoginProps) => {\n const auth = useAuth();\n const router = useRouter<AuthRouter>();\n const { tr } = useI18n<AuthI18n, \"en\">();\n const redirect = router.query.r || \"/\";\n\n const credentialsProvider = props.realmConfig.authenticationMethods.find(\n (it) => it.type === \"CREDENTIALS\",\n );\n\n const settings = props.realmConfig.settings;\n\n // Determine what login methods are available\n const loginMethods = useMemo(() => {\n const methods = [];\n if (settings.usernameEnabled !== false) methods.push(\"username\");\n if (settings.emailEnabled !== false) methods.push(\"email\");\n if (settings.phoneEnabled === true) methods.push(\"phone\");\n return methods;\n }, [settings]);\n\n // Create identifier title based on enabled methods\n const identifierTitle = useMemo(() => {\n if (loginMethods.length === 0) return tr(\"loginUsername\");\n if (loginMethods.length === 1) {\n if (loginMethods[0] === \"username\") return tr(\"loginUsername\");\n if (loginMethods[0] === \"email\") return tr(\"loginEmail\");\n if (loginMethods[0] === \"phone\") return tr(\"loginPhone\");\n }\n const labels = loginMethods.map((m) => {\n if (m === \"username\") return tr(\"loginUsername\").toLowerCase();\n if (m === \"email\") return tr(\"loginEmail\").toLowerCase();\n if (m === \"phone\") return tr(\"loginPhone\").toLowerCase();\n return m;\n });\n return capitalize(\n `${labels.slice(0, -1).join(\", \")} or ${labels[labels.length - 1]}`,\n );\n }, [loginMethods, tr]);\n\n const form = useForm({\n schema: t.object({\n identifier: t.string({\n minLength: 1,\n }),\n password: t.string({\n minLength: settings.passwordPolicy?.minLength || 6,\n }),\n }),\n handler: async (data) => {\n if (!credentialsProvider) {\n throw new AlephaError(\"Credentials provider not configured\");\n }\n\n try {\n await auth.login(credentialsProvider.name, {\n username: data.identifier,\n password: data.password,\n realm: props.realmConfig.realmName,\n });\n await router.go(router.query.r || \"/\");\n } catch (error) {\n if (\n error instanceof HttpError &&\n error.error === \"InvalidCredentialsError\"\n ) {\n throw new FormValidationError({\n message: \"Invalid identifier or password\",\n path: \"/password\",\n });\n }\n throw error;\n }\n },\n });\n\n const getAutoCompleteType = () => {\n if (loginMethods.includes(\"email\")) {\n return \"email\";\n }\n if (loginMethods.includes(\"username\")) {\n return \"username\";\n }\n if (loginMethods.includes(\"phone\")) {\n return \"tel\";\n }\n return \"username\";\n };\n\n const externalLoginMethods = props.realmConfig.authenticationMethods.filter(\n (method) => method.type !== \"CREDENTIALS\",\n );\n\n const showOrDivider = credentialsProvider && externalLoginMethods.length > 0;\n\n return (\n <Flex flex={1} justify={\"center\"} align={\"center\"}>\n <Stack gap={\"sm\"} w={360}>\n <Card withBorder p={\"lg\"} bg={\"var(--alepha-elevated)\"}>\n <Stack gap={\"md\"}>\n {/* Realm branding */}\n {(settings.logoUrl ||\n settings.displayName ||\n settings.description) && (\n <Stack gap={\"xs\"} align=\"center\" mb=\"xs\">\n {settings.logoUrl && (\n <Image\n src={settings.logoUrl}\n alt={settings.displayName || props.realmConfig.realmName}\n h={48}\n w=\"auto\"\n fit=\"contain\"\n />\n )}\n {settings.displayName && (\n <Title order={4} ta=\"center\">\n {settings.displayName}\n </Title>\n )}\n {settings.description && (\n <Text size=\"sm\" c=\"dimmed\" ta=\"center\">\n {settings.description}\n </Text>\n )}\n </Stack>\n )}\n\n {/* Credentials login form */}\n {credentialsProvider && (\n <>\n <form {...form.props}>\n <Stack flex={1} gap={\"md\"}>\n <Control\n title={identifierTitle}\n input={form.input.identifier}\n icon={IconUser}\n text={{\n autoComplete: getAutoCompleteType(),\n }}\n />\n <Control\n title={tr(\"loginPassword\")}\n input={form.input.password}\n icon={IconLock}\n password={{\n autoComplete: \"current-password\",\n }}\n />\n <ActionButton variant={\"filled\"} form={form}>\n {tr(\"loginSignIn\")}\n </ActionButton>\n </Stack>\n </form>\n {settings.resetPasswordAllowed && (\n <Text size=\"sm\" ta=\"center\">\n <ActionButton\n href={router.path(\"resetPassword\", {\n query: { realm: props.realmConfig.realmName },\n })}\n anchorProps={{ inherit: true }}\n >\n {tr(\"loginForgotPassword\")}\n </ActionButton>\n </Text>\n )}\n </>\n )}\n\n {/* OR divider - only when both credentials AND external methods exist */}\n {showOrDivider && (\n <Group align=\"center\" justify=\"center\" gap={\"md\"}>\n <Flex flex={1} h={\"1px\"} bg={\"var(--alepha-border)\"} />\n <Text size=\"xs\" c={\"dimmed\"}>\n {tr(\"loginOr\")}\n </Text>\n <Flex flex={1} h={\"1px\"} bg={\"var(--alepha-border)\"} />\n </Group>\n )}\n\n {/* External login methods */}\n {externalLoginMethods.length > 0 && (\n <Stack gap={\"sm\"}>\n {externalLoginMethods.map((method) => (\n <ActionButton\n variant={\"default\"}\n key={method.type}\n leftSection={leftSection(method.name.toLowerCase())}\n onClick={() =>\n auth.login(method.name, {\n redirect,\n realm: props.realmConfig.realmName,\n })\n }\n >\n {tr(\"loginContinueWith\", {\n args: [capitalize(method.name)],\n })}\n </ActionButton>\n ))}\n </Stack>\n )}\n\n {/* Registration link */}\n {settings.registrationAllowed && (\n <Text size=\"sm\" ta=\"center\">\n {tr(\"loginNoAccount\")}{\" \"}\n <ActionButton\n href={router.path(\"register\", {\n query: { realm: props.realmConfig.realmName },\n })}\n anchorProps={{ inherit: true }}\n >\n {tr(\"loginSignUp\")}\n </ActionButton>\n </Text>\n )}\n </Stack>\n </Card>\n <ActionButton variant={\"subtle\"} href={\"/\"}>\n {tr(\"loginCancel\")}\n </ActionButton>\n </Stack>\n </Flex>\n );\n};\n\nexport default Login;\n\nconst leftSection = (name: string) => {\n if (name === \"google\") {\n return <IconGoogle />;\n }\n\n if (name === \"github\") {\n return <IconGithub />;\n }\n};\n"],"mappings":"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"}
@@ -29,7 +29,10 @@ const Register = (props) => {
29
29
  const form = useForm({
30
30
  schema: useMemo(() => {
31
31
  const registerSchema = t.object({
32
- username: t.optional(t.text()),
32
+ username: t.optional(t.text({
33
+ trim: true,
34
+ pattern: settings.usernameRegExp
35
+ })),
33
36
  email: t.optional(t.email()),
34
37
  phoneNumber: t.optional(t.e164()),
35
38
  password: t.string({ minLength: 8 }),
@@ -359,4 +362,4 @@ const leftSection = (name) => {
359
362
 
360
363
  //#endregion
361
364
  export { Register_default as t };
362
- //# sourceMappingURL=Register-BKBIpHhW.js.map
365
+ //# sourceMappingURL=Register-CGlbQ50l.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Register-CGlbQ50l.js","names":["IconGoogle","IconGithub"],"sources":["../../src/auth/components/Register.tsx"],"sourcesContent":["import { useClient } from \"@alepha/react\";\nimport { useAuth } from \"@alepha/react/auth\";\nimport { useForm } from \"@alepha/react/form\";\nimport { useI18n } from \"@alepha/react/i18n\";\nimport { useRouter } from \"@alepha/react/router\";\nimport { ActionButton, Control, capitalize } from \"@alepha/ui\";\nimport {\n Alert,\n Card,\n Flex,\n Group,\n Image,\n PinInput,\n Stack,\n Text,\n Title,\n} from \"@mantine/core\";\nimport {\n IconAlertCircle,\n IconLock,\n IconMail,\n IconPhone,\n IconUser,\n} from \"@tabler/icons-react\";\nimport { TypeBoxError, t } from \"alepha\";\nimport type {\n RealmConfig,\n RegistrationIntentResponse,\n UserController,\n} from \"alepha/api/users\";\nimport { useMemo, useState } from \"react\";\nimport type { AuthI18n } from \"../AuthI18n.ts\";\nimport type { AuthRouter } from \"../AuthRouter.ts\";\nimport IconGithub from \"./icons/IconGithub.tsx\";\nimport IconGoogle from \"./icons/IconGoogle.tsx\";\n\nexport interface RegisterProps {\n realmConfig: RealmConfig;\n}\n\ntype RegistrationPhase = \"form\" | \"verification\";\n\ninterface RegistrationState {\n phase: RegistrationPhase;\n intent?: RegistrationIntentResponse;\n credentials?: {\n identifier: string;\n password: string;\n };\n}\n\nconst Register = (props: RegisterProps) => {\n const auth = useAuth();\n const userCtrl = useClient<UserController>();\n const router = useRouter<AuthRouter>();\n const { tr } = useI18n<AuthI18n, \"en\">();\n const redirect = router.query.r || \"/\";\n\n const [registrationState, setRegistrationState] = useState<RegistrationState>(\n {\n phase: \"form\",\n },\n );\n const [emailCode, setEmailCode] = useState(\"\");\n const [phoneCode, setPhoneCode] = useState(\"\");\n const [verificationError, setVerificationError] = useState<string | null>(\n null,\n );\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n const credentialsProvider = props.realmConfig.authenticationMethods.find(\n (it) => it.type === \"CREDENTIALS\",\n );\n\n const settings = props.realmConfig.settings || {};\n const isRegistrationAllowed = settings.registrationAllowed !== false;\n\n const registerSchema = useMemo(() => {\n const registerSchema = t.object({\n username: t.optional(\n t.text({\n trim: true,\n pattern: settings.usernameRegExp,\n }),\n ),\n email: t.optional(t.email()),\n phoneNumber: t.optional(t.e164()),\n password: t.string({ minLength: 8 }),\n confirmPassword: t.string({ minLength: 8 }),\n });\n\n const required = registerSchema.required as string[];\n\n if (settings.usernameRequired) required.push(\"username\");\n if (settings.emailRequired) required.push(\"email\");\n if (settings.phoneRequired) required.push(\"phoneNumber\");\n\n return registerSchema;\n }, []);\n\n const form = useForm({\n schema: registerSchema,\n handler: async (data) => {\n if (data.password !== data.confirmPassword) {\n throw new TypeBoxError({\n message: \"Passwords do not match\",\n instancePath: \"/confirmPassword\",\n keyword: \"not\",\n schemaPath: \"\",\n params: {},\n });\n }\n\n // Phase 1: Create registration intent\n const intent = await userCtrl.createRegistrationIntent({\n query: { userRealmName: props.realmConfig.realmName },\n body: {\n username: data.username,\n email: data.email,\n phoneNumber: data.phoneNumber,\n password: data.password,\n },\n });\n\n const identifier = data.username ?? data.email ?? data.phoneNumber;\n\n // Check if verification is needed\n if (\n intent.expectEmailVerification ||\n intent.expectPhoneVerification ||\n intent.expectCaptcha\n ) {\n // Move to verification phase\n setRegistrationState({\n phase: \"verification\",\n intent,\n credentials: identifier\n ? { identifier, password: data.password }\n : undefined,\n });\n return;\n }\n\n // No verification needed - complete registration immediately\n await userCtrl.createUserFromIntent({\n body: { intentId: intent.intentId },\n });\n\n // Auto-login after registration\n if (identifier && credentialsProvider) {\n await auth.login(credentialsProvider.name, {\n username: identifier,\n password: data.password,\n realm: props.realmConfig.realmName,\n });\n }\n\n await router.go(router.query.r || \"/\");\n },\n });\n\n const handleVerificationSubmit = async () => {\n if (!registrationState.intent) return;\n\n setIsSubmitting(true);\n setVerificationError(null);\n\n try {\n // Phase 2: Complete registration with verification codes\n await userCtrl.createUserFromIntent({\n body: {\n intentId: registrationState.intent.intentId,\n emailCode: registrationState.intent.expectEmailVerification\n ? emailCode\n : undefined,\n phoneCode: registrationState.intent.expectPhoneVerification\n ? phoneCode\n : undefined,\n },\n });\n\n // Auto-login after registration\n if (registrationState.credentials && credentialsProvider) {\n await auth.login(credentialsProvider.name, {\n username: registrationState.credentials.identifier,\n password: registrationState.credentials.password,\n realm: props.realmConfig.realmName,\n });\n }\n\n await router.go(router.query.r || \"/\");\n } catch (error) {\n setVerificationError(\n error instanceof Error ? error.message : \"Verification failed\",\n );\n } finally {\n setIsSubmitting(false);\n }\n };\n\n const canSubmitVerification = () => {\n if (!registrationState.intent) return false;\n\n if (\n registrationState.intent.expectEmailVerification &&\n emailCode.length !== 6\n ) {\n return false;\n }\n\n if (\n registrationState.intent.expectPhoneVerification &&\n phoneCode.length !== 6\n ) {\n return false;\n }\n\n return true;\n };\n\n // Verification phase UI\n if (registrationState.phase === \"verification\" && registrationState.intent) {\n return (\n <Flex flex={1} justify={\"center\"} align={\"center\"}>\n <Stack gap={\"sm\"} w={360}>\n <Card withBorder p={\"lg\"} bg={\"var(--alepha-elevated)\"}>\n <Stack gap={\"md\"}>\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"registerVerifyTitle\") ?? \"Verify your account\"}\n </Text>\n <Text size=\"sm\" c=\"dimmed\" ta=\"center\">\n {tr(\"registerVerifyDescription\") ??\n \"Please enter the verification code(s) sent to you.\"}\n </Text>\n\n {verificationError && (\n <Alert variant=\"light\" color=\"red\" icon={<IconAlertCircle />}>\n <Text size=\"sm\">{verificationError}</Text>\n </Alert>\n )}\n\n {registrationState.intent.expectEmailVerification && (\n <Stack gap={\"xs\"}>\n <Text size=\"sm\" fw={500}>\n {tr(\"registerEmailCode\")}\n </Text>\n <Flex justify=\"center\">\n <PinInput\n length={6}\n value={emailCode}\n onChange={setEmailCode}\n type=\"number\"\n oneTimeCode\n aria-label=\"Email verification code\"\n />\n </Flex>\n </Stack>\n )}\n\n {registrationState.intent.expectPhoneVerification && (\n <Stack gap={\"xs\"}>\n <Text size=\"sm\" fw={500}>\n {tr(\"registerPhoneCode\")}\n </Text>\n <Flex justify=\"center\">\n <PinInput\n length={6}\n value={phoneCode}\n onChange={setPhoneCode}\n type=\"number\"\n oneTimeCode\n aria-label=\"Phone verification code\"\n />\n </Flex>\n </Stack>\n )}\n\n <ActionButton\n color={\"blue\"}\n onClick={handleVerificationSubmit}\n loading={isSubmitting}\n disabled={!canSubmitVerification()}\n >\n {tr(\"registerVerifySubmit\")}\n </ActionButton>\n\n <ActionButton\n variant=\"subtle\"\n onClick={() =>\n setRegistrationState({ phase: \"form\", intent: undefined })\n }\n >\n {tr(\"registerVerifyBack\") ?? \"Back to registration\"}\n </ActionButton>\n </Stack>\n </Card>\n </Stack>\n </Flex>\n );\n }\n\n // External login methods\n const externalMethods = props.realmConfig.authenticationMethods.filter(\n (method) => method.type !== \"CREDENTIALS\",\n );\n\n const showOrDivider = credentialsProvider && externalMethods.length > 0;\n\n // Registration form phase UI\n return (\n <Flex flex={1} justify={\"center\"} align={\"center\"}>\n <Stack gap={\"sm\"} w={360}>\n <Card withBorder p={\"lg\"} bg={\"var(--alepha-elevated)\"}>\n <Stack gap={\"md\"}>\n {/* Realm branding */}\n {(settings.logoUrl ||\n settings.displayName ||\n settings.description) && (\n <Stack gap={\"xs\"} align=\"center\" mb=\"xs\">\n {settings.logoUrl && (\n <Image\n src={settings.logoUrl}\n alt={settings.displayName || props.realmConfig.realmName}\n h={48}\n w=\"auto\"\n fit=\"contain\"\n />\n )}\n {settings.displayName && (\n <Title order={4} ta=\"center\">\n {settings.displayName}\n </Title>\n )}\n {settings.description && (\n <Text size=\"sm\" c=\"dimmed\" ta=\"center\">\n {settings.description}\n </Text>\n )}\n </Stack>\n )}\n\n {!isRegistrationAllowed ? (\n <>\n <Alert\n variant=\"light\"\n color=\"yellow\"\n icon={<IconAlertCircle />}\n >\n <Text size=\"sm\">{tr(\"registerDisabled\")}</Text>\n </Alert>\n <ActionButton\n href={router.path(\"login\", {\n query: { realm: props.realmConfig.realmName },\n })}\n >\n {tr(\"registerBackToSignIn\")}\n </ActionButton>\n </>\n ) : (\n <>\n {/* Credentials registration form */}\n {credentialsProvider && (\n <form {...form.props}>\n <Stack flex={1} gap={\"md\"}>\n {settings.usernameEnabled !== false &&\n form.input.username && (\n <Control\n title={tr(\"registerUsername\")}\n input={form.input.username}\n icon={<IconUser />}\n text={{\n autoComplete: \"username\",\n }}\n />\n )}\n {settings.emailEnabled !== false && form.input.email && (\n <Control\n title={tr(\"registerEmail\")}\n input={form.input.email}\n icon={<IconMail />}\n text={{\n autoComplete: \"email\",\n }}\n />\n )}\n {settings.phoneEnabled === true &&\n form.input.phoneNumber && (\n <Control\n title={tr(\"registerPhone\")}\n input={form.input.phoneNumber}\n icon={<IconPhone />}\n text={{\n autoComplete: \"tel\",\n }}\n />\n )}\n <Control\n title={tr(\"registerPassword\")}\n input={form.input.password}\n icon={<IconLock />}\n password={{\n autoComplete: \"new-password\",\n }}\n />\n <Control\n title={tr(\"registerConfirmPassword\")}\n input={form.input.confirmPassword}\n icon={<IconLock />}\n password={{\n autoComplete: \"new-password\",\n }}\n />\n <ActionButton\n form={form}\n color={\"blue\"}\n variant={\"filled\"}\n >\n {tr(\"registerCreateAccount\")}\n </ActionButton>\n </Stack>\n </form>\n )}\n\n {/* OR divider - only when both credentials AND external methods exist */}\n {showOrDivider && (\n <Group align=\"center\" justify=\"center\" gap={\"md\"}>\n <Flex flex={1} h={\"1px\"} bg={\"var(--alepha-border)\"} />\n <Text size=\"xs\" c=\"dimmed\">\n {tr(\"registerOr\")}\n </Text>\n <Flex flex={1} h={\"1px\"} bg={\"var(--alepha-border)\"} />\n </Group>\n )}\n\n {/* External login methods */}\n {externalMethods.length > 0 && (\n <Stack gap={\"sm\"}>\n {externalMethods.map((method) => (\n <ActionButton\n variant={\"default\"}\n key={method.type}\n leftSection={leftSection(method.name.toLowerCase())}\n onClick={() =>\n auth.login(method.name, {\n redirect,\n realm: props.realmConfig.realmName,\n })\n }\n >\n {tr(\"registerContinueWith\", {\n args: [capitalize(method.name)],\n })}\n </ActionButton>\n ))}\n </Stack>\n )}\n\n {/* Sign in link */}\n <Text size=\"sm\" ta=\"center\">\n {tr(\"registerHaveAccount\")}{\" \"}\n <ActionButton\n href={router.path(\"login\", {\n query: { realm: props.realmConfig.realmName },\n })}\n anchorProps={{ inherit: true }}\n >\n {tr(\"registerSignIn\")}\n </ActionButton>\n </Text>\n </>\n )}\n </Stack>\n </Card>\n <ActionButton variant={\"subtle\"} href={redirect}>\n {tr(\"registerCancel\")}\n </ActionButton>\n </Stack>\n </Flex>\n );\n};\n\nexport default Register;\n\nconst leftSection = (name: string) => {\n if (name === \"google\") {\n return <IconGoogle />;\n }\n\n if (name === \"github\") {\n return <IconGithub />;\n }\n};\n"],"mappings":";;;;;;;;;;;;;;AAmDA,MAAM,YAAY,UAAyB;CACzC,MAAM,OAAO,SAAS;CACtB,MAAM,WAAW,WAA2B;CAC5C,MAAM,SAAS,WAAuB;CACtC,MAAM,EAAE,OAAO,SAAyB;CACxC,MAAM,WAAW,OAAO,MAAM,KAAK;CAEnC,MAAM,CAAC,mBAAmB,wBAAwB,SAChD,EACE,OAAO,QACR,CACF;CACD,MAAM,CAAC,WAAW,gBAAgB,SAAS,GAAG;CAC9C,MAAM,CAAC,WAAW,gBAAgB,SAAS,GAAG;CAC9C,MAAM,CAAC,mBAAmB,wBAAwB,SAChD,KACD;CACD,MAAM,CAAC,cAAc,mBAAmB,SAAS,MAAM;CAEvD,MAAM,sBAAsB,MAAM,YAAY,sBAAsB,MACjE,OAAO,GAAG,SAAS,cACrB;CAED,MAAM,WAAW,MAAM,YAAY,YAAY,EAAE;CACjD,MAAM,wBAAwB,SAAS,wBAAwB;CAyB/D,MAAM,OAAO,QAAQ;EACnB,QAxBqB,cAAc;GACnC,MAAM,iBAAiB,EAAE,OAAO;IAC9B,UAAU,EAAE,SACV,EAAE,KAAK;KACL,MAAM;KACN,SAAS,SAAS;KACnB,CAAC,CACH;IACD,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC;IAC5B,aAAa,EAAE,SAAS,EAAE,MAAM,CAAC;IACjC,UAAU,EAAE,OAAO,EAAE,WAAW,GAAG,CAAC;IACpC,iBAAiB,EAAE,OAAO,EAAE,WAAW,GAAG,CAAC;IAC5C,CAAC;GAEF,MAAM,WAAW,eAAe;AAEhC,OAAI,SAAS,iBAAkB,UAAS,KAAK,WAAW;AACxD,OAAI,SAAS,cAAe,UAAS,KAAK,QAAQ;AAClD,OAAI,SAAS,cAAe,UAAS,KAAK,cAAc;AAExD,UAAO;KACN,EAAE,CAAC;EAIJ,SAAS,OAAO,SAAS;AACvB,OAAI,KAAK,aAAa,KAAK,gBACzB,OAAM,IAAI,aAAa;IACrB,SAAS;IACT,cAAc;IACd,SAAS;IACT,YAAY;IACZ,QAAQ,EAAE;IACX,CAAC;GAIJ,MAAM,SAAS,MAAM,SAAS,yBAAyB;IACrD,OAAO,EAAE,eAAe,MAAM,YAAY,WAAW;IACrD,MAAM;KACJ,UAAU,KAAK;KACf,OAAO,KAAK;KACZ,aAAa,KAAK;KAClB,UAAU,KAAK;KAChB;IACF,CAAC;GAEF,MAAM,aAAa,KAAK,YAAY,KAAK,SAAS,KAAK;AAGvD,OACE,OAAO,2BACP,OAAO,2BACP,OAAO,eACP;AAEA,yBAAqB;KACnB,OAAO;KACP;KACA,aAAa,aACT;MAAE;MAAY,UAAU,KAAK;MAAU,GACvC;KACL,CAAC;AACF;;AAIF,SAAM,SAAS,qBAAqB,EAClC,MAAM,EAAE,UAAU,OAAO,UAAU,EACpC,CAAC;AAGF,OAAI,cAAc,oBAChB,OAAM,KAAK,MAAM,oBAAoB,MAAM;IACzC,UAAU;IACV,UAAU,KAAK;IACf,OAAO,MAAM,YAAY;IAC1B,CAAC;AAGJ,SAAM,OAAO,GAAG,OAAO,MAAM,KAAK,IAAI;;EAEzC,CAAC;CAEF,MAAM,2BAA2B,YAAY;AAC3C,MAAI,CAAC,kBAAkB,OAAQ;AAE/B,kBAAgB,KAAK;AACrB,uBAAqB,KAAK;AAE1B,MAAI;AAEF,SAAM,SAAS,qBAAqB,EAClC,MAAM;IACJ,UAAU,kBAAkB,OAAO;IACnC,WAAW,kBAAkB,OAAO,0BAChC,YACA;IACJ,WAAW,kBAAkB,OAAO,0BAChC,YACA;IACL,EACF,CAAC;AAGF,OAAI,kBAAkB,eAAe,oBACnC,OAAM,KAAK,MAAM,oBAAoB,MAAM;IACzC,UAAU,kBAAkB,YAAY;IACxC,UAAU,kBAAkB,YAAY;IACxC,OAAO,MAAM,YAAY;IAC1B,CAAC;AAGJ,SAAM,OAAO,GAAG,OAAO,MAAM,KAAK,IAAI;WAC/B,OAAO;AACd,wBACE,iBAAiB,QAAQ,MAAM,UAAU,sBAC1C;YACO;AACR,mBAAgB,MAAM;;;CAI1B,MAAM,8BAA8B;AAClC,MAAI,CAAC,kBAAkB,OAAQ,QAAO;AAEtC,MACE,kBAAkB,OAAO,2BACzB,UAAU,WAAW,EAErB,QAAO;AAGT,MACE,kBAAkB,OAAO,2BACzB,UAAU,WAAW,EAErB,QAAO;AAGT,SAAO;;AAIT,KAAI,kBAAkB,UAAU,kBAAkB,kBAAkB,OAClE,QACE,oBAAC;EAAK,MAAM;EAAG,SAAS;EAAU,OAAO;YACvC,oBAAC;GAAM,KAAK;GAAM,GAAG;aACnB,oBAAC;IAAK;IAAW,GAAG;IAAM,IAAI;cAC5B,qBAAC;KAAM,KAAK;;MACV,oBAAC;OAAK,MAAK;OAAK,IAAI;OAAK,IAAG;iBACzB,GAAG,sBAAsB,IAAI;QACzB;MACP,oBAAC;OAAK,MAAK;OAAK,GAAE;OAAS,IAAG;iBAC3B,GAAG,4BAA4B,IAC9B;QACG;MAEN,qBACC,oBAAC;OAAM,SAAQ;OAAQ,OAAM;OAAM,MAAM,oBAAC,oBAAkB;iBAC1D,oBAAC;QAAK,MAAK;kBAAM;SAAyB;QACpC;MAGT,kBAAkB,OAAO,2BACxB,qBAAC;OAAM,KAAK;kBACV,oBAAC;QAAK,MAAK;QAAK,IAAI;kBACjB,GAAG,oBAAoB;SACnB,EACP,oBAAC;QAAK,SAAQ;kBACZ,oBAAC;SACC,QAAQ;SACR,OAAO;SACP,UAAU;SACV,MAAK;SACL;SACA,cAAW;UACX;SACG;QACD;MAGT,kBAAkB,OAAO,2BACxB,qBAAC;OAAM,KAAK;kBACV,oBAAC;QAAK,MAAK;QAAK,IAAI;kBACjB,GAAG,oBAAoB;SACnB,EACP,oBAAC;QAAK,SAAQ;kBACZ,oBAAC;SACC,QAAQ;SACR,OAAO;SACP,UAAU;SACV,MAAK;SACL;SACA,cAAW;UACX;SACG;QACD;MAGV,oBAAC;OACC,OAAO;OACP,SAAS;OACT,SAAS;OACT,UAAU,CAAC,uBAAuB;iBAEjC,GAAG,uBAAuB;QACd;MAEf,oBAAC;OACC,SAAQ;OACR,eACE,qBAAqB;QAAE,OAAO;QAAQ,QAAQ;QAAW,CAAC;iBAG3D,GAAG,qBAAqB,IAAI;QAChB;;MACT;KACH;IACD;GACH;CAKX,MAAM,kBAAkB,MAAM,YAAY,sBAAsB,QAC7D,WAAW,OAAO,SAAS,cAC7B;CAED,MAAM,gBAAgB,uBAAuB,gBAAgB,SAAS;AAGtE,QACE,oBAAC;EAAK,MAAM;EAAG,SAAS;EAAU,OAAO;YACvC,qBAAC;GAAM,KAAK;GAAM,GAAG;cACnB,oBAAC;IAAK;IAAW,GAAG;IAAM,IAAI;cAC5B,qBAAC;KAAM,KAAK;iBAER,SAAS,WACT,SAAS,eACT,SAAS,gBACT,qBAAC;MAAM,KAAK;MAAM,OAAM;MAAS,IAAG;;OACjC,SAAS,WACR,oBAAC;QACC,KAAK,SAAS;QACd,KAAK,SAAS,eAAe,MAAM,YAAY;QAC/C,GAAG;QACH,GAAE;QACF,KAAI;SACJ;OAEH,SAAS,eACR,oBAAC;QAAM,OAAO;QAAG,IAAG;kBACjB,SAAS;SACJ;OAET,SAAS,eACR,oBAAC;QAAK,MAAK;QAAK,GAAE;QAAS,IAAG;kBAC3B,SAAS;SACL;;OAEH,EAGT,CAAC,wBACA,4CACE,oBAAC;MACC,SAAQ;MACR,OAAM;MACN,MAAM,oBAAC,oBAAkB;gBAEzB,oBAAC;OAAK,MAAK;iBAAM,GAAG,mBAAmB;QAAQ;OACzC,EACR,oBAAC;MACC,MAAM,OAAO,KAAK,SAAS,EACzB,OAAO,EAAE,OAAO,MAAM,YAAY,WAAW,EAC9C,CAAC;gBAED,GAAG,uBAAuB;OACd,IACd,GAEH;MAEG,uBACC,oBAAC;OAAK,GAAI,KAAK;iBACb,qBAAC;QAAM,MAAM;QAAG,KAAK;;SAClB,SAAS,oBAAoB,SAC5B,KAAK,MAAM,YACT,oBAAC;UACC,OAAO,GAAG,mBAAmB;UAC7B,OAAO,KAAK,MAAM;UAClB,MAAM,oBAAC,aAAW;UAClB,MAAM,EACJ,cAAc,YACf;WACD;SAEL,SAAS,iBAAiB,SAAS,KAAK,MAAM,SAC7C,oBAAC;UACC,OAAO,GAAG,gBAAgB;UAC1B,OAAO,KAAK,MAAM;UAClB,MAAM,oBAAC,aAAW;UAClB,MAAM,EACJ,cAAc,SACf;WACD;SAEH,SAAS,iBAAiB,QACzB,KAAK,MAAM,eACT,oBAAC;UACC,OAAO,GAAG,gBAAgB;UAC1B,OAAO,KAAK,MAAM;UAClB,MAAM,oBAAC,cAAY;UACnB,MAAM,EACJ,cAAc,OACf;WACD;SAEN,oBAAC;UACC,OAAO,GAAG,mBAAmB;UAC7B,OAAO,KAAK,MAAM;UAClB,MAAM,oBAAC,aAAW;UAClB,UAAU,EACR,cAAc,gBACf;WACD;SACF,oBAAC;UACC,OAAO,GAAG,0BAA0B;UACpC,OAAO,KAAK,MAAM;UAClB,MAAM,oBAAC,aAAW;UAClB,UAAU,EACR,cAAc,gBACf;WACD;SACF,oBAAC;UACO;UACN,OAAO;UACP,SAAS;oBAER,GAAG,wBAAwB;WACf;;SACT;QACH;MAIR,iBACC,qBAAC;OAAM,OAAM;OAAS,SAAQ;OAAS,KAAK;;QAC1C,oBAAC;SAAK,MAAM;SAAG,GAAG;SAAO,IAAI;UAA0B;QACvD,oBAAC;SAAK,MAAK;SAAK,GAAE;mBACf,GAAG,aAAa;UACZ;QACP,oBAAC;SAAK,MAAM;SAAG,GAAG;SAAO,IAAI;UAA0B;;QACjD;MAIT,gBAAgB,SAAS,KACxB,oBAAC;OAAM,KAAK;iBACT,gBAAgB,KAAK,WACpB,oBAAC;QACC,SAAS;QAET,aAAa,YAAY,OAAO,KAAK,aAAa,CAAC;QACnD,eACE,KAAK,MAAM,OAAO,MAAM;SACtB;SACA,OAAO,MAAM,YAAY;SAC1B,CAAC;kBAGH,GAAG,wBAAwB,EAC1B,MAAM,CAAC,WAAW,OAAO,KAAK,CAAC,EAChC,CAAC;UAXG,OAAO,KAYC,CACf;QACI;MAIV,qBAAC;OAAK,MAAK;OAAK,IAAG;;QAChB,GAAG,sBAAsB;QAAE;QAC5B,oBAAC;SACC,MAAM,OAAO,KAAK,SAAS,EACzB,OAAO,EAAE,OAAO,MAAM,YAAY,WAAW,EAC9C,CAAC;SACF,aAAa,EAAE,SAAS,MAAM;mBAE7B,GAAG,iBAAiB;UACR;;QACV;SACN;MAEC;KACH,EACP,oBAAC;IAAa,SAAS;IAAU,MAAM;cACpC,GAAG,iBAAiB;KACR;IACT;GACH;;AAIX,uBAAe;AAEf,MAAM,eAAe,SAAiB;AACpC,KAAI,SAAS,SACX,QAAO,oBAACA,uBAAa;AAGvB,KAAI,SAAS,SACX,QAAO,oBAACC,uBAAa"}
@@ -0,0 +1,4 @@
1
+ import "./IconGoogle-Cm5d8J3f.js";
2
+ import { t as Register_default } from "./Register-CGlbQ50l.js";
3
+
4
+ export { Register_default as default };
@@ -1 +1 @@
1
- {"version":3,"file":"ResetPassword-DvqD_1SJ.js","names":[],"sources":["../../src/auth/components/ResetPassword.tsx"],"sourcesContent":["import { useClient } from \"@alepha/react\";\nimport { useForm } from \"@alepha/react/form\";\nimport { useI18n } from \"@alepha/react/i18n\";\nimport { useRouter } from \"@alepha/react/router\";\nimport { ActionButton, Control } from \"@alepha/ui\";\nimport {\n Alert,\n Card,\n Flex,\n Image,\n PinInput,\n Stack,\n Text,\n Title,\n} from \"@mantine/core\";\nimport {\n IconAlertCircle,\n IconCheck,\n IconInfoCircle,\n IconLock,\n IconMail,\n} from \"@tabler/icons-react\";\nimport { AlephaError, t } from \"alepha\";\nimport type {\n PasswordResetIntentResponse,\n UserController,\n UserRealmConfig,\n} from \"alepha/api/users\";\nimport { resetPasswordRequestSchema } from \"alepha/api/users\";\nimport { useState } from \"react\";\nimport type { AuthI18n } from \"../AuthI18n.ts\";\nimport type { AuthRouter } from \"../AuthRouter.ts\";\n\nexport interface ResetPasswordProps {\n realmConfig: UserRealmConfig;\n}\n\ntype Step = \"email\" | \"code\" | \"password\" | \"success\";\n\ninterface ResetState {\n step: Step;\n intent?: PasswordResetIntentResponse;\n email?: string;\n code?: string;\n}\n\nconst ResetPassword = (props: ResetPasswordProps) => {\n const router = useRouter<AuthRouter>();\n const userCtrl = useClient<UserController>();\n const { tr } = useI18n<AuthI18n, \"en\">();\n const [resetState, setResetState] = useState<ResetState>({ step: \"email\" });\n const [error, setError] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const redirect = router.query.r || \"/\";\n\n const settings = props.realmConfig.settings;\n const isResetPasswordAllowed = settings?.resetPasswordAllowed !== false;\n\n // Phase 1: Request password reset intent\n const emailForm = useForm({\n schema: resetPasswordRequestSchema,\n handler: async (data) => {\n setError(null);\n const intent = await userCtrl.createPasswordResetIntent({\n query: { userRealmName: props.realmConfig.realmName },\n body: { email: data.email },\n });\n\n setResetState({\n step: \"code\",\n intent,\n email: data.email,\n });\n },\n });\n\n // Phase 2: Complete password reset\n const passwordForm = useForm(\n {\n schema: t.object({\n password: t.string({ minLength: 8 }),\n confirmPassword: t.string({ minLength: 8 }),\n }),\n handler: async (data) => {\n if (data.password !== data.confirmPassword) {\n throw new AlephaError(\"Passwords do not match\");\n }\n\n if (!resetState.intent || !resetState.code) {\n throw new AlephaError(\"Invalid reset state\");\n }\n\n await userCtrl.completePasswordReset({\n body: {\n intentId: resetState.intent.intentId,\n code: resetState.code,\n newPassword: data.password,\n },\n });\n\n setResetState({ step: \"success\" });\n },\n },\n [resetState.intent, resetState.code],\n );\n\n const handleCodeComplete = (value: string) => {\n if (value.length === 6) {\n setResetState((prev) => ({\n ...prev,\n step: \"password\",\n code: value,\n }));\n }\n };\n\n const handleResendCode = async () => {\n if (!resetState.email) return;\n\n setIsSubmitting(true);\n setError(null);\n\n try {\n const intent = await userCtrl.createPasswordResetIntent({\n query: { userRealmName: props.realmConfig.realmName },\n body: { email: resetState.email },\n });\n\n setResetState((prev) => ({\n ...prev,\n intent,\n }));\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to resend code\");\n } finally {\n setIsSubmitting(false);\n }\n };\n\n return (\n <Flex flex={1} justify={\"center\"} align={\"center\"}>\n <Stack gap={\"sm\"} w={360}>\n <Card withBorder p={\"lg\"} bg={\"var(--alepha-elevated)\"}>\n <Stack gap={\"md\"}>\n {/* Realm branding */}\n {(settings.logoUrl ||\n settings.displayName ||\n settings.description) && (\n <Stack gap={\"xs\"} align=\"center\" mb=\"xs\">\n {settings.logoUrl && (\n <Image\n src={settings.logoUrl}\n alt={settings.displayName || props.realmConfig.realmName}\n h={48}\n w=\"auto\"\n fit=\"contain\"\n />\n )}\n {settings.displayName && (\n <Title order={4} ta=\"center\">\n {settings.displayName}\n </Title>\n )}\n {settings.description && (\n <Text size=\"sm\" c=\"dimmed\" ta=\"center\">\n {settings.description}\n </Text>\n )}\n </Stack>\n )}\n\n {error && (\n <Alert variant=\"light\" color=\"red\" icon={<IconAlertCircle />}>\n <Text size=\"sm\">{error}</Text>\n </Alert>\n )}\n\n {!isResetPasswordAllowed ? (\n <>\n <Alert\n variant=\"light\"\n color=\"yellow\"\n icon={<IconAlertCircle />}\n >\n <Text size=\"sm\">{tr(\"resetPasswordDisabled\")}</Text>\n </Alert>\n <ActionButton\n href={router.path(\"login\", {\n query: { realm: props.realmConfig.realmName },\n })}\n >\n {tr(\"resetPasswordBackToSignIn\")}\n </ActionButton>\n </>\n ) : resetState.step === \"email\" ? (\n <form {...emailForm.props}>\n <Stack flex={1} gap={\"md\"}>\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"resetPasswordTitle\")}\n </Text>\n <Text size=\"sm\" c=\"dimmed\">\n {tr(\"resetPasswordEnterEmail\")}\n </Text>\n <Control\n title={tr(\"resetPasswordEmail\")}\n input={emailForm.input.email}\n icon={<IconMail />}\n text={{\n autoComplete: \"email\",\n autoFocus: true,\n disabled: !isResetPasswordAllowed,\n }}\n />\n <ActionButton\n form={emailForm}\n disabled={!isResetPasswordAllowed}\n >\n {tr(\"resetPasswordSendCode\")}\n </ActionButton>\n </Stack>\n </form>\n ) : resetState.step === \"code\" ? (\n <Stack gap={\"md\"}>\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"resetPasswordTitle\")}\n </Text>\n <Alert variant=\"light\" color=\"blue\" icon={<IconInfoCircle />}>\n <Text size=\"sm\">{tr(\"resetPasswordCodeSent\")}</Text>\n </Alert>\n <Text size=\"sm\" c=\"dimmed\" ta=\"center\">\n {tr(\"resetPasswordEnterCode\")}\n </Text>\n <Flex justify=\"center\">\n <PinInput\n length={6}\n type=\"number\"\n autoFocus\n oneTimeCode\n onComplete={handleCodeComplete}\n aria-label=\"Password reset verification code\"\n />\n </Flex>\n <ActionButton\n variant=\"subtle\"\n onClick={handleResendCode}\n loading={isSubmitting}\n >\n {tr(\"resetPasswordResendCode\")}\n </ActionButton>\n </Stack>\n ) : resetState.step === \"password\" ? (\n <form {...passwordForm.props}>\n <Stack flex={1} gap={\"md\"}>\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"resetPasswordTitle\")}\n </Text>\n <Text size=\"sm\" c=\"dimmed\">\n {tr(\"resetPasswordEnterNewPassword\")}\n </Text>\n <Control\n title={tr(\"resetPasswordNewPassword\")}\n input={passwordForm.input.password}\n icon={<IconLock />}\n password={{\n autoComplete: \"new-password\",\n autoFocus: true,\n }}\n />\n <Control\n title={tr(\"resetPasswordConfirmPassword\")}\n input={passwordForm.input.confirmPassword}\n icon={<IconLock />}\n password={{\n autoComplete: \"new-password\",\n }}\n />\n <ActionButton form={passwordForm}>\n {tr(\"resetPasswordSetNewPassword\")}\n </ActionButton>\n </Stack>\n </form>\n ) : (\n <>\n <Alert variant=\"light\" color=\"green\" icon={<IconCheck />}>\n <Text size=\"sm\">{tr(\"resetPasswordSuccess\")}</Text>\n </Alert>\n <ActionButton\n href={router.path(\"login\", {\n query: { realm: props.realmConfig.realmName },\n })}\n >\n {tr(\"resetPasswordBackToSignIn\")}\n </ActionButton>\n </>\n )}\n </Stack>\n </Card>\n <ActionButton variant={\"subtle\"} href={redirect}>\n {tr(\"resetPasswordCancel\")}\n </ActionButton>\n </Stack>\n </Flex>\n );\n};\n\nexport default ResetPassword;\n"],"mappings":"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"}
1
+ {"version":3,"file":"ResetPassword-DvqD_1SJ.js","names":[],"sources":["../../src/auth/components/ResetPassword.tsx"],"sourcesContent":["import { useClient } from \"@alepha/react\";\nimport { useForm } from \"@alepha/react/form\";\nimport { useI18n } from \"@alepha/react/i18n\";\nimport { useRouter } from \"@alepha/react/router\";\nimport { ActionButton, Control } from \"@alepha/ui\";\nimport {\n Alert,\n Card,\n Flex,\n Image,\n PinInput,\n Stack,\n Text,\n Title,\n} from \"@mantine/core\";\nimport {\n IconAlertCircle,\n IconCheck,\n IconInfoCircle,\n IconLock,\n IconMail,\n} from \"@tabler/icons-react\";\nimport { AlephaError, t } from \"alepha\";\nimport type {\n PasswordResetIntentResponse,\n RealmConfig,\n UserController,\n} from \"alepha/api/users\";\nimport { resetPasswordRequestSchema } from \"alepha/api/users\";\nimport { useState } from \"react\";\nimport type { AuthI18n } from \"../AuthI18n.ts\";\nimport type { AuthRouter } from \"../AuthRouter.ts\";\n\nexport interface ResetPasswordProps {\n realmConfig: RealmConfig;\n}\n\ntype Step = \"email\" | \"code\" | \"password\" | \"success\";\n\ninterface ResetState {\n step: Step;\n intent?: PasswordResetIntentResponse;\n email?: string;\n code?: string;\n}\n\nconst ResetPassword = (props: ResetPasswordProps) => {\n const router = useRouter<AuthRouter>();\n const userCtrl = useClient<UserController>();\n const { tr } = useI18n<AuthI18n, \"en\">();\n const [resetState, setResetState] = useState<ResetState>({ step: \"email\" });\n const [error, setError] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const redirect = router.query.r || \"/\";\n\n const settings = props.realmConfig.settings;\n const isResetPasswordAllowed = settings?.resetPasswordAllowed !== false;\n\n // Phase 1: Request password reset intent\n const emailForm = useForm({\n schema: resetPasswordRequestSchema,\n handler: async (data) => {\n setError(null);\n const intent = await userCtrl.createPasswordResetIntent({\n query: { userRealmName: props.realmConfig.realmName },\n body: { email: data.email },\n });\n\n setResetState({\n step: \"code\",\n intent,\n email: data.email,\n });\n },\n });\n\n // Phase 2: Complete password reset\n const passwordForm = useForm(\n {\n schema: t.object({\n password: t.string({ minLength: 8 }),\n confirmPassword: t.string({ minLength: 8 }),\n }),\n handler: async (data) => {\n if (data.password !== data.confirmPassword) {\n throw new AlephaError(\"Passwords do not match\");\n }\n\n if (!resetState.intent || !resetState.code) {\n throw new AlephaError(\"Invalid reset state\");\n }\n\n await userCtrl.completePasswordReset({\n body: {\n intentId: resetState.intent.intentId,\n code: resetState.code,\n newPassword: data.password,\n },\n });\n\n setResetState({ step: \"success\" });\n },\n },\n [resetState.intent, resetState.code],\n );\n\n const handleCodeComplete = (value: string) => {\n if (value.length === 6) {\n setResetState((prev) => ({\n ...prev,\n step: \"password\",\n code: value,\n }));\n }\n };\n\n const handleResendCode = async () => {\n if (!resetState.email) return;\n\n setIsSubmitting(true);\n setError(null);\n\n try {\n const intent = await userCtrl.createPasswordResetIntent({\n query: { userRealmName: props.realmConfig.realmName },\n body: { email: resetState.email },\n });\n\n setResetState((prev) => ({\n ...prev,\n intent,\n }));\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to resend code\");\n } finally {\n setIsSubmitting(false);\n }\n };\n\n return (\n <Flex flex={1} justify={\"center\"} align={\"center\"}>\n <Stack gap={\"sm\"} w={360}>\n <Card withBorder p={\"lg\"} bg={\"var(--alepha-elevated)\"}>\n <Stack gap={\"md\"}>\n {/* Realm branding */}\n {(settings.logoUrl ||\n settings.displayName ||\n settings.description) && (\n <Stack gap={\"xs\"} align=\"center\" mb=\"xs\">\n {settings.logoUrl && (\n <Image\n src={settings.logoUrl}\n alt={settings.displayName || props.realmConfig.realmName}\n h={48}\n w=\"auto\"\n fit=\"contain\"\n />\n )}\n {settings.displayName && (\n <Title order={4} ta=\"center\">\n {settings.displayName}\n </Title>\n )}\n {settings.description && (\n <Text size=\"sm\" c=\"dimmed\" ta=\"center\">\n {settings.description}\n </Text>\n )}\n </Stack>\n )}\n\n {error && (\n <Alert variant=\"light\" color=\"red\" icon={<IconAlertCircle />}>\n <Text size=\"sm\">{error}</Text>\n </Alert>\n )}\n\n {!isResetPasswordAllowed ? (\n <>\n <Alert\n variant=\"light\"\n color=\"yellow\"\n icon={<IconAlertCircle />}\n >\n <Text size=\"sm\">{tr(\"resetPasswordDisabled\")}</Text>\n </Alert>\n <ActionButton\n href={router.path(\"login\", {\n query: { realm: props.realmConfig.realmName },\n })}\n >\n {tr(\"resetPasswordBackToSignIn\")}\n </ActionButton>\n </>\n ) : resetState.step === \"email\" ? (\n <form {...emailForm.props}>\n <Stack flex={1} gap={\"md\"}>\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"resetPasswordTitle\")}\n </Text>\n <Text size=\"sm\" c=\"dimmed\">\n {tr(\"resetPasswordEnterEmail\")}\n </Text>\n <Control\n title={tr(\"resetPasswordEmail\")}\n input={emailForm.input.email}\n icon={<IconMail />}\n text={{\n autoComplete: \"email\",\n autoFocus: true,\n disabled: !isResetPasswordAllowed,\n }}\n />\n <ActionButton\n form={emailForm}\n disabled={!isResetPasswordAllowed}\n >\n {tr(\"resetPasswordSendCode\")}\n </ActionButton>\n </Stack>\n </form>\n ) : resetState.step === \"code\" ? (\n <Stack gap={\"md\"}>\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"resetPasswordTitle\")}\n </Text>\n <Alert variant=\"light\" color=\"blue\" icon={<IconInfoCircle />}>\n <Text size=\"sm\">{tr(\"resetPasswordCodeSent\")}</Text>\n </Alert>\n <Text size=\"sm\" c=\"dimmed\" ta=\"center\">\n {tr(\"resetPasswordEnterCode\")}\n </Text>\n <Flex justify=\"center\">\n <PinInput\n length={6}\n type=\"number\"\n autoFocus\n oneTimeCode\n onComplete={handleCodeComplete}\n aria-label=\"Password reset verification code\"\n />\n </Flex>\n <ActionButton\n variant=\"subtle\"\n onClick={handleResendCode}\n loading={isSubmitting}\n >\n {tr(\"resetPasswordResendCode\")}\n </ActionButton>\n </Stack>\n ) : resetState.step === \"password\" ? (\n <form {...passwordForm.props}>\n <Stack flex={1} gap={\"md\"}>\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"resetPasswordTitle\")}\n </Text>\n <Text size=\"sm\" c=\"dimmed\">\n {tr(\"resetPasswordEnterNewPassword\")}\n </Text>\n <Control\n title={tr(\"resetPasswordNewPassword\")}\n input={passwordForm.input.password}\n icon={<IconLock />}\n password={{\n autoComplete: \"new-password\",\n autoFocus: true,\n }}\n />\n <Control\n title={tr(\"resetPasswordConfirmPassword\")}\n input={passwordForm.input.confirmPassword}\n icon={<IconLock />}\n password={{\n autoComplete: \"new-password\",\n }}\n />\n <ActionButton form={passwordForm}>\n {tr(\"resetPasswordSetNewPassword\")}\n </ActionButton>\n </Stack>\n </form>\n ) : (\n <>\n <Alert variant=\"light\" color=\"green\" icon={<IconCheck />}>\n <Text size=\"sm\">{tr(\"resetPasswordSuccess\")}</Text>\n </Alert>\n <ActionButton\n href={router.path(\"login\", {\n query: { realm: props.realmConfig.realmName },\n })}\n >\n {tr(\"resetPasswordBackToSignIn\")}\n </ActionButton>\n </>\n )}\n </Stack>\n </Card>\n <ActionButton variant={\"subtle\"} href={redirect}>\n {tr(\"resetPasswordCancel\")}\n </ActionButton>\n </Stack>\n </Flex>\n );\n};\n\nexport default ResetPassword;\n"],"mappings":"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"}
@@ -5,11 +5,11 @@ import * as _alepha_react_router0 from "@alepha/react/router";
5
5
  import * as alepha_server_links0 from "alepha/server/links";
6
6
  import * as react_jsx_runtime0 from "react/jsx-runtime";
7
7
  import { ReactNode } from "react";
8
- import { UserRealmConfig, UserRealmController } from "alepha/api/users";
8
+ import { RealmConfig, RealmController } from "alepha/api/users";
9
9
 
10
10
  //#region ../../src/auth/AuthRouter.d.ts
11
11
  declare class AuthRouter {
12
- protected readonly userRealmClient: alepha_server_links0.HttpVirtualClient<UserRealmController>;
12
+ protected readonly realmClient: alepha_server_links0.HttpVirtualClient<RealmController>;
13
13
  protected readonly auth: ReactAuth;
14
14
  layout: _alepha_react_router0.PagePrimitive<_alepha_react_router0.PageConfigSchema, any, _alepha_react_router0.TPropsParentDefault>;
15
15
  login: _alepha_react_router0.PagePrimitive<{
@@ -19,6 +19,7 @@ declare class AuthRouter {
19
19
  }>;
20
20
  }, {
21
21
  realmConfig: {
22
+ realmName: string;
22
23
  settings: {
23
24
  description?: string | undefined;
24
25
  displayName?: string | undefined;
@@ -28,6 +29,7 @@ declare class AuthRouter {
28
29
  emailRequired: boolean;
29
30
  usernameEnabled: boolean;
30
31
  usernameRequired: boolean;
32
+ usernameRegExp: string;
31
33
  phoneEnabled: boolean;
32
34
  phoneRequired: boolean;
33
35
  verifyEmailRequired: boolean;
@@ -43,7 +45,6 @@ declare class AuthRouter {
43
45
  requireSpecialCharacters: boolean;
44
46
  };
45
47
  };
46
- realmName: string;
47
48
  authenticationMethods: {
48
49
  type: "OAUTH2" | "OIDC" | "CREDENTIALS";
49
50
  name: string;
@@ -57,6 +58,7 @@ declare class AuthRouter {
57
58
  }>;
58
59
  }, {
59
60
  realmConfig: {
61
+ realmName: string;
60
62
  settings: {
61
63
  description?: string | undefined;
62
64
  displayName?: string | undefined;
@@ -66,6 +68,7 @@ declare class AuthRouter {
66
68
  emailRequired: boolean;
67
69
  usernameEnabled: boolean;
68
70
  usernameRequired: boolean;
71
+ usernameRegExp: string;
69
72
  phoneEnabled: boolean;
70
73
  phoneRequired: boolean;
71
74
  verifyEmailRequired: boolean;
@@ -81,7 +84,6 @@ declare class AuthRouter {
81
84
  requireSpecialCharacters: boolean;
82
85
  };
83
86
  };
84
- realmName: string;
85
87
  authenticationMethods: {
86
88
  type: "OAUTH2" | "OIDC" | "CREDENTIALS";
87
89
  name: string;
@@ -95,6 +97,7 @@ declare class AuthRouter {
95
97
  }>;
96
98
  }, {
97
99
  realmConfig: {
100
+ realmName: string;
98
101
  settings: {
99
102
  description?: string | undefined;
100
103
  displayName?: string | undefined;
@@ -104,6 +107,7 @@ declare class AuthRouter {
104
107
  emailRequired: boolean;
105
108
  usernameEnabled: boolean;
106
109
  usernameRequired: boolean;
110
+ usernameRegExp: string;
107
111
  phoneEnabled: boolean;
108
112
  phoneRequired: boolean;
109
113
  verifyEmailRequired: boolean;
@@ -119,7 +123,6 @@ declare class AuthRouter {
119
123
  requireSpecialCharacters: boolean;
120
124
  };
121
125
  };
122
- realmName: string;
123
126
  authenticationMethods: {
124
127
  type: "OAUTH2" | "OIDC" | "CREDENTIALS";
125
128
  name: string;
@@ -133,7 +136,8 @@ declare class AuthRouter {
133
136
  }>;
134
137
  }, any, _alepha_react_router0.TPropsParentDefault>;
135
138
  logout: _alepha_react_router0.PagePrimitive<_alepha_react_router0.PageConfigSchema, {}, _alepha_react_router0.TPropsParentDefault>;
136
- protected loadRealmConfig(userRealmName?: string): Promise<{
139
+ protected loadRealmConfig(realmName?: string): Promise<{
140
+ realmName: string;
137
141
  settings: {
138
142
  description?: string | undefined;
139
143
  displayName?: string | undefined;
@@ -143,6 +147,7 @@ declare class AuthRouter {
143
147
  emailRequired: boolean;
144
148
  usernameEnabled: boolean;
145
149
  usernameRequired: boolean;
150
+ usernameRegExp: string;
146
151
  phoneEnabled: boolean;
147
152
  phoneRequired: boolean;
148
153
  verifyEmailRequired: boolean;
@@ -158,7 +163,6 @@ declare class AuthRouter {
158
163
  requireSpecialCharacters: boolean;
159
164
  };
160
165
  };
161
- realmName: string;
162
166
  authenticationMethods: {
163
167
  type: "OAUTH2" | "OIDC" | "CREDENTIALS";
164
168
  name: string;
@@ -169,43 +173,43 @@ declare class AuthRouter {
169
173
  //#region ../../src/auth/components/buttons/UserButton.d.ts
170
174
  interface UserButtonProps extends Omit<ActionProps, "menu" | "icon" | "onClick"> {
171
175
  /**
172
- * Additional menu items to display before the logout option
173
- */
176
+ * Additional menu items to display before the logout option
177
+ */
174
178
  menuItems?: ActionMenuItem[];
175
179
  /**
176
- * Custom logout label (default: "Sign out")
177
- */
180
+ * Custom logout label (default: "Sign out")
181
+ */
178
182
  logoutLabel?: string;
179
183
  /**
180
- * Menu configuration overrides
181
- */
184
+ * Menu configuration overrides
185
+ */
182
186
  menuConfig?: Partial<Omit<ActionMenuConfig, "items">>;
183
187
  /**
184
- * Whether to show a divider before logout (default: true when menuItems provided)
185
- */
188
+ * Whether to show a divider before logout (default: true when menuItems provided)
189
+ */
186
190
  showLogoutDivider?: boolean;
187
191
  /**
188
- * Custom icon to use instead of user avatar (default: IconUser)
189
- */
192
+ * Custom icon to use instead of user avatar (default: IconUser)
193
+ */
190
194
  icon?: ReactNode;
191
195
  }
192
196
  declare const UserButton: (props: UserButtonProps) => react_jsx_runtime0.JSX.Element;
193
197
  //#endregion
194
198
  //#region ../../src/auth/components/Login.d.ts
195
199
  interface LoginProps {
196
- realmConfig: UserRealmConfig;
200
+ realmConfig: RealmConfig;
197
201
  }
198
202
  declare const Login: (props: LoginProps) => react_jsx_runtime0.JSX.Element;
199
203
  //#endregion
200
204
  //#region ../../src/auth/components/Register.d.ts
201
205
  interface RegisterProps {
202
- realmConfig: UserRealmConfig;
206
+ realmConfig: RealmConfig;
203
207
  }
204
208
  declare const Register: (props: RegisterProps) => react_jsx_runtime0.JSX.Element;
205
209
  //#endregion
206
210
  //#region ../../src/auth/components/ResetPassword.d.ts
207
211
  interface ResetPasswordProps {
208
- realmConfig: UserRealmConfig;
212
+ realmConfig: RealmConfig;
209
213
  }
210
214
  declare const ResetPassword: (props: ResetPasswordProps) => react_jsx_runtime0.JSX.Element;
211
215
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/auth/AuthRouter.ts","../../src/auth/components/buttons/UserButton.tsx","../../src/auth/components/Login.tsx","../../src/auth/components/Register.tsx","../../src/auth/components/ResetPassword.tsx","../../src/auth/components/VerifyEmail.tsx","../../src/auth/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;cAuBa,UAAA;sCACuB,oBAAA,CAAA,kBAAA;2BACX;UAEjB,qBAAA,CAAA,cAFiB,qBAAA,CAEjB,gBAAA,OAAA,qBAAA,CAAA,mBAAA;+BAYD;;2BAZC,OAAA,CAAA,OAAA;;IAJK,CAAA,CAAA;EACuB,CAAA,EAAA;IAAA,WAAA,EAAA;MACX,QAAA,EAAA;QAAA,WAEjB,CAAA,EAAA,MAAA,GAAA,SAAA;QAAA,WAAA,CAAA,EAAA,MAAA,GAAA,SAAA;QAAA,OAAA,CAAA,EAAA,MAAA,GAAA,SAAA;QAAA,mBAAA,EAAA,OAAA;;;;;;qBAYD,EAAA,OAAA;QAAA,mBAAA,EAAA,OAAA;;;;;;mBAiBG,EAAA,MAAA;UAAA,gBAAA,EAAA,OAAA;;;;;;iBAiBK,MAAA;MAAA,qBAAA,EAAA;;;;;;kCAjBL,aAkCG,CAAA;IAAA,KAAA,iBAcL,CAAA;MAAA,CAAA,mBAAA,CAjED,OAAA,CAAA,OAAA,CAiEC;MAAA,KAAA,mBAAA,iBAAA;IAagD,CAAA,CAAA;EAAA,CAAA,EAAA;;;;QCvGvC,WACf,CAAA,EAAA,MAAA,GAAA,SAAA;QAAa,OAAA,CAAA,EAAA,MAAA,GAAA,SAAA;QAID,mBAAA,EAAA,OAAA;QAUc,YAAA,EAAA,OAAA;QAAL,aAAA,EAAA,OAAA;QAAR,eAAA,EAAA,OAAA;QAUN,gBAAA,EAAA,OAAA;QAxBC,YAAA,EAAA,OAAA;QAAI,aAAA,EAAA,OAAA;QA2BR,mBAAqB,EAAA,OAAA;;;;QC1BV,oBACF,EAAA,OAAe;QAmO7B,cAhOqB,EAAA;;;;UCgBQ,cACf,EAAA,OAAA;UAqbd,wBAvaqC,EAAA,OAAA;;;;MClBrB,qBAAkB,EAAA;QAa7B,IAiQL,EAAA,QAAA,GAjQ6B,MAAA,GAAA,aAAkB;;;;ECnCpC,CAAA,4CAAgB;EAItB,aAAA,wBL0DS,aK1D8B,CAAA;;2BLyCnC,OAAA,CAAA,OAAA;;IMhCG,CAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCNkEA;;+BAjBE,OAAA,CAAA,OAAA;;;;UA+BP,qBAAA,CAAA,cAdK,qBAAA,CAcL,gBAAA,MAAA,qBAAA,CAAA,mBAAA;qDAagD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UCvGvC,eAAA,SACP,KAAK;;;;cAID;;;;EDID,WAAA,CAAA,EAAU,MAAA;EACa;;;EACX,UAAA,CAAA,ECIV,ODFP,CCEe,IDFf,CCEoB,gBDFpB,EAAA,OAAA,CAAA,CAAA;EAAA;;;;;;;SCYC;;cAGH,UDHC,EAAA,CAAA,KAAA,ECGoB,eDHpB,EAAA,GCGmC,kBAAA,CAAA,GAAA,CAAA,ODHnC;;;UEvBU,UAAA;eACF;;cAGT,eAAgB,eAAU,kBAAA,CAAA,GAAA,CAAA;;;UCgBf,aAAA;eACF;;cAcT,kBAAmB,kBAAa,kBAAA,CAAA,GAAA,CAAA;;;UClBrB,kBAAA;eACF;;cAYT,uBAAwB,uBAAkB,kBAAA,CAAA,GAAA,CAAA;;;KCnCpC,gBAAA;cAIN,sBAAuB,qBAAgB,kBAAA,CAAA,GAAA,CAAA;;;;;;ALQ7C;;AACoC,cMAvB,YNAuB,EMAX,OAAA,CAAA,ONAW,CMGlC,OAAA,CAHuB,MAAA,CNAW"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/auth/AuthRouter.ts","../../src/auth/components/buttons/UserButton.tsx","../../src/auth/components/Login.tsx","../../src/auth/components/Register.tsx","../../src/auth/components/ResetPassword.tsx","../../src/auth/components/VerifyEmail.tsx","../../src/auth/index.ts"],"mappings":";;;;;;;;;;cAuBa,UAAA;EAAA,mBAAA,WAAA,EACmB,oBAAA,CAAA,iBAAA,CAAA,eAAA;EAAA,mBAAA,IAAA,EACP,SAAA;EAAA,MAAA,EAEjB,qBAAA,CAAA,aAAA,CAFiB,qBAAA,CAEjB,gBAAA,OAAA,qBAAA,CAAA,mBAAA;EAAA,KAAA,wBAYD,aAAA;IAAA,KAAA;2BAZC,OAAA,CAAA,OAAA;MAAA,KAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kCA6BE,aAAA;IAAA,KAAA;2BAjBH,OAAA,CAAA,OAAA;MAAA,KAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uCAkCQ,aAAA;IAAA,KAAA;2BAjBL,OAAA,CAAA,OAAA;MAAA,KAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCAkCG,aAAA;IAAA,KAAA;+BAjBE,OAAA,CAAA,OAAA;MAAA,KAAA;;;UA+BP,qBAAA,CAAA,aAAA,CAdK,qBAAA,CAcL,gBAAA,MAAA,qBAAA,CAAA,mBAAA;EAAA,UAAA,gBAAA,SAAA,YAa4C,OAAA;IAAA,SAAA;IAAA,QAAA;MAAA,WAAA;MAAA,WAAA;MAAA,OAAA;MAAA,mBAAA;MAAA,YAAA;MAAA,aAAA;MAAA,eAAA;MAAA,gBAAA;MAAA,cAAA;MAAA,YAAA;MAAA,aAAA;MAAA,mBAAA;MAAA,mBAAA;MAAA,wBAAA;MAAA,yBAAA;MAAA,oBAAA;MAAA,cAAA;QAAA,SAAA;QAAA,gBAAA;QAAA,gBAAA;QAAA,cAAA;QAAA,wBAAA;MAAA;IAAA;IAAA,qBAAA;MAAA,IAAA;MAAA,IAAA;IAAA;EAAA;AAAA;;;UCvGnC,eAAA,SACP,IAAA,CAAK,WAAA;EAAA;;;EAAA,SAAA,GAID,cAAA;EAAA;;;EAAA,WAAA;EAAA;;;EAAA,UAAA,GAUC,OAAA,CAAQ,IAAA,CAAK,gBAAA;EAAA;;;EAAA,iBAAA;EAAA;;;EAAA,IAAA,GAUnB,SAAA;AAAA;AAAA,cAGH,UAAA,GAAA,KAAA,EAAqB,eAAA,KAAe,kBAAA,CAAA,GAAA,CAAA,OAAA;;;UC1BzB,UAAA;EAAA,WAAA,EACF,WAAA;AAAA;AAAA,cAGT,KAAA,GAAA,KAAA,EAAgB,UAAA,KAAU,kBAAA,CAAA,GAAA,CAAA,OAAA;;;UCgBf,aAAA;EAAA,WAAA,EACF,WAAA;AAAA;AAAA,cAcT,QAAA,GAAA,KAAA,EAAmB,aAAA,KAAa,kBAAA,CAAA,GAAA,CAAA,OAAA;;;UClBrB,kBAAA;EAAA,WAAA,EACF,WAAA;AAAA;AAAA,cAYT,aAAA,GAAA,KAAA,EAAwB,kBAAA,KAAkB,kBAAA,CAAA,GAAA,CAAA,OAAA;;;KCnCpC,gBAAA;AAAA,cAIN,WAAA,GAAA,MAAA,EAAuB,gBAAA,KAAgB,kBAAA,CAAA,GAAA,CAAA,OAAA;;;;ACS7C;;;;cAAa,YAAA,EAAY,OAAA,CAAA,OAAA,CAGvB,OAAA,CAHuB,MAAA"}