@alepha/ui 0.18.1 → 0.18.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/{AdminApiKeys-C-6_Q-lH.js → AdminApiKeys-BJhIwfD6.js} +17 -38
- package/dist/admin/AdminApiKeys-BJhIwfD6.js.map +1 -0
- package/dist/admin/{AdminAudits-Bgbf04hO.js → AdminAudits-DzD_4cDt.js} +23 -19
- package/dist/admin/AdminAudits-DzD_4cDt.js.map +1 -0
- package/dist/admin/AdminDashboard-C92tIc6x.js +67 -0
- package/dist/admin/AdminDashboard-C92tIc6x.js.map +1 -0
- package/dist/admin/{AdminFiles-B9a7G3cY.js → AdminFiles-DLpfhBkf.js} +3 -7
- package/dist/admin/AdminFiles-DLpfhBkf.js.map +1 -0
- package/dist/admin/{AdminJobDashboard-DaTwf5OY.js → AdminJobDashboard-KIOkeMgE.js} +2 -2
- package/dist/admin/{AdminJobDashboard-DaTwf5OY.js.map → AdminJobDashboard-KIOkeMgE.js.map} +1 -1
- package/dist/admin/{AdminJobExecutions-B9cek5dl.js → AdminJobExecutions-D0Yo_PU0.js} +24 -36
- package/dist/admin/AdminJobExecutions-D0Yo_PU0.js.map +1 -0
- package/dist/admin/{AdminJobRegistry-DFgV3oqx.js → AdminJobRegistry-PFajqaGK.js} +10 -18
- package/dist/admin/AdminJobRegistry-PFajqaGK.js.map +1 -0
- package/dist/admin/AdminLayout-B1DXZHDn.js +61 -0
- package/dist/admin/AdminLayout-B1DXZHDn.js.map +1 -0
- package/dist/admin/{AdminParameters-DHw9ATgl.js → AdminParameters-BspPeqp_.js} +2 -2
- package/dist/admin/{AdminParameters-DHw9ATgl.js.map → AdminParameters-BspPeqp_.js.map} +1 -1
- package/dist/admin/{AdminSessions-BhGJPI3z.js → AdminSessions-BnH5CZQl.js} +48 -53
- package/dist/admin/AdminSessions-BnH5CZQl.js.map +1 -0
- package/dist/admin/{AdminUserLayout-BdC4Te8m.js → AdminUserLayout-DUbC6-BI.js} +2 -2
- package/dist/admin/{AdminUserLayout-BdC4Te8m.js.map → AdminUserLayout-DUbC6-BI.js.map} +1 -1
- package/dist/admin/{AdminUserProfile-DAt23fqY.js → AdminUserProfile-DuTUnjdG.js} +3 -3
- package/dist/admin/{AdminUserProfile-DAt23fqY.js.map → AdminUserProfile-DuTUnjdG.js.map} +1 -1
- package/dist/admin/{AdminUserSessions-1uzcx02z.js → AdminUserSessions-DvZdAGpL.js} +33 -35
- package/dist/admin/AdminUserSessions-DvZdAGpL.js.map +1 -0
- package/dist/admin/AdminUsers-CR9z0g_5.js +206 -0
- package/dist/admin/AdminUsers-CR9z0g_5.js.map +1 -0
- package/dist/admin/{AuthLayout-DFJvCvzw.js → AuthLayout-DsUfp9RG.js} +2 -2
- package/dist/admin/{AuthLayout-DFJvCvzw.js.map → AuthLayout-DsUfp9RG.js.map} +1 -1
- package/dist/admin/{IconGoogle-CSQLPYwX.js → IconGoogle-Ch1m3Uzl.js} +1 -1
- package/dist/admin/{IconGoogle-CSQLPYwX.js.map → IconGoogle-Ch1m3Uzl.js.map} +1 -1
- package/dist/admin/{Login-BGheURrg.js → Login-DHbYJKwg.js} +3 -3
- package/dist/{auth/Login-Denw_UGy.js.map → admin/Login-DHbYJKwg.js.map} +1 -1
- package/dist/{auth/Profile-BMX_Ar_s.js → admin/Profile-B2EcIDB9.js} +2 -2
- package/dist/{auth/Profile-BMX_Ar_s.js.map → admin/Profile-B2EcIDB9.js.map} +1 -1
- package/dist/admin/{Register-Cs10l8vX.js → Register-Z3fxRbUF.js} +3 -3
- package/dist/{demo/Register-a70LPgs2.js.map → admin/Register-Z3fxRbUF.js.map} +1 -1
- package/dist/admin/{ResetPassword-BwDdfkGH.js → ResetPassword-_Y1qTTKh.js} +2 -2
- package/dist/admin/{ResetPassword-BwDdfkGH.js.map → ResetPassword-_Y1qTTKh.js.map} +1 -1
- package/dist/admin/{VerifyEmail-DfXHAiQl.js → VerifyEmail-Bg22bwcC.js} +2 -2
- package/dist/admin/{VerifyEmail-DfXHAiQl.js.map → VerifyEmail-Bg22bwcC.js.map} +1 -1
- package/dist/admin/{core-2xoLiT0o.js → core-BVO_TQxb.js} +1474 -233
- package/dist/admin/core-BVO_TQxb.js.map +1 -0
- package/dist/admin/index.d.ts +29 -4
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +448 -69
- package/dist/admin/index.js.map +1 -1
- package/dist/auth/{AuthLayout-CAE1pX9s.js → AuthLayout-C161NeF6.js} +2 -2
- package/dist/auth/{AuthLayout-CAE1pX9s.js.map → AuthLayout-C161NeF6.js.map} +1 -1
- package/dist/auth/{Login-Denw_UGy.js → Login-C7jIqf00.js} +2 -2
- package/dist/{admin/Login-BGheURrg.js.map → auth/Login-C7jIqf00.js.map} +1 -1
- package/dist/{admin/Profile-B-c9pCPf.js → auth/Profile-BMpXJ0oi.js} +2 -2
- package/dist/{demo/Profile-CWqti7FB.js.map → auth/Profile-BMpXJ0oi.js.map} +1 -1
- package/dist/auth/{Register-6hi_cpfF.js → Register-2gx8qll-.js} +2 -2
- package/dist/auth/{Register-6hi_cpfF.js.map → Register-2gx8qll-.js.map} +1 -1
- package/dist/{demo/ResetPassword-DWN0lzr5.js → auth/ResetPassword-DBxt9hKk.js} +2 -2
- package/dist/auth/{ResetPassword-CqfTk1FI.js.map → ResetPassword-DBxt9hKk.js.map} +1 -1
- package/dist/{demo/VerifyEmail-DZWL72K4.js → auth/VerifyEmail-Z80Ubajk.js} +2 -2
- package/dist/auth/{VerifyEmail-nWiSTMjF.js.map → VerifyEmail-Z80Ubajk.js.map} +1 -1
- package/dist/auth/{core-niW0sFLv.js → core-DyfeVr5c.js} +1002 -38
- package/dist/auth/core-DyfeVr5c.js.map +1 -0
- package/dist/auth/index.d.ts +12 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +12 -13
- package/dist/auth/index.js.map +1 -1
- package/dist/core/index.d.ts +95 -14
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1473 -232
- package/dist/core/index.js.map +1 -1
- package/dist/demo/{AuthLayout-jLa0aKsI.js → AuthLayout-DN-ClJQk.js} +2 -2
- package/dist/demo/{AuthLayout-jLa0aKsI.js.map → AuthLayout-DN-ClJQk.js.map} +1 -1
- package/dist/demo/{DemoButton-BmaWZVwf.js → DemoButton-CGUyR9eM.js} +3 -3
- package/dist/demo/{DemoButton-BmaWZVwf.js.map → DemoButton-CGUyR9eM.js.map} +1 -1
- package/dist/demo/{DemoDataTable-Z9xyV221.js → DemoDataTable-QFG-xXSx.js} +15 -19
- package/dist/demo/DemoDataTable-QFG-xXSx.js.map +1 -0
- package/dist/demo/{DemoDialog-4ItHLf9t.js → DemoDialog-DW8QEvD1.js} +2 -2
- package/dist/demo/{DemoDialog-4ItHLf9t.js.map → DemoDialog-DW8QEvD1.js.map} +1 -1
- package/dist/demo/{DemoFlex-EtVq8QfX.js → DemoFlex-CAhLUanT.js} +3 -3
- package/dist/demo/{DemoFlex-EtVq8QfX.js.map → DemoFlex-CAhLUanT.js.map} +1 -1
- package/dist/demo/{DemoHeading-BS-vGfkI.js → DemoHeading-yIFmNjHB.js} +3 -3
- package/dist/demo/{DemoHeading-BS-vGfkI.js.map → DemoHeading-yIFmNjHB.js.map} +1 -1
- package/dist/demo/{DemoHome-Clbn8AmS.js → DemoHome-BSGuBHus.js} +2 -2
- package/dist/demo/{DemoHome-Clbn8AmS.js.map → DemoHome-BSGuBHus.js.map} +1 -1
- package/dist/demo/{DemoJsonViewer-DkIX_ky2.js → DemoJsonViewer-DsA2IpgV.js} +3 -3
- package/dist/demo/{DemoJsonViewer-DkIX_ky2.js.map → DemoJsonViewer-DsA2IpgV.js.map} +1 -1
- package/dist/demo/{DemoLayout-C56xb5EE.js → DemoLayout-Cy6xjn6P.js} +2 -2
- package/dist/demo/{DemoLayout-C56xb5EE.js.map → DemoLayout-Cy6xjn6P.js.map} +1 -1
- package/dist/demo/{DemoLogin-BZwpicOS.js → DemoLogin-vqxgTu4P.js} +8 -8
- package/dist/demo/{DemoLogin-BZwpicOS.js.map → DemoLogin-vqxgTu4P.js.map} +1 -1
- package/dist/demo/{DemoRegister-C7_qc4MJ.js → DemoRegister-YHPvPg77.js} +8 -8
- package/dist/demo/{DemoRegister-C7_qc4MJ.js.map → DemoRegister-YHPvPg77.js.map} +1 -1
- package/dist/demo/{DemoResetPassword-BI1Ct4Dw.js → DemoResetPassword-mOW18Zlm.js} +8 -8
- package/dist/demo/{DemoResetPassword-BI1Ct4Dw.js.map → DemoResetPassword-mOW18Zlm.js.map} +1 -1
- package/dist/demo/{DemoSidebar-CcBo4ltC.js → DemoSidebar-od7aLjP_.js} +3 -3
- package/dist/demo/{DemoSidebar-CcBo4ltC.js.map → DemoSidebar-od7aLjP_.js.map} +1 -1
- package/dist/demo/{DemoText-CzXuUn3g.js → DemoText-DU3JeRS0.js} +3 -3
- package/dist/demo/{DemoText-CzXuUn3g.js.map → DemoText-DU3JeRS0.js.map} +1 -1
- package/dist/demo/{DemoToast-BgHDhWrX.js → DemoToast-CUJEiPRa.js} +2 -2
- package/dist/demo/{DemoToast-BgHDhWrX.js.map → DemoToast-CUJEiPRa.js.map} +1 -1
- package/dist/demo/{DemoTypeForm-DDzWoMSV.js → DemoTypeForm-C1dNkahD.js} +3 -3
- package/dist/demo/{DemoTypeForm-DDzWoMSV.js.map → DemoTypeForm-C1dNkahD.js.map} +1 -1
- package/dist/demo/{DemoVerifyEmail-C_Irdnov.js → DemoVerifyEmail-D9EcXZ38.js} +8 -8
- package/dist/demo/{DemoVerifyEmail-C_Irdnov.js.map → DemoVerifyEmail-D9EcXZ38.js.map} +1 -1
- package/dist/demo/{Login-hSOU3jZc.js → Login-CoYf_P_F.js} +2 -2
- package/dist/demo/{Login-hSOU3jZc.js.map → Login-CoYf_P_F.js.map} +1 -1
- package/dist/demo/{Profile-CWqti7FB.js → Profile-BE_Y3co2.js} +2 -2
- package/dist/{admin/Profile-B-c9pCPf.js.map → demo/Profile-BE_Y3co2.js.map} +1 -1
- package/dist/demo/{Register-a70LPgs2.js → Register-fXHmBpr3.js} +2 -2
- package/dist/{admin/Register-Cs10l8vX.js.map → demo/Register-fXHmBpr3.js.map} +1 -1
- package/dist/{auth/ResetPassword-CqfTk1FI.js → demo/ResetPassword-CAPj8MO3.js} +2 -2
- package/dist/demo/{ResetPassword-DWN0lzr5.js.map → ResetPassword-CAPj8MO3.js.map} +1 -1
- package/dist/demo/{Showcase-Dq3MISpd.js → Showcase-BtEU0pY9.js} +2 -2
- package/dist/demo/{Showcase-Dq3MISpd.js.map → Showcase-BtEU0pY9.js.map} +1 -1
- package/dist/{auth/VerifyEmail-nWiSTMjF.js → demo/VerifyEmail-DFmdCdYs.js} +2 -2
- package/dist/demo/{VerifyEmail-DZWL72K4.js.map → VerifyEmail-DFmdCdYs.js.map} +1 -1
- package/dist/demo/{auth-d6n3xbug.js → auth-Djd7SKiw.js} +8 -8
- package/dist/demo/{auth-d6n3xbug.js.map → auth-Djd7SKiw.js.map} +1 -1
- package/dist/demo/{core-RCUw1Q-a.js → core-B7LNjM78.js} +1484 -226
- package/dist/demo/core-B7LNjM78.js.map +1 -0
- package/dist/demo/index.js +17 -17
- package/package.json +3 -3
- package/src/admin/{AdminRouter.ts → AdminRouter.tsx} +128 -19
- package/src/admin/components/AdminDashboard.tsx +52 -0
- package/src/admin/components/AdminLayout.tsx +32 -40
- package/src/admin/components/audits/AdminAudits.tsx +22 -16
- package/src/admin/components/files/AdminFiles.tsx +1 -6
- package/src/admin/components/jobs/AdminJobExecutions.tsx +33 -39
- package/src/admin/components/jobs/AdminJobRegistry.tsx +9 -18
- package/src/admin/components/keys/AdminApiKeys.tsx +23 -41
- package/src/admin/components/sessions/AdminSessions.tsx +71 -71
- package/src/admin/components/users/AdminUserSessions.tsx +33 -31
- package/src/admin/components/users/AdminUsers.tsx +184 -72
- package/src/admin/index.ts +2 -2
- package/src/admin/primitives/$uiAdmin.ts +1 -1
- package/src/auth/components/buttons/UserButton.tsx +1 -3
- package/src/core/atoms/alephaSidebarAtom.ts +1 -1
- package/src/core/atoms/alephaThemeListAtom.ts +14 -1
- package/src/core/atoms/alephaThemeOverridesAtom.ts +17 -0
- package/src/core/atoms/themes/editorial.ts +184 -0
- package/src/core/atoms/themes/monochrome.ts +197 -0
- package/src/core/atoms/themes/rosePine.ts +208 -0
- package/src/core/atoms/themes/softBrutalism.ts +221 -0
- package/src/core/atoms/themes/terminal.ts +186 -0
- package/src/core/components/Flex.tsx +91 -1
- package/src/core/components/Text.tsx +1 -1
- package/src/core/components/buttons/ActionButton.tsx +15 -19
- package/src/core/components/buttons/DarkModeButton.tsx +3 -3
- package/src/core/components/buttons/LanguageButton.tsx +1 -1
- package/src/core/components/buttons/OmnibarButton.tsx +1 -2
- package/src/core/components/buttons/ThemeButton.tsx +40 -11
- package/src/core/components/buttons/ThemeExpertModal.tsx +184 -0
- package/src/core/components/buttons/ToggleSidebarButton.tsx +1 -2
- package/src/core/components/layout/AppBar.tsx +10 -0
- package/src/core/components/layout/DashboardShell.tsx +10 -7
- package/src/core/components/layout/Sidebar.tsx +60 -52
- package/src/core/constants/ui.ts +5 -5
- package/src/core/hooks/useTheme.ts +26 -3
- package/src/core/index.ts +6 -1
- package/src/core/interfaces/AlephaTheme.ts +2 -0
- package/src/core/providers/ThemeProvider.ts +108 -8
- package/src/core/services/DialogService.tsx +24 -3
- package/src/core/styles.css +26 -23
- package/src/core/table/components/DataTable.tsx +167 -137
- package/src/core/table/components/DataTableFilters.tsx +1 -6
- package/src/core/table/components/DataTablePagination.tsx +51 -28
- package/src/core/table/components/DataTableToolbar.tsx +9 -4
- package/src/core/table/index.ts +1 -0
- package/src/core/table/interfaces/types.ts +13 -9
- package/src/demo/components/core/DemoDataTable.tsx +15 -19
- package/dist/admin/AdminApiKeys-C-6_Q-lH.js.map +0 -1
- package/dist/admin/AdminAudits-Bgbf04hO.js.map +0 -1
- package/dist/admin/AdminFiles-B9a7G3cY.js.map +0 -1
- package/dist/admin/AdminJobExecutions-B9cek5dl.js.map +0 -1
- package/dist/admin/AdminJobRegistry-DFgV3oqx.js.map +0 -1
- package/dist/admin/AdminLayout-DHsvWxVB.js +0 -70
- package/dist/admin/AdminLayout-DHsvWxVB.js.map +0 -1
- package/dist/admin/AdminSessions-BhGJPI3z.js.map +0 -1
- package/dist/admin/AdminUserSessions-1uzcx02z.js.map +0 -1
- package/dist/admin/AdminUsers-C85c3eiQ.js +0 -121
- package/dist/admin/AdminUsers-C85c3eiQ.js.map +0 -1
- package/dist/admin/auth-Dr0Cf8I7.js +0 -319
- package/dist/admin/auth-Dr0Cf8I7.js.map +0 -1
- package/dist/admin/core-2xoLiT0o.js.map +0 -1
- package/dist/auth/core-niW0sFLv.js.map +0 -1
- package/dist/demo/DemoDataTable-Z9xyV221.js.map +0 -1
- package/dist/demo/core-RCUw1Q-a.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Register-a70LPgs2.js","names":[],"sources":["../../src/auth/components/Register.tsx"],"sourcesContent":["import { ActionButton, Control, capitalize } from \"@alepha/ui\";\nimport { Alert, Card, Flex, Image, PinInput, Text, Title } 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 { 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 { 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.push(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.push(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 <Flex direction=\"column\" gap={\"sm\"} w={360}>\n <Card withBorder p={\"lg\"} bg={\"var(--alepha-elevated)\"}>\n <Flex direction=\"column\" 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 <Flex direction=\"column\" 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 </Flex>\n )}\n\n {registrationState.intent.expectPhoneVerification && (\n <Flex direction=\"column\" 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 </Flex>\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 </Flex>\n </Card>\n </Flex>\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 <Flex direction=\"column\" gap={\"sm\"} w={360}>\n <Card withBorder p={\"lg\"} bg={\"var(--alepha-elevated)\"}>\n <Flex direction=\"column\" gap={\"md\"}>\n {/* Realm branding */}\n {(settings.logoUrl ||\n settings.displayName ||\n settings.description) && (\n <Flex direction=\"column\" 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 </Flex>\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 <Flex direction=\"column\" 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 </Flex>\n </form>\n )}\n\n {/* OR divider - only when both credentials AND external methods exist */}\n {showOrDivider && (\n <Flex 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 </Flex>\n )}\n\n {/* External login methods */}\n {externalMethods.length > 0 && (\n <Flex direction=\"column\" 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 </Flex>\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 </Flex>\n </Card>\n <ActionButton variant={\"subtle\"} href={redirect}>\n {tr(\"registerCancel\")}\n </ActionButton>\n </Flex>\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":"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"}
|
|
1
|
+
{"version":3,"file":"Register-Z3fxRbUF.js","names":[],"sources":["../../src/auth/components/Register.tsx"],"sourcesContent":["import { ActionButton, Control, capitalize } from \"@alepha/ui\";\nimport { Alert, Card, Flex, Image, PinInput, Text, Title } 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 { 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 { 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.push(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.push(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 <Flex direction=\"column\" gap={\"sm\"} w={360}>\n <Card withBorder p={\"lg\"} bg={\"var(--alepha-elevated)\"}>\n <Flex direction=\"column\" 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 <Flex direction=\"column\" 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 </Flex>\n )}\n\n {registrationState.intent.expectPhoneVerification && (\n <Flex direction=\"column\" 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 </Flex>\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 </Flex>\n </Card>\n </Flex>\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 <Flex direction=\"column\" gap={\"sm\"} w={360}>\n <Card withBorder p={\"lg\"} bg={\"var(--alepha-elevated)\"}>\n <Flex direction=\"column\" gap={\"md\"}>\n {/* Realm branding */}\n {(settings.logoUrl ||\n settings.displayName ||\n settings.description) && (\n <Flex direction=\"column\" 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 </Flex>\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 <Flex direction=\"column\" 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 </Flex>\n </form>\n )}\n\n {/* OR divider - only when both credentials AND external methods exist */}\n {showOrDivider && (\n <Flex 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 </Flex>\n )}\n\n {/* External login methods */}\n {externalMethods.length > 0 && (\n <Flex direction=\"column\" 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 </Flex>\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 </Flex>\n </Card>\n <ActionButton variant={\"subtle\"} href={redirect}>\n {tr(\"registerCancel\")}\n </ActionButton>\n </Flex>\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":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-CjeV3_4I.js";
|
|
2
|
-
import { _ as ActionButton,
|
|
2
|
+
import { _ as ActionButton, a as Control } from "./core-BVO_TQxb.js";
|
|
3
3
|
import { AlephaError, t } from "alepha";
|
|
4
4
|
import { useForm } from "alepha/react/form";
|
|
5
5
|
import { useI18n } from "alepha/react/i18n";
|
|
@@ -283,4 +283,4 @@ const ResetPassword = (props) => {
|
|
|
283
283
|
|
|
284
284
|
//#endregion
|
|
285
285
|
export { ResetPassword_exports as t };
|
|
286
|
-
//# sourceMappingURL=ResetPassword-
|
|
286
|
+
//# sourceMappingURL=ResetPassword-_Y1qTTKh.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResetPassword-BwDdfkGH.js","names":[],"sources":["../../src/auth/components/ResetPassword.tsx"],"sourcesContent":["import { ActionButton, Control } from \"@alepha/ui\";\nimport { Alert, Card, Flex, Image, PinInput, Text, Title } 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 { useClient } from \"alepha/react\";\nimport { useForm } from \"alepha/react/form\";\nimport { useI18n } from \"alepha/react/i18n\";\nimport { useRouter } from \"alepha/react/router\";\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 <Flex direction=\"column\" gap={\"sm\"} w={360}>\n <Card withBorder p={\"lg\"} bg={\"var(--alepha-elevated)\"}>\n <Flex direction=\"column\" gap={\"md\"}>\n {/* Realm branding */}\n {(settings.logoUrl ||\n settings.displayName ||\n settings.description) && (\n <Flex direction=\"column\" 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 </Flex>\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 <Flex direction=\"column\" 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 </Flex>\n </form>\n ) : resetState.step === \"code\" ? (\n <Flex direction=\"column\" 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 </Flex>\n ) : resetState.step === \"password\" ? (\n <form {...passwordForm.props}>\n <Flex direction=\"column\" 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 </Flex>\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 </Flex>\n </Card>\n <ActionButton variant={\"subtle\"} href={redirect}>\n {tr(\"resetPasswordCancel\")}\n </ActionButton>\n </Flex>\n </Flex>\n );\n};\n\nexport default ResetPassword;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ResetPassword-_Y1qTTKh.js","names":[],"sources":["../../src/auth/components/ResetPassword.tsx"],"sourcesContent":["import { ActionButton, Control } from \"@alepha/ui\";\nimport { Alert, Card, Flex, Image, PinInput, Text, Title } 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 { useClient } from \"alepha/react\";\nimport { useForm } from \"alepha/react/form\";\nimport { useI18n } from \"alepha/react/i18n\";\nimport { useRouter } from \"alepha/react/router\";\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 <Flex direction=\"column\" gap={\"sm\"} w={360}>\n <Card withBorder p={\"lg\"} bg={\"var(--alepha-elevated)\"}>\n <Flex direction=\"column\" gap={\"md\"}>\n {/* Realm branding */}\n {(settings.logoUrl ||\n settings.displayName ||\n settings.description) && (\n <Flex direction=\"column\" 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 </Flex>\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 <Flex direction=\"column\" 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 </Flex>\n </form>\n ) : resetState.step === \"code\" ? (\n <Flex direction=\"column\" 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 </Flex>\n ) : resetState.step === \"password\" ? (\n <form {...passwordForm.props}>\n <Flex direction=\"column\" 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 </Flex>\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 </Flex>\n </Card>\n <ActionButton variant={\"subtle\"} href={redirect}>\n {tr(\"resetPasswordCancel\")}\n </ActionButton>\n </Flex>\n </Flex>\n );\n};\n\nexport default ResetPassword;\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-CjeV3_4I.js";
|
|
2
|
-
import { _ as ActionButton } from "./core-
|
|
2
|
+
import { _ as ActionButton } from "./core-BVO_TQxb.js";
|
|
3
3
|
import { useI18n } from "alepha/react/i18n";
|
|
4
4
|
import { Alert, Card, Flex, Loader, Text } from "@mantine/core";
|
|
5
5
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -132,4 +132,4 @@ const VerifyEmail = (_props) => {
|
|
|
132
132
|
|
|
133
133
|
//#endregion
|
|
134
134
|
export { VerifyEmail_exports as t };
|
|
135
|
-
//# sourceMappingURL=VerifyEmail-
|
|
135
|
+
//# sourceMappingURL=VerifyEmail-Bg22bwcC.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VerifyEmail-
|
|
1
|
+
{"version":3,"file":"VerifyEmail-Bg22bwcC.js","names":[],"sources":["../../src/auth/components/VerifyEmail.tsx"],"sourcesContent":["import { ActionButton } from \"@alepha/ui\";\nimport { Alert, Card, Flex, Loader, Text } from \"@mantine/core\";\nimport { IconAlertCircle, IconCheck, IconMailCheck } from \"@tabler/icons-react\";\nimport type { UserController } from \"alepha/api/users\";\nimport { useClient } from \"alepha/react\";\nimport { useI18n } from \"alepha/react/i18n\";\nimport { useRouter, useRouterState } from \"alepha/react/router\";\nimport { useEffect, useState } from \"react\";\nimport type { AuthI18n } from \"../AuthI18n.ts\";\nimport type { AuthRouter } from \"../AuthRouter.ts\";\n\nexport type VerifyEmailProps = {};\n\ntype Step = \"verifying\" | \"success\" | \"error\";\n\nconst VerifyEmail = (_props: VerifyEmailProps) => {\n const router = useRouter<AuthRouter>();\n const state = useRouterState();\n const userCtrl = useClient<UserController>();\n const { tr } = useI18n<AuthI18n, \"en\">();\n\n const [step, setStep] = useState<Step>(\"verifying\");\n const [error, setError] = useState<string | null>(null);\n\n const email = state.query.email as string | undefined;\n const token = state.query.token as string | undefined;\n\n useEffect(() => {\n const verify = async () => {\n if (!email || !token) {\n setError(tr(\"verifyEmailMissingParams\"));\n setStep(\"error\");\n return;\n }\n\n try {\n await userCtrl.verifyEmail({\n body: { email, token },\n });\n setStep(\"success\");\n } catch (err) {\n setError(err instanceof Error ? err.message : tr(\"verifyEmailFailed\"));\n setStep(\"error\");\n }\n };\n\n verify();\n }, [email, token]);\n\n return (\n <Flex flex={1} justify=\"center\" align=\"center\">\n <Flex direction=\"column\" gap=\"sm\" w={400}>\n <Card withBorder p=\"lg\" bg=\"var(--alepha-elevated)\">\n <Flex direction=\"column\" gap=\"md\" align=\"center\">\n {step === \"verifying\" && (\n <>\n <Loader size=\"lg\" />\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"verifyEmailVerifying\")}\n </Text>\n <Text size=\"sm\" c=\"dimmed\" ta=\"center\">\n {tr(\"verifyEmailPleaseWait\")}\n </Text>\n </>\n )}\n\n {step === \"success\" && (\n <>\n <IconMailCheck size={48} color=\"var(--mantine-color-green-6)\" />\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"verifyEmailTitle\")}\n </Text>\n <Alert variant=\"light\" color=\"green\" icon={<IconCheck />}>\n <Text size=\"sm\">{tr(\"verifyEmailSuccess\")}</Text>\n </Alert>\n <ActionButton href={router.path(\"login\")} fullWidth>\n {tr(\"verifyEmailSignIn\")}\n </ActionButton>\n </>\n )}\n\n {step === \"error\" && (\n <>\n <IconAlertCircle size={48} color=\"var(--mantine-color-red-6)\" />\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"verifyEmailTitle\")}\n </Text>\n <Alert variant=\"light\" color=\"red\" icon={<IconAlertCircle />}>\n <Text size=\"sm\">{error || tr(\"verifyEmailFailed\")}</Text>\n </Alert>\n <ActionButton href={router.path(\"login\")} fullWidth>\n {tr(\"verifyEmailBackToSignIn\")}\n </ActionButton>\n </>\n )}\n </Flex>\n </Card>\n </Flex>\n </Flex>\n );\n};\n\nexport default VerifyEmail;\n"],"mappings":";;;;;;;;;;;;AAeA,MAAM,eAAe,WAA6B;CAChD,MAAM,SAAS,WAAuB;CACtC,MAAM,QAAQ,gBAAgB;CAC9B,MAAM,WAAW,WAA2B;CAC5C,MAAM,EAAE,OAAO,SAAyB;CAExC,MAAM,CAAC,MAAM,WAAW,SAAe,YAAY;CACnD,MAAM,CAAC,OAAO,YAAY,SAAwB,KAAK;CAEvD,MAAM,QAAQ,MAAM,MAAM;CAC1B,MAAM,QAAQ,MAAM,MAAM;AAE1B,iBAAgB;EACd,MAAM,SAAS,YAAY;AACzB,OAAI,CAAC,SAAS,CAAC,OAAO;AACpB,aAAS,GAAG,2BAA2B,CAAC;AACxC,YAAQ,QAAQ;AAChB;;AAGF,OAAI;AACF,UAAM,SAAS,YAAY,EACzB,MAAM;KAAE;KAAO;KAAO,EACvB,CAAC;AACF,YAAQ,UAAU;YACX,KAAK;AACZ,aAAS,eAAe,QAAQ,IAAI,UAAU,GAAG,oBAAoB,CAAC;AACtE,YAAQ,QAAQ;;;AAIpB,UAAQ;IACP,CAAC,OAAO,MAAM,CAAC;AAElB,QACE,oBAAC;EAAK,MAAM;EAAG,SAAQ;EAAS,OAAM;YACpC,oBAAC;GAAK,WAAU;GAAS,KAAI;GAAK,GAAG;aACnC,oBAAC;IAAK;IAAW,GAAE;IAAK,IAAG;cACzB,qBAAC;KAAK,WAAU;KAAS,KAAI;KAAK,OAAM;;MACrC,SAAS,eACR;OACE,oBAAC,UAAO,MAAK,OAAO;OACpB,oBAAC;QAAK,MAAK;QAAK,IAAI;QAAK,IAAG;kBACzB,GAAG,uBAAuB;SACtB;OACP,oBAAC;QAAK,MAAK;QAAK,GAAE;QAAS,IAAG;kBAC3B,GAAG,wBAAwB;SACvB;UACN;MAGJ,SAAS,aACR;OACE,oBAAC;QAAc,MAAM;QAAI,OAAM;SAAiC;OAChE,oBAAC;QAAK,MAAK;QAAK,IAAI;QAAK,IAAG;kBACzB,GAAG,mBAAmB;SAClB;OACP,oBAAC;QAAM,SAAQ;QAAQ,OAAM;QAAQ,MAAM,oBAAC,cAAY;kBACtD,oBAAC;SAAK,MAAK;mBAAM,GAAG,qBAAqB;UAAQ;SAC3C;OACR,oBAAC;QAAa,MAAM,OAAO,KAAK,QAAQ;QAAE;kBACvC,GAAG,oBAAoB;SACX;UACd;MAGJ,SAAS,WACR;OACE,oBAAC;QAAgB,MAAM;QAAI,OAAM;SAA+B;OAChE,oBAAC;QAAK,MAAK;QAAK,IAAI;QAAK,IAAG;kBACzB,GAAG,mBAAmB;SAClB;OACP,oBAAC;QAAM,SAAQ;QAAQ,OAAM;QAAM,MAAM,oBAAC,oBAAkB;kBAC1D,oBAAC;SAAK,MAAK;mBAAM,SAAS,GAAG,oBAAoB;UAAQ;SACnD;OACR,oBAAC;QAAa,MAAM,OAAO,KAAK,QAAQ;QAAE;kBACvC,GAAG,0BAA0B;SACjB;UACd;;MAEA;KACF;IACF;GACF"}
|