hazo_auth 7.0.1 → 8.0.1
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/README.md +96 -319
- package/SETUP_CHECKLIST.md +59 -248
- package/cli-src/cli/generate.ts +1 -10
- package/cli-src/cli/validate.ts +0 -4
- package/cli-src/lib/auth/auth_types.ts +15 -21
- package/cli-src/lib/auth/hazo_get_auth.server.ts +19 -0
- package/cli-src/lib/auth/hazo_get_tenant_auth.server.ts +24 -25
- package/cli-src/lib/auth/index.ts +2 -2
- package/cli-src/lib/auth/nextauth_config.ts +27 -67
- package/cli-src/lib/auth/with_auth.server.ts +15 -15
- package/cli-src/lib/config/default_config.ts +8 -0
- package/cli-src/lib/cookies_config.server.ts +1 -1
- package/cli-src/lib/email_verification_config.server.ts +34 -0
- package/cli-src/lib/forgot_password_config.server.ts +34 -0
- package/cli-src/lib/legal/legal_docs_config.server.ts +61 -0
- package/cli-src/lib/legal/legal_docs_reader.server.ts +36 -0
- package/cli-src/lib/legal/legal_docs_service.ts +196 -0
- package/cli-src/lib/legal/legal_docs_types.ts +31 -0
- package/cli-src/lib/login_config.server.ts +29 -14
- package/cli-src/lib/my_settings_config.server.ts +3 -0
- package/cli-src/lib/oauth_config.server.ts +31 -57
- package/cli-src/lib/register_config.server.ts +35 -11
- package/cli-src/lib/reset_password_config.server.ts +31 -0
- package/cli-src/lib/services/email_template_manifest.ts +0 -17
- package/cli-src/lib/services/index.ts +2 -8
- package/cli-src/lib/services/oauth_service.ts +74 -128
- package/cli-src/lib/services/otp_service.ts +7 -2
- package/cli-src/lib/services/registration_service.ts +16 -1
- package/cli-src/lib/services/session_token_service.ts +0 -2
- package/config/hazo_auth_config.example.ini +41 -76
- package/dist/cli/generate.d.ts.map +1 -1
- package/dist/cli/generate.js +1 -10
- package/dist/cli/validate.d.ts.map +1 -1
- package/dist/cli/validate.js +0 -4
- package/dist/client.d.ts +1 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +3 -1
- package/dist/components/layouts/create_firm/index.d.ts +8 -4
- package/dist/components/layouts/create_firm/index.d.ts.map +1 -1
- package/dist/components/layouts/create_firm/index.js +3 -3
- package/dist/components/layouts/email_verification/index.d.ts +5 -4
- package/dist/components/layouts/email_verification/index.d.ts.map +1 -1
- package/dist/components/layouts/email_verification/index.js +4 -4
- package/dist/components/layouts/forgot_password/index.d.ts +5 -4
- package/dist/components/layouts/forgot_password/index.d.ts.map +1 -1
- package/dist/components/layouts/forgot_password/index.js +2 -2
- package/dist/components/layouts/index.d.ts +1 -0
- package/dist/components/layouts/index.d.ts.map +1 -1
- package/dist/components/layouts/index.js +2 -0
- package/dist/components/layouts/legal/index.d.ts +5 -0
- package/dist/components/layouts/legal/index.d.ts.map +1 -0
- package/dist/components/layouts/legal/index.js +4 -0
- package/dist/components/layouts/legal/legal_acceptance_gate.d.ts +7 -0
- package/dist/components/layouts/legal/legal_acceptance_gate.d.ts.map +1 -0
- package/dist/components/layouts/legal/legal_acceptance_gate.js +84 -0
- package/dist/components/layouts/legal/legal_doc_checkbox_list.d.ts +9 -0
- package/dist/components/layouts/legal/legal_doc_checkbox_list.d.ts.map +1 -0
- package/dist/components/layouts/legal/legal_doc_checkbox_list.js +11 -0
- package/dist/components/layouts/legal/legal_doc_combined_view.d.ts +9 -0
- package/dist/components/layouts/legal/legal_doc_combined_view.d.ts.map +1 -0
- package/dist/components/layouts/legal/legal_doc_combined_view.js +11 -0
- package/dist/components/layouts/legal/legal_doc_drawer.d.ts +8 -0
- package/dist/components/layouts/legal/legal_doc_drawer.d.ts.map +1 -0
- package/dist/components/layouts/legal/legal_doc_drawer.js +55 -0
- package/dist/components/layouts/login/index.d.ts +13 -19
- package/dist/components/layouts/login/index.d.ts.map +1 -1
- package/dist/components/layouts/login/index.js +8 -11
- package/dist/components/layouts/otp/index.d.ts +5 -1
- package/dist/components/layouts/otp/index.d.ts.map +1 -1
- package/dist/components/layouts/otp/index.js +2 -2
- package/dist/components/layouts/register/hooks/use_register_form.d.ts +5 -1
- package/dist/components/layouts/register/hooks/use_register_form.d.ts.map +1 -1
- package/dist/components/layouts/register/hooks/use_register_form.js +25 -10
- package/dist/components/layouts/register/index.d.ts +11 -11
- package/dist/components/layouts/register/index.d.ts.map +1 -1
- package/dist/components/layouts/register/index.js +26 -7
- package/dist/components/layouts/reset_password/index.d.ts +5 -4
- package/dist/components/layouts/reset_password/index.d.ts.map +1 -1
- package/dist/components/layouts/reset_password/index.js +5 -5
- package/dist/components/layouts/shared/components/already_logged_in_guard.d.ts +5 -3
- package/dist/components/layouts/shared/components/already_logged_in_guard.d.ts.map +1 -1
- package/dist/components/layouts/shared/components/already_logged_in_guard.js +2 -2
- package/dist/components/layouts/shared/components/facebook_sign_in_button.d.ts +2 -6
- package/dist/components/layouts/shared/components/facebook_sign_in_button.d.ts.map +1 -1
- package/dist/components/layouts/shared/components/facebook_sign_in_button.js +11 -13
- package/dist/components/layouts/shared/components/sidebar_layout_wrapper.d.ts.map +1 -1
- package/dist/components/layouts/shared/components/sidebar_layout_wrapper.js +3 -8
- package/dist/components/layouts/shared/components/two_column_auth_layout.d.ts +6 -3
- package/dist/components/layouts/shared/components/two_column_auth_layout.d.ts.map +1 -1
- package/dist/components/layouts/shared/components/two_column_auth_layout.js +5 -8
- package/dist/components/layouts/shared/index.d.ts +2 -0
- package/dist/components/layouts/shared/index.d.ts.map +1 -1
- package/dist/components/layouts/shared/index.js +1 -0
- package/dist/components/layouts/user_management/index.d.ts.map +1 -1
- package/dist/components/layouts/user_management/index.js +84 -9
- package/dist/components/ui/button.d.ts +1 -1
- package/dist/components/ui/input-otp.d.ts +2 -2
- package/dist/components/ui/sheet.d.ts +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/lib/auth/auth_types.d.ts +14 -13
- package/dist/lib/auth/auth_types.d.ts.map +1 -1
- package/dist/lib/auth/auth_types.js +0 -10
- package/dist/lib/auth/hazo_get_auth.server.d.ts.map +1 -1
- package/dist/lib/auth/hazo_get_auth.server.js +19 -0
- package/dist/lib/auth/hazo_get_tenant_auth.server.d.ts +7 -8
- package/dist/lib/auth/hazo_get_tenant_auth.server.d.ts.map +1 -1
- package/dist/lib/auth/hazo_get_tenant_auth.server.js +22 -23
- package/dist/lib/auth/index.d.ts +2 -2
- package/dist/lib/auth/index.d.ts.map +1 -1
- package/dist/lib/auth/nextauth_config.d.ts +0 -10
- package/dist/lib/auth/nextauth_config.d.ts.map +1 -1
- package/dist/lib/auth/nextauth_config.js +23 -52
- package/dist/lib/auth/with_auth.server.d.ts +13 -13
- package/dist/lib/auth/with_auth.server.d.ts.map +1 -1
- package/dist/lib/auth/with_auth.server.js +2 -2
- package/dist/lib/config/default_config.d.ts +16 -0
- package/dist/lib/config/default_config.d.ts.map +1 -1
- package/dist/lib/config/default_config.js +8 -0
- package/dist/lib/cookies_config.server.d.ts +1 -1
- package/dist/lib/cookies_config.server.js +1 -1
- package/dist/lib/email_verification_config.server.d.ts +3 -0
- package/dist/lib/email_verification_config.server.d.ts.map +1 -1
- package/dist/lib/email_verification_config.server.js +15 -0
- package/dist/lib/forgot_password_config.server.d.ts +3 -0
- package/dist/lib/forgot_password_config.server.d.ts.map +1 -1
- package/dist/lib/forgot_password_config.server.js +15 -0
- package/dist/lib/legal/legal_docs_config.server.d.ts +22 -0
- package/dist/lib/legal/legal_docs_config.server.d.ts.map +1 -0
- package/dist/lib/legal/legal_docs_config.server.js +52 -0
- package/dist/lib/legal/legal_docs_reader.server.d.ts +15 -0
- package/dist/lib/legal/legal_docs_reader.server.d.ts.map +1 -0
- package/dist/lib/legal/legal_docs_reader.server.js +24 -0
- package/dist/lib/legal/legal_docs_service.d.ts +49 -0
- package/dist/lib/legal/legal_docs_service.d.ts.map +1 -0
- package/dist/lib/legal/legal_docs_service.js +140 -0
- package/dist/lib/legal/legal_docs_types.d.ts +25 -0
- package/dist/lib/legal/legal_docs_types.d.ts.map +1 -0
- package/dist/lib/legal/legal_docs_types.js +2 -0
- package/dist/lib/login_config.server.d.ts +3 -6
- package/dist/lib/login_config.server.d.ts.map +1 -1
- package/dist/lib/login_config.server.js +11 -7
- package/dist/lib/my_settings_config.server.d.ts +1 -0
- package/dist/lib/my_settings_config.server.d.ts.map +1 -1
- package/dist/lib/my_settings_config.server.js +2 -0
- package/dist/lib/oauth_config.server.d.ts +8 -17
- package/dist/lib/oauth_config.server.d.ts.map +1 -1
- package/dist/lib/oauth_config.server.js +10 -25
- package/dist/lib/register_config.server.d.ts +5 -2
- package/dist/lib/register_config.server.d.ts.map +1 -1
- package/dist/lib/register_config.server.js +15 -4
- package/dist/lib/reset_password_config.server.d.ts +3 -0
- package/dist/lib/reset_password_config.server.d.ts.map +1 -1
- package/dist/lib/reset_password_config.server.js +13 -0
- package/dist/lib/services/email_template_manifest.d.ts.map +1 -1
- package/dist/lib/services/email_template_manifest.js +0 -17
- package/dist/lib/services/index.d.ts +0 -2
- package/dist/lib/services/index.d.ts.map +1 -1
- package/dist/lib/services/index.js +0 -1
- package/dist/lib/services/oauth_service.d.ts +11 -22
- package/dist/lib/services/oauth_service.d.ts.map +1 -1
- package/dist/lib/services/oauth_service.js +63 -96
- package/dist/lib/services/otp_service.d.ts +1 -1
- package/dist/lib/services/otp_service.d.ts.map +1 -1
- package/dist/lib/services/otp_service.js +6 -1
- package/dist/lib/services/registration_service.d.ts +5 -0
- package/dist/lib/services/registration_service.d.ts.map +1 -1
- package/dist/lib/services/registration_service.js +6 -0
- package/dist/lib/services/session_token_service.d.ts +0 -2
- package/dist/lib/services/session_token_service.d.ts.map +1 -1
- package/dist/lib/services/session_token_service.js +0 -2
- package/dist/page_components/create_firm.d.ts +1 -13
- package/dist/page_components/create_firm.d.ts.map +1 -1
- package/dist/page_components/create_firm.js +6 -10
- package/dist/page_components/forgot_password.d.ts +4 -1
- package/dist/page_components/forgot_password.d.ts.map +1 -1
- package/dist/page_components/forgot_password.js +6 -2
- package/dist/page_components/index.d.ts +0 -5
- package/dist/page_components/index.d.ts.map +1 -1
- package/dist/page_components/index.js +0 -5
- package/dist/page_components/login.d.ts +4 -1
- package/dist/page_components/login.d.ts.map +1 -1
- package/dist/page_components/login.js +6 -2
- package/dist/page_components/register.d.ts +4 -1
- package/dist/page_components/register.d.ts.map +1 -1
- package/dist/page_components/register.js +6 -2
- package/dist/page_components/reset_password.d.ts +4 -1
- package/dist/page_components/reset_password.d.ts.map +1 -1
- package/dist/page_components/reset_password.js +6 -2
- package/dist/page_components/verify_email.d.ts +4 -1
- package/dist/page_components/verify_email.d.ts.map +1 -1
- package/dist/page_components/verify_email.js +6 -2
- package/dist/server/routes/assets.d.ts +8 -0
- package/dist/server/routes/assets.d.ts.map +1 -0
- package/dist/server/routes/assets.js +38 -0
- package/dist/server/routes/consent_me.d.ts +4 -0
- package/dist/server/routes/consent_me.d.ts.map +1 -0
- package/dist/server/routes/consent_me.js +15 -0
- package/dist/server/routes/index.d.ts +9 -4
- package/dist/server/routes/index.d.ts.map +1 -1
- package/dist/server/routes/index.js +13 -5
- package/dist/server/routes/legal_docs_accept.d.ts +3 -0
- package/dist/server/routes/legal_docs_accept.d.ts.map +1 -0
- package/dist/server/routes/legal_docs_accept.js +43 -0
- package/dist/server/routes/legal_docs_get.d.ts +3 -0
- package/dist/server/routes/legal_docs_get.d.ts.map +1 -0
- package/dist/server/routes/legal_docs_get.js +49 -0
- package/dist/server/routes/legal_docs_publish.d.ts +3 -0
- package/dist/server/routes/legal_docs_publish.d.ts.map +1 -0
- package/dist/server/routes/legal_docs_publish.js +35 -0
- package/dist/server/routes/me.d.ts.map +1 -1
- package/dist/server/routes/me.js +1 -43
- package/dist/server/routes/oauth_facebook_callback.d.ts +1 -1
- package/dist/server/routes/oauth_facebook_callback.d.ts.map +1 -1
- package/dist/server/routes/oauth_facebook_callback.js +8 -1
- package/dist/server/routes/oauth_google_callback.js +1 -1
- package/dist/server/routes/otp/verify.js +2 -2
- package/dist/server/routes/register.d.ts.map +1 -1
- package/dist/server/routes/register.js +26 -0
- package/dist/server/routes/strings_defaults.d.ts +4 -0
- package/dist/server/routes/strings_defaults.d.ts.map +1 -0
- package/dist/server/routes/strings_defaults.js +7 -0
- package/dist/server/routes/user_management_users.d.ts +11 -0
- package/dist/server/routes/user_management_users.d.ts.map +1 -1
- package/dist/server/routes/user_management_users.js +94 -0
- package/dist/server-lib.d.ts +0 -3
- package/dist/server-lib.d.ts.map +1 -1
- package/dist/server-lib.js +0 -2
- package/dist/server_pages/forgot_password.d.ts +18 -14
- package/dist/server_pages/forgot_password.d.ts.map +1 -1
- package/dist/server_pages/forgot_password.js +14 -12
- package/dist/server_pages/forgot_password_client_wrapper.d.ts +8 -7
- package/dist/server_pages/forgot_password_client_wrapper.d.ts.map +1 -1
- package/dist/server_pages/forgot_password_client_wrapper.js +2 -2
- package/dist/server_pages/index.d.ts +2 -0
- package/dist/server_pages/index.d.ts.map +1 -1
- package/dist/server_pages/index.js +1 -0
- package/dist/server_pages/login.d.ts +22 -23
- package/dist/server_pages/login.d.ts.map +1 -1
- package/dist/server_pages/login.js +27 -14
- package/dist/server_pages/login_client_wrapper.d.ts +9 -10
- package/dist/server_pages/login_client_wrapper.d.ts.map +1 -1
- package/dist/server_pages/login_client_wrapper.js +2 -2
- package/dist/server_pages/my_settings.d.ts +1 -3
- package/dist/server_pages/my_settings.d.ts.map +1 -1
- package/dist/server_pages/my_settings.js +2 -9
- package/dist/server_pages/register.d.ts +17 -20
- package/dist/server_pages/register.d.ts.map +1 -1
- package/dist/server_pages/register.js +20 -15
- package/dist/server_pages/register_client_wrapper.d.ts +8 -10
- package/dist/server_pages/register_client_wrapper.d.ts.map +1 -1
- package/dist/server_pages/register_client_wrapper.js +2 -2
- package/dist/server_pages/reset_password.d.ts +16 -11
- package/dist/server_pages/reset_password.d.ts.map +1 -1
- package/dist/server_pages/reset_password.js +14 -10
- package/dist/server_pages/reset_password_client_wrapper.d.ts +8 -7
- package/dist/server_pages/reset_password_client_wrapper.d.ts.map +1 -1
- package/dist/server_pages/reset_password_client_wrapper.js +2 -2
- package/dist/server_pages/verify_email.d.ts +18 -12
- package/dist/server_pages/verify_email.d.ts.map +1 -1
- package/dist/server_pages/verify_email.js +13 -11
- package/dist/server_pages/verify_email_client_wrapper.d.ts +8 -7
- package/dist/server_pages/verify_email_client_wrapper.d.ts.map +1 -1
- package/dist/server_pages/verify_email_client_wrapper.js +2 -2
- package/dist/strings.d.ts +2 -0
- package/dist/strings.d.ts.map +1 -0
- package/dist/strings.js +3 -0
- package/dist/themes/index.d.ts +0 -1
- package/dist/themes/index.d.ts.map +1 -1
- package/dist/themes/index.js +1 -1
- package/package.json +30 -61
- package/dist/themes/preset_indigo_sunset.d.ts +0 -3
- package/dist/themes/preset_indigo_sunset.d.ts.map +0 -1
- package/dist/themes/preset_indigo_sunset.js +0 -20
|
@@ -23,14 +23,16 @@ const ORDERED_FIELDS = [
|
|
|
23
23
|
LOGIN_FIELD_IDS.PASSWORD,
|
|
24
24
|
];
|
|
25
25
|
// section: component
|
|
26
|
-
export default function login_layout({
|
|
27
|
-
var _a
|
|
26
|
+
export default function login_layout({ image_src, image_alt, image_background_color = "#f1f5f9", field_overrides, labels, button_colors, data_client, logger, redirectRoute, successMessage = "Successfully logged in", alreadyLoggedInMessage = "You are already logged in", showLogoutButton = true, showReturnHomeButton = false, returnHomeButtonLabel = "Return home", returnHomePath = "/", forgot_password_path = "/hazo_auth/forgot_password", forgot_password_label = "Forgot password?", create_account_path = "/hazo_auth/register", create_account_label = "Create account", show_create_account_link = true, urlOnLogon, oauth, layout = "two_column", }) {
|
|
27
|
+
var _a;
|
|
28
28
|
// Default OAuth config: both enabled
|
|
29
29
|
const oauthConfig = oauth || {
|
|
30
30
|
enable_google: true,
|
|
31
31
|
enable_email_password: true,
|
|
32
32
|
google_button_text: "Continue with Google",
|
|
33
33
|
oauth_divider_text: "or continue with email",
|
|
34
|
+
enable_facebook_oauth: false,
|
|
35
|
+
facebook_button_text: "Continue with Facebook",
|
|
34
36
|
};
|
|
35
37
|
// Read OAuth error from URL query params (e.g., ?error=AccessDenied)
|
|
36
38
|
const searchParams = useSearchParams();
|
|
@@ -49,9 +51,6 @@ export default function login_layout({ theme, field_overrides, labels, button_co
|
|
|
49
51
|
const oauthCallbackUrl = safeRedirect
|
|
50
52
|
? `/api/hazo_auth/oauth/google/callback?next=${encodeURIComponent(safeRedirect)}`
|
|
51
53
|
: "/api/hazo_auth/oauth/google/callback";
|
|
52
|
-
const facebookCallbackUrl = safeRedirect
|
|
53
|
-
? `/api/hazo_auth/oauth/facebook/callback?next=${encodeURIComponent(safeRedirect)}`
|
|
54
|
-
: "/api/hazo_auth/oauth/facebook/callback";
|
|
55
54
|
const effectiveRedirectRoute = (_a = redirectRoute !== null && redirectRoute !== void 0 ? redirectRoute : safeRedirect) !== null && _a !== void 0 ? _a : undefined;
|
|
56
55
|
const getOAuthErrorMessage = (error) => {
|
|
57
56
|
switch (error) {
|
|
@@ -60,9 +59,7 @@ export default function login_layout({ theme, field_overrides, labels, button_co
|
|
|
60
59
|
case "OAuthSignin":
|
|
61
60
|
case "OAuthCallback":
|
|
62
61
|
case "OAuthCreateAccount":
|
|
63
|
-
return "Something went wrong with sign-in. Please try again.";
|
|
64
|
-
case "link_blocked_unverified":
|
|
65
|
-
return "This email is already registered but not verified. Please verify your email before linking a social account.";
|
|
62
|
+
return "Something went wrong with Google sign-in. Please try again.";
|
|
66
63
|
default:
|
|
67
64
|
return "An error occurred during sign-in. Please try again.";
|
|
68
65
|
}
|
|
@@ -101,7 +98,7 @@ export default function login_layout({ theme, field_overrides, labels, button_co
|
|
|
101
98
|
// into TwoColumnAuthLayout's `formContent`; in "form_only" mode it's returned
|
|
102
99
|
// as the entire output for the consumer to compose into their own chrome.
|
|
103
100
|
const successContent = (_jsxs(_Fragment, { children: [_jsx(FormHeader, { heading: resolvedLabels.heading, subHeading: resolvedLabels.subHeading }), _jsxs("div", { className: "cls_login_layout_success flex flex-col items-center justify-center gap-4 p-8 text-center", children: [_jsx(CheckCircle, { className: "cls_login_layout_success_icon h-16 w-16 text-green-600", "aria-hidden": "true" }), _jsx("p", { className: "cls_login_layout_success_message text-lg font-medium text-slate-900", children: successMessage })] })] }));
|
|
104
|
-
const mainContent = (_jsxs(_Fragment, { children: [_jsx(FormHeader, { heading: resolvedLabels.heading, subHeading: resolvedLabels.subHeading }), oauthError && (_jsxs("div", { className: "cls_login_layout_oauth_error flex items-center gap-2 rounded-md border border-red-200 bg-red-50 p-3 text-sm text-red-700", children: [_jsx(AlertCircle, { className: "h-4 w-4 shrink-0", "aria-hidden": "true" }), _jsx("span", { children: getOAuthErrorMessage(oauthError) })] })), oauthConfig.enable_google && (_jsx("div", { className: "cls_login_layout_oauth_section", children: _jsx(GoogleSignInButton, { label: oauthConfig.google_button_text, callbackUrl: oauthCallbackUrl }) })), oauthConfig.
|
|
101
|
+
const mainContent = (_jsxs(_Fragment, { children: [_jsx(FormHeader, { heading: resolvedLabels.heading, subHeading: resolvedLabels.subHeading }), oauthError && (_jsxs("div", { className: "cls_login_layout_oauth_error flex items-center gap-2 rounded-md border border-red-200 bg-red-50 p-3 text-sm text-red-700", children: [_jsx(AlertCircle, { className: "h-4 w-4 shrink-0", "aria-hidden": "true" }), _jsx("span", { children: getOAuthErrorMessage(oauthError) })] })), oauthConfig.enable_google && (_jsx("div", { className: "cls_login_layout_oauth_section", children: _jsx(GoogleSignInButton, { label: oauthConfig.google_button_text, callbackUrl: oauthCallbackUrl }) })), oauthConfig.enable_facebook_oauth && (_jsx("div", { className: "cls_login_layout_facebook_section", children: _jsx(FacebookSignInButton, { label: oauthConfig.facebook_button_text || "Continue with Facebook", callbackUrl: "/api/hazo_auth/oauth/facebook/callback" }) })), (oauthConfig.enable_google || oauthConfig.enable_facebook_oauth) && oauthConfig.enable_email_password && (_jsx(OAuthDivider, { text: oauthConfig.oauth_divider_text })), oauthConfig.enable_email_password && (_jsxs("form", { className: "cls_login_layout_form_fields flex flex-col gap-5", onSubmit: form.handleSubmit, "aria-label": "Login form", children: [renderFields(form), _jsx(FormActionButtons, { submitLabel: resolvedLabels.submitButton, cancelLabel: resolvedLabels.cancelButton, buttonPalette: resolvedButtonPalette, isSubmitDisabled: form.isSubmitDisabled, onCancel: form.handleCancel, submitAriaLabel: "Submit login form", cancelAriaLabel: "Cancel login form" }), ((forgot_password_path && forgot_password_label) || (show_create_account_link && create_account_path && create_account_label)) && (_jsxs("div", { className: "cls_login_layout_support_links flex flex-col gap-1 text-sm text-muted-foreground", children: [forgot_password_path && forgot_password_label && (_jsx(Link, { href: forgot_password_path, className: "cls_login_layout_forgot_password_link text-primary underline-offset-4 hover:underline", "aria-label": "Go to forgot password page", children: forgot_password_label })), show_create_account_link && create_account_path && create_account_label && (_jsx(Link, { href: create_account_path, className: "cls_login_layout_create_account_link text-primary underline-offset-4 hover:underline", "aria-label": "Go to create account page", children: create_account_label }))] }))] })), show_create_account_link && create_account_path && create_account_label && !oauthConfig.enable_email_password && (oauthConfig.enable_google || oauthConfig.enable_facebook_oauth) && (_jsx("div", { className: "cls_login_layout_support_links mt-4 text-center text-sm text-muted-foreground", children: _jsx(Link, { href: create_account_path, className: "cls_login_layout_create_account_link text-primary underline-offset-4 hover:underline", "aria-label": "Go to create account page", children: create_account_label }) }))] }));
|
|
105
102
|
// Form-only mode: return the content directly. Consumer is expected to wrap
|
|
106
103
|
// it in their own page/brand chrome. We deliberately skip AlreadyLoggedInGuard
|
|
107
104
|
// here — its 2-col fallback would defeat the purpose of form_only. Consumer
|
|
@@ -111,10 +108,10 @@ export default function login_layout({ theme, field_overrides, labels, button_co
|
|
|
111
108
|
}
|
|
112
109
|
// Two-column mode (default): success state.
|
|
113
110
|
if (form.isSuccess) {
|
|
114
|
-
return (_jsx(TwoColumnAuthLayout, {
|
|
111
|
+
return (_jsx(TwoColumnAuthLayout, { imageSrc: image_src, imageAlt: image_alt, imageBackgroundColor: image_background_color, formContent: successContent }));
|
|
115
112
|
}
|
|
116
113
|
// Two-column mode (default): main flow with already-logged-in guard.
|
|
117
|
-
return (_jsx(AlreadyLoggedInGuard, {
|
|
114
|
+
return (_jsx(AlreadyLoggedInGuard, { image_src: image_src, image_alt: image_alt, image_background_color: image_background_color, message: alreadyLoggedInMessage, showLogoutButton: showLogoutButton, showReturnHomeButton: showReturnHomeButton, returnHomeButtonLabel: returnHomeButtonLabel, returnHomePath: returnHomePath, children: _jsx(TwoColumnAuthLayout, { imageSrc: image_src, imageAlt: image_alt, imageBackgroundColor: image_background_color, formContent: mainContent }) }));
|
|
118
115
|
}
|
|
119
116
|
// Same-origin path validator for the `?redirect=` query param. Accepts
|
|
120
117
|
// values like "/foo" or "/foo?bar". Rejects anything that could redirect
|
|
@@ -11,7 +11,11 @@ export interface OTPLayoutProps {
|
|
|
11
11
|
ctaText?: string;
|
|
12
12
|
/** Theme that controls visual appearance and layout mode. */
|
|
13
13
|
theme?: HazoAuthTheme;
|
|
14
|
+
/** URL of the visual panel image. Defaults to the package default login image. */
|
|
15
|
+
image_src?: string;
|
|
16
|
+
/** Alt text for the visual panel image. */
|
|
17
|
+
image_alt?: string;
|
|
14
18
|
}
|
|
15
|
-
export declare function OTPLayout({ redirect_url, title, subtitle, ctaText, theme, }: OTPLayoutProps): React.ReactElement;
|
|
19
|
+
export declare function OTPLayout({ redirect_url, title, subtitle, ctaText, theme, image_src, image_alt, }: OTPLayoutProps): React.ReactElement;
|
|
16
20
|
export default OTPLayout;
|
|
17
21
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/layouts/otp/index.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAGhE,MAAM,WAAW,cAAc;IAC7B,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/layouts/otp/index.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAGhE,MAAM,WAAW,cAAc;IAC7B,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAGD,wBAAgB,SAAS,CAAC,EACxB,YAAkB,EAClB,KAAiC,EACjC,QAAQ,EACR,OAAO,EACP,KAAK,EACL,SAAiD,EACjD,SAA0C,GAC3C,EAAE,cAAc,GAAG,KAAK,CAAC,YAAY,CA4BrC;AAED,eAAe,SAAS,CAAC"}
|
|
@@ -8,9 +8,9 @@ import { OTPRequestForm } from "../../otp/OTPRequestForm.js";
|
|
|
8
8
|
import { OTPVerifyForm } from "../../otp/OTPVerifyForm.js";
|
|
9
9
|
import { TwoColumnAuthLayout } from "../shared/components/two_column_auth_layout.js";
|
|
10
10
|
// section: component
|
|
11
|
-
export function OTPLayout({ redirect_url = "/", title = "Sign in with email code", subtitle, ctaText, theme, }) {
|
|
11
|
+
export function OTPLayout({ redirect_url = "/", title = "Sign in with email code", subtitle, ctaText, theme, image_src = "/hazo_auth/images/login_default.jpg", image_alt = "Sign in with a one-time code", }) {
|
|
12
12
|
const [sent_to, set_sent_to] = React.useState(null);
|
|
13
13
|
const formContent = (_jsxs("div", { className: "mx-auto w-full max-w-sm py-12", children: [_jsx("h1", { className: `text-2xl font-semibold ${subtitle ? "mb-2" : "mb-6"}`, children: title }), subtitle && (_jsx("p", { className: "text-sm text-muted-foreground mb-6", children: subtitle })), sent_to ? (_jsx(OTPVerifyForm, { email: sent_to, redirect_url: redirect_url, submit_label: ctaText })) : (_jsx(OTPRequestForm, { on_sent: (email) => set_sent_to(email) }))] }));
|
|
14
|
-
return (_jsx(TwoColumnAuthLayout, {
|
|
14
|
+
return (_jsx(TwoColumnAuthLayout, { imageSrc: image_src, imageAlt: image_alt, formContent: formContent }));
|
|
15
15
|
}
|
|
16
16
|
export default OTPLayout;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { LayoutDataClient } from "../../shared/data/layout_data_client";
|
|
2
2
|
import type { PasswordRequirementOptions, PasswordRequirementOverrides } from "../../shared/config/layout_customization";
|
|
3
3
|
import { type RegisterFieldId } from "../config/register_field_config.js";
|
|
4
|
+
import type { LegalDoc } from "../../../../lib/legal/legal_docs_types";
|
|
4
5
|
export type RegisterFormValues = Record<RegisterFieldId, string>;
|
|
5
6
|
export type RegisterFormErrors = Partial<Record<RegisterFieldId, string | string[]>> & {
|
|
6
7
|
submit?: string;
|
|
@@ -12,6 +13,7 @@ export type UseRegisterFormParams<TClient = unknown> = {
|
|
|
12
13
|
passwordRequirementOverrides?: PasswordRequirementOverrides;
|
|
13
14
|
dataClient: LayoutDataClient<TClient>;
|
|
14
15
|
urlOnLogon?: string;
|
|
16
|
+
legalDocs?: LegalDoc[];
|
|
15
17
|
};
|
|
16
18
|
export type UseRegisterFormResult = {
|
|
17
19
|
values: RegisterFormValues;
|
|
@@ -25,6 +27,8 @@ export type UseRegisterFormResult = {
|
|
|
25
27
|
togglePasswordVisibility: (fieldId: "password" | "confirm_password") => void;
|
|
26
28
|
handleSubmit: (event: React.FormEvent<HTMLFormElement>) => void;
|
|
27
29
|
handleCancel: () => void;
|
|
30
|
+
legal_accepted: Record<string, boolean>;
|
|
31
|
+
handleLegalAcceptedChange: (key: string, value: boolean) => void;
|
|
28
32
|
};
|
|
29
|
-
export declare const use_register_form: <TClient>({ showNameField, passwordRequirements, dataClient, urlOnLogon, }: UseRegisterFormParams<TClient>) => UseRegisterFormResult;
|
|
33
|
+
export declare const use_register_form: <TClient>({ showNameField, passwordRequirements, dataClient, urlOnLogon, legalDocs, }: UseRegisterFormParams<TClient>) => UseRegisterFormResult;
|
|
30
34
|
//# sourceMappingURL=use_register_form.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use_register_form.d.ts","sourceRoot":"","sources":["../../../../../src/components/layouts/register/hooks/use_register_form.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAC7E,OAAO,KAAK,EAAE,0BAA0B,EAAE,4BAA4B,EAAE,MAAM,0CAA0C,CAAC;AACzH,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"use_register_form.d.ts","sourceRoot":"","sources":["../../../../../src/components/layouts/register/hooks/use_register_form.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAC7E,OAAO,KAAK,EAAE,0BAA0B,EAAE,4BAA4B,EAAE,MAAM,0CAA0C,CAAC;AACzH,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAG3F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wCAAwC,CAAC;AASvE,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;AACjE,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC,GAAG;IACrF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AACF,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAC1C,OAAO,CAAC,eAAe,EAAE,UAAU,GAAG,kBAAkB,CAAC,EACzD,OAAO,CACR,CAAC;AAEF,MAAM,MAAM,qBAAqB,CAAC,OAAO,GAAG,OAAO,IAAI;IACrD,aAAa,EAAE,OAAO,CAAC;IACvB,oBAAoB,EAAE,0BAA0B,CAAC;IACjD,4BAA4B,CAAC,EAAE,4BAA4B,CAAC;IAC5D,UAAU,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,kBAAkB,EAAE,uBAAuB,CAAC;IAC5C,gBAAgB,EAAE,OAAO,CAAC;IAC1B,YAAY,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,OAAO,CAAC;IACtB,iBAAiB,EAAE,CAAC,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrE,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,wBAAwB,EAAE,CAAC,OAAO,EAAE,UAAU,GAAG,kBAAkB,KAAK,IAAI,CAAC;IAC7E,YAAY,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,eAAe,CAAC,KAAK,IAAI,CAAC;IAChE,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,yBAAyB,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CAClE,CAAC;AAYF,eAAO,MAAM,iBAAiB,GAAI,OAAO,EAAG,6EAMzC,qBAAqB,CAAC,OAAO,CAAC,KAAG,qBA6QnC,CAAC"}
|
|
@@ -18,7 +18,7 @@ const buildInitialValues = () => ({
|
|
|
18
18
|
[REGISTER_FIELD_IDS.CONFIRM_PASSWORD]: "",
|
|
19
19
|
});
|
|
20
20
|
// section: hook
|
|
21
|
-
export const use_register_form = ({ showNameField, passwordRequirements, dataClient, urlOnLogon, }) => {
|
|
21
|
+
export const use_register_form = ({ showNameField, passwordRequirements, dataClient, urlOnLogon, legalDocs, }) => {
|
|
22
22
|
const { apiBasePath } = useHazoAuthConfig();
|
|
23
23
|
const initialValues = useMemo(() => buildInitialValues(), []);
|
|
24
24
|
const [values, setValues] = useState(initialValues);
|
|
@@ -29,6 +29,7 @@ export const use_register_form = ({ showNameField, passwordRequirements, dataCli
|
|
|
29
29
|
});
|
|
30
30
|
const [emailTouched, setEmailTouched] = useState(false);
|
|
31
31
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
32
|
+
const [legal_accepted, set_legal_accepted] = useState({});
|
|
32
33
|
// Check if form has been edited (changed from initial state)
|
|
33
34
|
const isFormEdited = useMemo(() => {
|
|
34
35
|
return Object.entries(values).some(([fieldId, fieldValue]) => {
|
|
@@ -64,9 +65,17 @@ export const use_register_form = ({ showNameField, passwordRequirements, dataCli
|
|
|
64
65
|
if (hasEmptyField) {
|
|
65
66
|
return true;
|
|
66
67
|
}
|
|
67
|
-
//
|
|
68
|
+
// Disable if any required legal document has not been accepted
|
|
69
|
+
const all_legal_accepted = (legalDocs !== null && legalDocs !== void 0 ? legalDocs : []).every(doc => legal_accepted[doc.key]);
|
|
70
|
+
if (!all_legal_accepted) {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
// Enable if form is edited, has no errors, all required fields are filled, and legal docs accepted
|
|
68
74
|
return false;
|
|
69
|
-
}, [errors, showNameField, values, isSubmitting, isFormEdited]);
|
|
75
|
+
}, [errors, showNameField, values, isSubmitting, isFormEdited, legal_accepted, legalDocs]);
|
|
76
|
+
const handleLegalAcceptedChange = useCallback((key, value) => {
|
|
77
|
+
set_legal_accepted(prev => (Object.assign(Object.assign({}, prev), { [key]: value })));
|
|
78
|
+
}, []);
|
|
70
79
|
const togglePasswordVisibility = useCallback((fieldId) => {
|
|
71
80
|
setPasswordVisibility((previous) => (Object.assign(Object.assign({}, previous), { [fieldId]: !previous[fieldId] })));
|
|
72
81
|
}, []);
|
|
@@ -143,17 +152,19 @@ export const use_register_form = ({ showNameField, passwordRequirements, dataCli
|
|
|
143
152
|
setIsSubmitting(true);
|
|
144
153
|
setErrors({});
|
|
145
154
|
try {
|
|
155
|
+
const legal_accepted_payload = legalDocs && legalDocs.length > 0
|
|
156
|
+
? Object.fromEntries(legalDocs
|
|
157
|
+
.filter(doc => legal_accepted[doc.key])
|
|
158
|
+
.map(doc => [doc.key, { hash: doc.hash }]))
|
|
159
|
+
: undefined;
|
|
146
160
|
const response = await fetch(`${apiBasePath}/register`, {
|
|
147
161
|
method: "POST",
|
|
148
162
|
headers: {
|
|
149
163
|
"Content-Type": "application/json",
|
|
150
164
|
},
|
|
151
|
-
body: JSON.stringify({
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
password: values[REGISTER_FIELD_IDS.PASSWORD],
|
|
155
|
-
url_on_logon: urlOnLogon,
|
|
156
|
-
}),
|
|
165
|
+
body: JSON.stringify(Object.assign({ name: values[REGISTER_FIELD_IDS.NAME] || undefined, email: values[REGISTER_FIELD_IDS.EMAIL], password: values[REGISTER_FIELD_IDS.PASSWORD], url_on_logon: urlOnLogon }, (legal_accepted_payload && Object.keys(legal_accepted_payload).length > 0
|
|
166
|
+
? { legal_accepted: legal_accepted_payload }
|
|
167
|
+
: {}))),
|
|
157
168
|
});
|
|
158
169
|
const data = await response.json();
|
|
159
170
|
if (!response.ok) {
|
|
@@ -172,6 +183,7 @@ export const use_register_form = ({ showNameField, passwordRequirements, dataCli
|
|
|
172
183
|
confirm_password: false,
|
|
173
184
|
});
|
|
174
185
|
setEmailTouched(false);
|
|
186
|
+
set_legal_accepted({});
|
|
175
187
|
}
|
|
176
188
|
catch (error) {
|
|
177
189
|
const errorMessage = error instanceof Error ? error.message : "Registration failed. Please try again.";
|
|
@@ -187,7 +199,7 @@ export const use_register_form = ({ showNameField, passwordRequirements, dataCli
|
|
|
187
199
|
finally {
|
|
188
200
|
setIsSubmitting(false);
|
|
189
201
|
}
|
|
190
|
-
}, [values, passwordRequirements, dataClient, urlOnLogon]);
|
|
202
|
+
}, [values, passwordRequirements, dataClient, urlOnLogon, legalDocs, legal_accepted]);
|
|
191
203
|
const handleCancel = useCallback(() => {
|
|
192
204
|
const resetValues = buildInitialValues();
|
|
193
205
|
setValues(resetValues);
|
|
@@ -197,6 +209,7 @@ export const use_register_form = ({ showNameField, passwordRequirements, dataCli
|
|
|
197
209
|
confirm_password: false,
|
|
198
210
|
});
|
|
199
211
|
setEmailTouched(false);
|
|
212
|
+
set_legal_accepted({});
|
|
200
213
|
}, []);
|
|
201
214
|
return {
|
|
202
215
|
values,
|
|
@@ -210,5 +223,7 @@ export const use_register_form = ({ showNameField, passwordRequirements, dataCli
|
|
|
210
223
|
togglePasswordVisibility,
|
|
211
224
|
handleSubmit,
|
|
212
225
|
handleCancel,
|
|
226
|
+
legal_accepted,
|
|
227
|
+
handleLegalAcceptedChange,
|
|
213
228
|
};
|
|
214
229
|
};
|
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
import { type ButtonPaletteOverrides, type LayoutFieldMapOverrides, type LayoutLabelOverrides, type PasswordRequirementOverrides } from "../shared/config/layout_customization.js";
|
|
2
2
|
import { type LayoutDataClient } from "../shared/data/layout_data_client.js";
|
|
3
|
-
import type {
|
|
4
|
-
import type { ReactNode } from "react";
|
|
3
|
+
import type { StaticImageData } from "next/image";
|
|
5
4
|
export type OAuthLayoutConfig = {
|
|
6
5
|
/** Enable Google OAuth login */
|
|
7
6
|
enable_google: boolean;
|
|
8
|
-
/** Enable Facebook OAuth login */
|
|
9
|
-
enable_facebook?: boolean;
|
|
10
7
|
/** Enable traditional email/password login */
|
|
11
8
|
enable_email_password: boolean;
|
|
12
9
|
/** Text displayed on the Google sign-in button */
|
|
13
10
|
google_button_text: string;
|
|
14
|
-
/** Text displayed on the Facebook sign-in button */
|
|
15
|
-
facebook_button_text?: string;
|
|
16
11
|
/** Text displayed on the divider between OAuth and email/password form */
|
|
17
12
|
oauth_divider_text: string;
|
|
13
|
+
/** Enable Facebook OAuth login */
|
|
14
|
+
enable_facebook_oauth?: boolean;
|
|
15
|
+
/** Text displayed on the Facebook sign-in button */
|
|
16
|
+
facebook_button_text?: string;
|
|
18
17
|
};
|
|
19
18
|
export type RegisterLayoutProps<TClient = unknown> = {
|
|
20
|
-
/**
|
|
21
|
-
|
|
19
|
+
/** Image source for the visual panel. Required when `layout` is `"two_column"` (the default); ignored when `"form_only"`. */
|
|
20
|
+
image_src?: string | StaticImageData;
|
|
21
|
+
/** Image alt text. Required when `layout` is `"two_column"` (the default); ignored when `"form_only"`. */
|
|
22
|
+
image_alt?: string;
|
|
23
|
+
image_background_color?: string;
|
|
22
24
|
field_overrides?: LayoutFieldMapOverrides;
|
|
23
25
|
labels?: LayoutLabelOverrides;
|
|
24
26
|
button_colors?: ButtonPaletteOverrides;
|
|
@@ -37,8 +39,6 @@ export type RegisterLayoutProps<TClient = unknown> = {
|
|
|
37
39
|
oauth?: OAuthLayoutConfig;
|
|
38
40
|
/** Layout mode (default: `"two_column"`). See `LoginLayoutProps.layout` for the full description. */
|
|
39
41
|
layout?: "two_column" | "form_only";
|
|
40
|
-
/** Optional legal text rendered below the form (accepts ReactNode for links/JSX) */
|
|
41
|
-
legalText?: ReactNode;
|
|
42
42
|
};
|
|
43
|
-
export default function register_layout<TClient>({
|
|
43
|
+
export default function register_layout<TClient>({ image_src, image_alt, image_background_color, field_overrides, labels, button_colors, password_requirements, show_name_field, data_client, alreadyLoggedInMessage, showLogoutButton, showReturnHomeButton, returnHomeButtonLabel, returnHomePath, signInPath, signInLabel, urlOnLogon, oauth, layout, }: RegisterLayoutProps<TClient>): import("react/jsx-runtime").JSX.Element;
|
|
44
44
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/layouts/register/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/layouts/register/index.tsx"],"names":[],"mappings":"AAmBA,OAAO,EACL,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EAClC,MAAM,uCAAuC,CAAC;AAY/C,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAOlD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,gCAAgC;IAChC,aAAa,EAAE,OAAO,CAAC;IACvB,8CAA8C;IAC9C,qBAAqB,EAAE,OAAO,CAAC;IAC/B,kDAAkD;IAClD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,0EAA0E;IAC1E,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kCAAkC;IAClC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,oDAAoD;IACpD,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,mBAAmB,CAAC,OAAO,GAAG,OAAO,IAAI;IACnD,6HAA6H;IAC7H,SAAS,CAAC,EAAE,MAAM,GAAG,eAAe,CAAC;IACrC,0GAA0G;IAC1G,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,eAAe,CAAC,EAAE,uBAAuB,CAAC;IAC1C,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,aAAa,CAAC,EAAE,sBAAsB,CAAC;IACvC,qBAAqB,CAAC,EAAE,4BAA4B,CAAC;IACrD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACvC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0BAA0B;IAC1B,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,qGAAqG;IACrG,MAAM,CAAC,EAAE,YAAY,GAAG,WAAW,CAAC;CACrC,CAAC;AAYF,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,OAAO,EAAE,EAC/C,SAAS,EACT,SAAS,EACT,sBAAkC,EAClC,eAAe,EACf,MAAM,EACN,aAAa,EACb,qBAAqB,EACrB,eAAsB,EACtB,WAAW,EACX,sBAAoD,EACpD,gBAAuB,EACvB,oBAA4B,EAC5B,qBAAqC,EACrC,cAAoB,EACpB,UAA+B,EAC/B,WAAuB,EACvB,UAAU,EACV,KAAK,EACL,MAAqB,GACtB,EAAE,mBAAmB,CAAC,OAAO,CAAC,2CAsR9B"}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"use client";
|
|
4
4
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
5
5
|
// section: imports
|
|
6
|
+
import { useState, useEffect } from "react";
|
|
6
7
|
import Link from "next/link";
|
|
7
8
|
import { useSearchParams } from "next/navigation";
|
|
8
9
|
import { Input } from "../../ui/input.js";
|
|
@@ -18,6 +19,9 @@ import { OAuthDivider } from "../shared/components/oauth_divider.js";
|
|
|
18
19
|
import { AlertCircle } from "lucide-react";
|
|
19
20
|
import { REGISTER_FIELD_IDS, createRegisterFieldDefinitions, resolveRegisterButtonPalette, resolveRegisterLabels, resolveRegisterPasswordRequirements, } from "./config/register_field_config.js";
|
|
20
21
|
import { use_register_form, } from "./hooks/use_register_form.js";
|
|
22
|
+
import { LegalDocCheckboxList } from "../legal/legal_doc_checkbox_list.js";
|
|
23
|
+
import { LegalDocCombinedView } from "../legal/legal_doc_combined_view.js";
|
|
24
|
+
import { useHazoAuthConfig } from "../../../contexts/hazo_auth_provider.js";
|
|
21
25
|
const ORDERED_FIELDS = [
|
|
22
26
|
REGISTER_FIELD_IDS.NAME,
|
|
23
27
|
REGISTER_FIELD_IDS.EMAIL,
|
|
@@ -25,14 +29,16 @@ const ORDERED_FIELDS = [
|
|
|
25
29
|
REGISTER_FIELD_IDS.CONFIRM_PASSWORD,
|
|
26
30
|
];
|
|
27
31
|
// section: component
|
|
28
|
-
export default function register_layout({
|
|
29
|
-
var _a
|
|
32
|
+
export default function register_layout({ image_src, image_alt, image_background_color = "#f1f5f9", field_overrides, labels, button_colors, password_requirements, show_name_field = true, data_client, alreadyLoggedInMessage = "You are already logged in", showLogoutButton = true, showReturnHomeButton = false, returnHomeButtonLabel = "Return home", returnHomePath = "/", signInPath = "/hazo_auth/login", signInLabel = "Sign in", urlOnLogon, oauth, layout = "two_column", }) {
|
|
33
|
+
var _a;
|
|
30
34
|
// Default OAuth config: both enabled
|
|
31
35
|
const oauthConfig = oauth || {
|
|
32
36
|
enable_google: true,
|
|
33
37
|
enable_email_password: true,
|
|
34
38
|
google_button_text: "Sign up with Google",
|
|
35
39
|
oauth_divider_text: "or continue with email",
|
|
40
|
+
enable_facebook_oauth: false,
|
|
41
|
+
facebook_button_text: "Continue with Facebook",
|
|
36
42
|
};
|
|
37
43
|
// Read OAuth error from URL query params (e.g., ?error=AccessDenied)
|
|
38
44
|
const searchParams = useSearchParams();
|
|
@@ -47,9 +53,6 @@ export default function register_layout({ theme, field_overrides, labels, button
|
|
|
47
53
|
const oauthCallbackUrl = safeRedirect
|
|
48
54
|
? `/api/hazo_auth/oauth/google/callback?next=${encodeURIComponent(safeRedirect)}`
|
|
49
55
|
: "/api/hazo_auth/oauth/google/callback";
|
|
50
|
-
const facebookCallbackUrl = safeRedirect
|
|
51
|
-
? `/api/hazo_auth/oauth/facebook/callback?next=${encodeURIComponent(safeRedirect)}`
|
|
52
|
-
: "/api/hazo_auth/oauth/facebook/callback";
|
|
53
56
|
const effectiveUrlOnLogon = (_a = urlOnLogon !== null && urlOnLogon !== void 0 ? urlOnLogon : safeRedirect) !== null && _a !== void 0 ? _a : undefined;
|
|
54
57
|
const getOAuthErrorMessage = (error) => {
|
|
55
58
|
switch (error) {
|
|
@@ -63,6 +66,21 @@ export default function register_layout({ theme, field_overrides, labels, button
|
|
|
63
66
|
return "An error occurred during sign-in. Please try again.";
|
|
64
67
|
}
|
|
65
68
|
};
|
|
69
|
+
const { apiBasePath } = useHazoAuthConfig();
|
|
70
|
+
const [legal_docs, set_legal_docs] = useState([]);
|
|
71
|
+
const [legal_display_mode, set_legal_display_mode] = useState('separate');
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
fetch(`${apiBasePath}/legal_docs`)
|
|
74
|
+
.then(r => r.json())
|
|
75
|
+
.then(result => {
|
|
76
|
+
var _a, _b;
|
|
77
|
+
if (result.ok && ((_b = (_a = result.data) === null || _a === void 0 ? void 0 : _a.docs) === null || _b === void 0 ? void 0 : _b.length) > 0) {
|
|
78
|
+
set_legal_docs(result.data.docs);
|
|
79
|
+
set_legal_display_mode(result.data.display_mode);
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
.catch(() => { });
|
|
83
|
+
}, [apiBasePath]);
|
|
66
84
|
const fieldDefinitions = createRegisterFieldDefinitions(field_overrides);
|
|
67
85
|
const resolvedLabels = resolveRegisterLabels(labels);
|
|
68
86
|
const resolvedButtonPalette = resolveRegisterButtonPalette(button_colors);
|
|
@@ -72,6 +90,7 @@ export default function register_layout({ theme, field_overrides, labels, button
|
|
|
72
90
|
passwordRequirements: resolvedPasswordRequirements,
|
|
73
91
|
dataClient: data_client,
|
|
74
92
|
urlOnLogon: effectiveUrlOnLogon,
|
|
93
|
+
legalDocs: legal_docs,
|
|
75
94
|
});
|
|
76
95
|
const renderFields = (formState) => {
|
|
77
96
|
const renderOrder = ORDERED_FIELDS.filter((fieldId) => show_name_field || fieldId !== REGISTER_FIELD_IDS.NAME);
|
|
@@ -99,13 +118,13 @@ export default function register_layout({ theme, field_overrides, labels, button
|
|
|
99
118
|
// Form content — used in both layout modes. See `login_layout` for the
|
|
100
119
|
// rationale: keeps the form independent of TwoColumnAuthLayout / AuthPageShell
|
|
101
120
|
// so consumers can compose it into their own brand chrome.
|
|
102
|
-
const mainContent = (_jsxs(_Fragment, { children: [_jsx(FormHeader, { heading: resolvedLabels.heading, subHeading: resolvedLabels.subHeading }), oauthError && (_jsxs("div", { className: "cls_register_layout_oauth_error flex items-center gap-2 rounded-md border border-red-200 bg-red-50 p-3 text-sm text-red-700", children: [_jsx(AlertCircle, { className: "h-4 w-4 shrink-0", "aria-hidden": "true" }), _jsx("span", { children: getOAuthErrorMessage(oauthError) })] })), oauthConfig.enable_google && (_jsx("div", { className: "cls_register_layout_oauth_section", children: _jsx(GoogleSignInButton, { label: oauthConfig.google_button_text, callbackUrl: oauthCallbackUrl }) })), oauthConfig.
|
|
121
|
+
const mainContent = (_jsxs(_Fragment, { children: [_jsx(FormHeader, { heading: resolvedLabels.heading, subHeading: resolvedLabels.subHeading }), oauthError && (_jsxs("div", { className: "cls_register_layout_oauth_error flex items-center gap-2 rounded-md border border-red-200 bg-red-50 p-3 text-sm text-red-700", children: [_jsx(AlertCircle, { className: "h-4 w-4 shrink-0", "aria-hidden": "true" }), _jsx("span", { children: getOAuthErrorMessage(oauthError) })] })), oauthConfig.enable_google && (_jsx("div", { className: "cls_register_layout_oauth_section", children: _jsx(GoogleSignInButton, { label: oauthConfig.google_button_text, callbackUrl: oauthCallbackUrl }) })), oauthConfig.enable_facebook_oauth && (_jsx("div", { className: "cls_register_layout_facebook_section", children: _jsx(FacebookSignInButton, { label: oauthConfig.facebook_button_text || "Continue with Facebook", callbackUrl: "/api/hazo_auth/oauth/facebook/callback" }) })), (oauthConfig.enable_google || oauthConfig.enable_facebook_oauth) && oauthConfig.enable_email_password && (_jsx(OAuthDivider, { text: oauthConfig.oauth_divider_text })), oauthConfig.enable_email_password && (_jsxs("form", { className: "cls_register_layout_form_fields flex flex-col gap-5", onSubmit: form.handleSubmit, "aria-label": "Registration form", children: [renderFields(form), legal_docs.length > 0 && (_jsx("div", { className: "space-y-2", children: legal_display_mode === 'combined' ? (_jsx(LegalDocCombinedView, { docs: legal_docs, accepted: legal_docs.every(doc => form.legal_accepted[doc.key]), onAcceptedChange: (value) => legal_docs.forEach(doc => form.handleLegalAcceptedChange(doc.key, value)) })) : (_jsx(LegalDocCheckboxList, { docs: legal_docs, accepted: form.legal_accepted, onAcceptedChange: form.handleLegalAcceptedChange })) })), _jsx(FormActionButtons, { submitLabel: resolvedLabels.submitButton, cancelLabel: resolvedLabels.cancelButton, buttonPalette: resolvedButtonPalette, isSubmitDisabled: form.isSubmitDisabled, onCancel: form.handleCancel, submitAriaLabel: "Submit registration form", cancelAriaLabel: "Cancel registration form" }), _jsxs("div", { className: "cls_register_layout_sign_in_link flex items-center justify-center gap-1 text-sm text-muted-foreground", children: [_jsx("span", { children: "Already have an account?" }), _jsx(Link, { href: signInPath, className: "cls_register_layout_sign_in_link_text text-primary underline-offset-4 hover:underline", "aria-label": "Go to sign in page", children: signInLabel })] }), form.isSubmitting && (_jsx("div", { className: "cls_register_submitting_indicator text-sm text-slate-600 text-center", children: "Registering..." }))] })), !oauthConfig.enable_email_password && (oauthConfig.enable_google || oauthConfig.enable_facebook_oauth) && (_jsxs("div", { className: "cls_register_layout_sign_in_link mt-4 flex items-center justify-center gap-1 text-sm text-muted-foreground", children: [_jsx("span", { children: "Already have an account?" }), _jsx(Link, { href: signInPath, className: "cls_register_layout_sign_in_link_text text-primary underline-offset-4 hover:underline", "aria-label": "Go to sign in page", children: signInLabel })] }))] }));
|
|
103
122
|
// form_only mode: emit just the form content. See login_layout for the
|
|
104
123
|
// rationale; AlreadyLoggedInGuard is intentionally skipped here.
|
|
105
124
|
if (layout === "form_only") {
|
|
106
125
|
return mainContent;
|
|
107
126
|
}
|
|
108
|
-
return (_jsx(AlreadyLoggedInGuard, {
|
|
127
|
+
return (_jsx(AlreadyLoggedInGuard, { image_src: image_src, image_alt: image_alt, image_background_color: image_background_color, message: alreadyLoggedInMessage, showLogoutButton: showLogoutButton, showReturnHomeButton: showReturnHomeButton, returnHomeButtonLabel: returnHomeButtonLabel, returnHomePath: returnHomePath, children: _jsx(TwoColumnAuthLayout, { imageSrc: image_src, imageAlt: image_alt, imageBackgroundColor: image_background_color, formContent: mainContent }) }));
|
|
109
128
|
}
|
|
110
129
|
// Same-origin path validator. See login/index.tsx for the rationale.
|
|
111
130
|
function isSafeRedirectPath(value) {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import type { StaticImageData } from "next/image";
|
|
1
2
|
import { type ButtonPaletteOverrides, type LayoutFieldMapOverrides, type LayoutLabelOverrides, type PasswordRequirementOverrides } from "../shared/config/layout_customization.js";
|
|
2
3
|
import { type LayoutDataClient } from "../shared/data/layout_data_client.js";
|
|
3
|
-
import type { HazoAuthTheme } from "../../../theme/theme_types";
|
|
4
4
|
export type ResetPasswordLayoutProps<TClient = unknown> = {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
image_src: string | StaticImageData;
|
|
6
|
+
image_alt: string;
|
|
7
|
+
image_background_color?: string;
|
|
7
8
|
field_overrides?: LayoutFieldMapOverrides;
|
|
8
9
|
labels?: LayoutLabelOverrides;
|
|
9
10
|
button_colors?: ButtonPaletteOverrides;
|
|
@@ -19,5 +20,5 @@ export type ResetPasswordLayoutProps<TClient = unknown> = {
|
|
|
19
20
|
loginPath?: string;
|
|
20
21
|
forgotPasswordPath?: string;
|
|
21
22
|
};
|
|
22
|
-
export default function reset_password_layout<TClient>({
|
|
23
|
+
export default function reset_password_layout<TClient>({ image_src, image_alt, image_background_color, field_overrides, labels, button_colors, password_requirements, data_client, alreadyLoggedInMessage, showLogoutButton, showReturnHomeButton, returnHomeButtonLabel, returnHomePath, errorMessage, successMessage, loginPath, forgotPasswordPath, }: ResetPasswordLayoutProps<TClient>): import("react/jsx-runtime").JSX.Element;
|
|
23
24
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/layouts/reset_password/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/layouts/reset_password/index.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAOlD,OAAO,EACL,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EAClC,MAAM,uCAAuC,CAAC;AAY/C,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAI1E,MAAM,MAAM,wBAAwB,CAAC,OAAO,GAAG,OAAO,IAAI;IACxD,SAAS,EAAE,MAAM,GAAG,eAAe,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,eAAe,CAAC,EAAE,uBAAuB,CAAC;IAC1C,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,aAAa,CAAC,EAAE,sBAAsB,CAAC;IACvC,qBAAqB,CAAC,EAAE,4BAA4B,CAAC;IACrD,WAAW,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACvC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC;AAUF,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAC,OAAO,EAAE,EACrD,SAAS,EACT,SAAS,EACT,sBAAkC,EAClC,eAAe,EACf,MAAM,EACN,aAAa,EACb,qBAAqB,EACrB,WAAW,EACX,sBAAsB,EACtB,gBAAuB,EACvB,oBAA4B,EAC5B,qBAAqC,EACrC,cAAoB,EACpB,YAAgH,EAChH,cAAuE,EACvE,SAA8B,EAC9B,kBAAiD,GAClD,EAAE,wBAAwB,CAAC,OAAO,CAAC,2CAqNnC"}
|
|
@@ -18,7 +18,7 @@ const ORDERED_FIELDS = [
|
|
|
18
18
|
RESET_PASSWORD_FIELD_IDS.CONFIRM_PASSWORD,
|
|
19
19
|
];
|
|
20
20
|
// section: component
|
|
21
|
-
export default function reset_password_layout({
|
|
21
|
+
export default function reset_password_layout({ image_src, image_alt, image_background_color = "#f1f5f9", field_overrides, labels, button_colors, password_requirements, data_client, alreadyLoggedInMessage, showLogoutButton = true, showReturnHomeButton = false, returnHomeButtonLabel = "Return home", returnHomePath = "/", errorMessage = "Reset password link invalid or has expired. Please go to Reset Password page to get a new link.", successMessage = "Password reset successfully. Redirecting to login...", loginPath = "/hazo_auth/login", forgotPasswordPath = "/hazo_auth/forgot_password", }) {
|
|
22
22
|
const fieldDefinitions = createResetPasswordFieldDefinitions(field_overrides);
|
|
23
23
|
const resolvedLabels = resolveResetPasswordLabels(labels);
|
|
24
24
|
const resolvedButtonPalette = resolveResetPasswordButtonPalette(button_colors);
|
|
@@ -39,15 +39,15 @@ export default function reset_password_layout({ theme, field_overrides, labels,
|
|
|
39
39
|
};
|
|
40
40
|
// Show success message if password reset was successful
|
|
41
41
|
if (form.isSuccess) {
|
|
42
|
-
return (_jsx(AlreadyLoggedInGuard, {
|
|
42
|
+
return (_jsx(AlreadyLoggedInGuard, { image_src: image_src, image_alt: image_alt, image_background_color: image_background_color, message: alreadyLoggedInMessage, showLogoutButton: showLogoutButton, showReturnHomeButton: showReturnHomeButton, returnHomeButtonLabel: returnHomeButtonLabel, returnHomePath: returnHomePath, children: _jsx(TwoColumnAuthLayout, { imageSrc: image_src, imageAlt: image_alt, imageBackgroundColor: image_background_color, formContent: _jsxs(_Fragment, { children: [_jsx(FormHeader, { heading: resolvedLabels.heading, subHeading: resolvedLabels.subHeading }), _jsxs("div", { className: "cls_reset_password_layout_success flex flex-col items-center justify-center gap-4 p-8 text-center", children: [_jsx(CheckCircle, { className: "cls_reset_password_layout_success_icon h-16 w-16 text-green-600", "aria-hidden": "true" }), _jsx("p", { className: "cls_reset_password_layout_success_message text-lg font-medium text-slate-900", children: successMessage })] })] }) }) }));
|
|
43
43
|
}
|
|
44
44
|
// Show loading state while validating token
|
|
45
45
|
if (form.isValidatingToken) {
|
|
46
|
-
return (_jsx(AlreadyLoggedInGuard, {
|
|
46
|
+
return (_jsx(AlreadyLoggedInGuard, { image_src: image_src, image_alt: image_alt, image_background_color: image_background_color, message: alreadyLoggedInMessage, showLogoutButton: showLogoutButton, showReturnHomeButton: showReturnHomeButton, returnHomeButtonLabel: returnHomeButtonLabel, returnHomePath: returnHomePath, children: _jsx(TwoColumnAuthLayout, { imageSrc: image_src, imageAlt: image_alt, imageBackgroundColor: image_background_color, formContent: _jsxs("div", { className: "cls_reset_password_layout_validating flex flex-col items-center justify-center gap-4 py-8", children: [_jsx(Loader2, { className: "h-12 w-12 animate-spin text-slate-600", "aria-hidden": "true" }), _jsxs("div", { className: "cls_reset_password_layout_validating_text text-center", children: [_jsx("h1", { className: "cls_reset_password_layout_validating_heading text-2xl font-semibold text-slate-900", children: resolvedLabels.heading }), _jsx("p", { className: "cls_reset_password_layout_validating_subheading mt-2 text-sm text-slate-600", children: "Validating reset token..." })] })] }) }) }));
|
|
47
47
|
}
|
|
48
48
|
// Show error message if token is invalid or missing
|
|
49
49
|
if (form.tokenError || !form.token) {
|
|
50
|
-
return (_jsx(AlreadyLoggedInGuard, {
|
|
50
|
+
return (_jsx(AlreadyLoggedInGuard, { image_src: image_src, image_alt: image_alt, image_background_color: image_background_color, message: alreadyLoggedInMessage, showLogoutButton: showLogoutButton, showReturnHomeButton: showReturnHomeButton, returnHomeButtonLabel: returnHomeButtonLabel, returnHomePath: returnHomePath, children: _jsx(TwoColumnAuthLayout, { imageSrc: image_src, imageAlt: image_alt, imageBackgroundColor: image_background_color, formContent: _jsxs("div", { className: "cls_reset_password_layout_error flex flex-col items-center justify-center gap-4 p-8 text-center", children: [_jsx(XCircle, { className: "cls_reset_password_layout_error_icon h-16 w-16 text-red-600", "aria-hidden": "true" }), _jsxs("div", { className: "cls_reset_password_layout_error_text", children: [_jsx("h1", { className: "cls_reset_password_layout_error_heading text-2xl font-semibold text-slate-900", children: "Invalid Reset Link" }), _jsx("p", { className: "cls_reset_password_layout_error_message mt-2 text-sm text-slate-600", children: form.tokenError || errorMessage })] }), _jsx(Link, { href: forgotPasswordPath, className: "cls_reset_password_layout_forgot_password_link mt-4 text-sm text-blue-600 hover:text-blue-800 underline", children: "Go to Reset Password page" })] }) }) }));
|
|
51
51
|
}
|
|
52
|
-
return (_jsx(AlreadyLoggedInGuard, {
|
|
52
|
+
return (_jsx(AlreadyLoggedInGuard, { image_src: image_src, image_alt: image_alt, image_background_color: image_background_color, message: alreadyLoggedInMessage, showLogoutButton: showLogoutButton, showReturnHomeButton: showReturnHomeButton, returnHomeButtonLabel: returnHomeButtonLabel, returnHomePath: returnHomePath, children: _jsx(TwoColumnAuthLayout, { imageSrc: image_src, imageAlt: image_alt, imageBackgroundColor: image_background_color, formContent: _jsxs(_Fragment, { children: [_jsx(FormHeader, { heading: resolvedLabels.heading, subHeading: resolvedLabels.subHeading }), _jsxs("form", { className: "cls_reset_password_layout_form_fields flex flex-col gap-5", onSubmit: form.handleSubmit, "aria-label": "Reset password form", children: [renderFields(form), _jsx(FormActionButtons, { submitLabel: resolvedLabels.submitButton, cancelLabel: resolvedLabels.cancelButton, buttonPalette: resolvedButtonPalette, isSubmitDisabled: form.isSubmitDisabled, onCancel: form.handleCancel, submitAriaLabel: "Submit reset password form", cancelAriaLabel: "Cancel reset password form" }), form.isSubmitting && (_jsx("div", { className: "cls_reset_password_layout_submitting_indicator text-sm text-slate-600 text-center", children: "Resetting password..." }))] })] }) }) }));
|
|
53
53
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { StaticImageData } from "next/image";
|
|
2
2
|
export type AlreadyLoggedInGuardProps = {
|
|
3
|
-
|
|
3
|
+
image_src: string | StaticImageData;
|
|
4
|
+
image_alt: string;
|
|
5
|
+
image_background_color?: string;
|
|
4
6
|
message?: string;
|
|
5
7
|
showLogoutButton?: boolean;
|
|
6
8
|
showReturnHomeButton?: boolean;
|
|
@@ -15,5 +17,5 @@ export type AlreadyLoggedInGuardProps = {
|
|
|
15
17
|
* @param props - Component props including layout config and message customization
|
|
16
18
|
* @returns Either the "already logged in" UI or the children
|
|
17
19
|
*/
|
|
18
|
-
export declare function AlreadyLoggedInGuard({
|
|
20
|
+
export declare function AlreadyLoggedInGuard({ image_src, image_alt, image_background_color, message, showLogoutButton, showReturnHomeButton, returnHomeButtonLabel, returnHomePath, requireEmailVerified, children, }: AlreadyLoggedInGuardProps): import("react/jsx-runtime").JSX.Element;
|
|
19
21
|
//# sourceMappingURL=already_logged_in_guard.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"already_logged_in_guard.d.ts","sourceRoot":"","sources":["../../../../../src/components/layouts/shared/components/already_logged_in_guard.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"already_logged_in_guard.d.ts","sourceRoot":"","sources":["../../../../../src/components/layouts/shared/components/already_logged_in_guard.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGlD,MAAM,MAAM,yBAAyB,GAAG;IACtC,SAAS,EAAE,MAAM,GAAG,eAAe,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC;AAGF;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,SAAS,EACT,SAAS,EACT,sBAAkC,EAClC,OAAqC,EACrC,gBAAuB,EACvB,oBAA4B,EAC5B,qBAAqC,EACrC,cAAoB,EACpB,oBAA4B,EAC5B,QAAQ,GACT,EAAE,yBAAyB,2CAiD3B"}
|
|
@@ -16,7 +16,7 @@ import { Home } from "lucide-react";
|
|
|
16
16
|
* @param props - Component props including layout config and message customization
|
|
17
17
|
* @returns Either the "already logged in" UI or the children
|
|
18
18
|
*/
|
|
19
|
-
export function AlreadyLoggedInGuard({
|
|
19
|
+
export function AlreadyLoggedInGuard({ image_src, image_alt, image_background_color = "#f1f5f9", message = "You're already logged in.", showLogoutButton = true, showReturnHomeButton = false, returnHomeButtonLabel = "Return home", returnHomePath = "/", requireEmailVerified = false, children, }) {
|
|
20
20
|
const router = useRouter();
|
|
21
21
|
const authStatus = use_auth_status();
|
|
22
22
|
// Check if user should see "already logged in" message
|
|
@@ -26,7 +26,7 @@ export function AlreadyLoggedInGuard({ theme, message = "You're already logged i
|
|
|
26
26
|
!authStatus.loading &&
|
|
27
27
|
(!requireEmailVerified || authStatus.email_verified === true);
|
|
28
28
|
if (shouldShowAlreadyLoggedIn) {
|
|
29
|
-
return (_jsx(TwoColumnAuthLayout, {
|
|
29
|
+
return (_jsx(TwoColumnAuthLayout, { imageSrc: image_src, imageAlt: image_alt, imageBackgroundColor: image_background_color, formContent: _jsxs("div", { className: "cls_already_logged_in_guard flex flex-col items-center justify-center gap-4 p-8 text-center", children: [_jsx("p", { className: "cls_already_logged_in_guard_message text-lg font-medium text-slate-900", children: message }), _jsxs("div", { className: "cls_already_logged_in_guard_actions flex flex-col gap-3 items-center mt-4", children: [showLogoutButton && (_jsx(LogoutButton, { className: "cls_already_logged_in_guard_logout_button", variant: "default" })), showReturnHomeButton && (_jsxs(Button, { onClick: () => router.push(returnHomePath), variant: "outline", className: "cls_already_logged_in_guard_return_home_button", "aria-label": returnHomeButtonLabel, children: [_jsx(Home, { className: "h-4 w-4 mr-2", "aria-hidden": "true" }), returnHomeButtonLabel] }))] })] }) }));
|
|
30
30
|
}
|
|
31
31
|
return _jsx(_Fragment, { children: children });
|
|
32
32
|
}
|
|
@@ -9,17 +9,13 @@ export type FacebookSignInButtonProps = {
|
|
|
9
9
|
className?: string;
|
|
10
10
|
/** Callback URL after OAuth (default: /api/hazo_auth/oauth/facebook/callback) */
|
|
11
11
|
callbackUrl?: string;
|
|
12
|
-
/** Pass enabled={false} to hide when Facebook OAuth is disabled */
|
|
13
|
-
enabled?: boolean;
|
|
14
12
|
};
|
|
15
13
|
/**
|
|
16
14
|
* Facebook Sign-In button component
|
|
17
|
-
* Displays the Facebook
|
|
15
|
+
* Displays the Facebook logo with configurable text
|
|
18
16
|
* Initiates the Facebook OAuth flow when clicked
|
|
19
17
|
* Uses next-auth/react signIn function for proper OAuth flow
|
|
20
|
-
* Pass `enabled={false}` to hide when Facebook OAuth is disabled.
|
|
21
|
-
* Returns null when Facebook OAuth is not enabled (enable_facebook=false or env vars absent)
|
|
22
18
|
*/
|
|
23
|
-
export declare function FacebookSignInButton({ label, onClick, disabled, className, callbackUrl,
|
|
19
|
+
export declare function FacebookSignInButton({ label, onClick, disabled, className, callbackUrl, }: FacebookSignInButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
24
20
|
export default FacebookSignInButton;
|
|
25
21
|
//# sourceMappingURL=facebook_sign_in_button.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"facebook_sign_in_button.d.ts","sourceRoot":"","sources":["../../../../../src/components/layouts/shared/components/facebook_sign_in_button.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"facebook_sign_in_button.d.ts","sourceRoot":"","sources":["../../../../../src/components/layouts/shared/components/facebook_sign_in_button.tsx"],"names":[],"mappings":"AAqBA,MAAM,MAAM,yBAAyB,GAAG;IACtC,mCAAmC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,yBAAyB;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iFAAiF;IACjF,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAGF;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,KAAgC,EAChC,OAAO,EACP,QAAgB,EAChB,SAAS,EACT,WAAsD,GACvD,EAAE,yBAAyB,2CA6C3B;AAED,eAAe,oBAAoB,CAAC"}
|