hazo_auth 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +383 -774
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +5 -0
- package/dist/components/layouts/email_verification/config/email_verification_field_config.d.ts +23 -0
- package/dist/components/layouts/email_verification/config/email_verification_field_config.d.ts.map +1 -0
- package/dist/components/layouts/email_verification/config/email_verification_field_config.js +44 -0
- package/dist/components/layouts/email_verification/hooks/use_email_verification.d.ts +31 -0
- package/dist/components/layouts/email_verification/hooks/use_email_verification.d.ts.map +1 -0
- package/dist/components/layouts/email_verification/hooks/use_email_verification.js +222 -0
- package/dist/components/layouts/email_verification/index.d.ts +23 -0
- package/dist/components/layouts/email_verification/index.d.ts.map +1 -0
- package/dist/components/layouts/email_verification/index.js +61 -0
- package/dist/components/layouts/forgot_password/config/forgot_password_field_config.d.ts +10 -0
- package/dist/components/layouts/forgot_password/config/forgot_password_field_config.d.ts.map +1 -0
- package/dist/components/layouts/forgot_password/config/forgot_password_field_config.js +33 -0
- package/dist/components/layouts/forgot_password/hooks/use_forgot_password_form.d.ts +22 -0
- package/dist/components/layouts/forgot_password/hooks/use_forgot_password_form.d.ts.map +1 -0
- package/dist/components/layouts/forgot_password/hooks/use_forgot_password_form.js +127 -0
- package/dist/components/layouts/forgot_password/index.d.ts +18 -0
- package/dist/components/layouts/forgot_password/index.d.ts.map +1 -0
- package/dist/components/layouts/forgot_password/index.js +43 -0
- package/dist/components/layouts/index.d.ts +16 -0
- package/dist/components/layouts/index.d.ts.map +1 -0
- package/dist/components/layouts/index.js +11 -0
- package/dist/components/layouts/login/config/login_field_config.d.ts +11 -0
- package/dist/components/layouts/login/config/login_field_config.d.ts.map +1 -0
- package/dist/components/layouts/login/config/login_field_config.js +42 -0
- package/dist/components/layouts/login/hooks/use_login_form.d.ts +34 -0
- package/dist/components/layouts/login/hooks/use_login_form.d.ts.map +1 -0
- package/dist/components/layouts/login/hooks/use_login_form.js +196 -0
- package/dist/components/layouts/login/index.d.ts +31 -0
- package/dist/components/layouts/login/index.d.ts.map +1 -0
- package/dist/components/layouts/login/index.js +58 -0
- package/dist/components/layouts/my_settings/components/editable_field.d.ts +19 -0
- package/dist/components/layouts/my_settings/components/editable_field.d.ts.map +1 -0
- package/dist/components/layouts/my_settings/components/editable_field.js +73 -0
- package/dist/components/layouts/my_settings/components/password_change_dialog.d.ts +28 -0
- package/dist/components/layouts/my_settings/components/password_change_dialog.d.ts.map +1 -0
- package/dist/components/layouts/my_settings/components/password_change_dialog.js +138 -0
- package/dist/components/layouts/my_settings/components/profile_picture_dialog.d.ts +42 -0
- package/dist/components/layouts/my_settings/components/profile_picture_dialog.d.ts.map +1 -0
- package/dist/components/layouts/my_settings/components/profile_picture_dialog.js +198 -0
- package/dist/components/layouts/my_settings/components/profile_picture_display.d.ts +16 -0
- package/dist/components/layouts/my_settings/components/profile_picture_display.d.ts.map +1 -0
- package/dist/components/layouts/my_settings/components/profile_picture_display.js +33 -0
- package/dist/components/layouts/my_settings/components/profile_picture_gravatar_tab.d.ts +17 -0
- package/dist/components/layouts/my_settings/components/profile_picture_gravatar_tab.d.ts.map +1 -0
- package/dist/components/layouts/my_settings/components/profile_picture_gravatar_tab.js +48 -0
- package/dist/components/layouts/my_settings/components/profile_picture_library_tab.d.ts +21 -0
- package/dist/components/layouts/my_settings/components/profile_picture_library_tab.d.ts.map +1 -0
- package/dist/components/layouts/my_settings/components/profile_picture_library_tab.js +144 -0
- package/dist/components/layouts/my_settings/components/profile_picture_upload_tab.d.ts +23 -0
- package/dist/components/layouts/my_settings/components/profile_picture_upload_tab.d.ts.map +1 -0
- package/dist/components/layouts/my_settings/components/profile_picture_upload_tab.js +169 -0
- package/dist/components/layouts/my_settings/config/my_settings_field_config.d.ts +19 -0
- package/dist/components/layouts/my_settings/config/my_settings_field_config.d.ts.map +1 -0
- package/dist/components/layouts/my_settings/config/my_settings_field_config.js +26 -0
- package/dist/components/layouts/my_settings/hooks/use_my_settings.d.ts +46 -0
- package/dist/components/layouts/my_settings/hooks/use_my_settings.d.ts.map +1 -0
- package/dist/components/layouts/my_settings/hooks/use_my_settings.js +354 -0
- package/dist/components/layouts/my_settings/index.d.ts +64 -0
- package/dist/components/layouts/my_settings/index.d.ts.map +1 -0
- package/dist/components/layouts/my_settings/index.js +65 -0
- package/dist/components/layouts/register/config/register_field_config.d.ts +14 -0
- package/dist/components/layouts/register/config/register_field_config.d.ts.map +1 -0
- package/dist/components/layouts/register/config/register_field_config.js +69 -0
- package/dist/components/layouts/register/hooks/use_register_form.d.ts +30 -0
- package/dist/components/layouts/register/hooks/use_register_form.d.ts.map +1 -0
- package/dist/components/layouts/register/hooks/use_register_form.js +184 -0
- package/dist/components/layouts/register/index.d.ts +23 -0
- package/dist/components/layouts/register/index.d.ts.map +1 -0
- package/dist/components/layouts/register/index.js +58 -0
- package/dist/components/layouts/reset_password/config/reset_password_field_config.d.ts +13 -0
- package/dist/components/layouts/reset_password/config/reset_password_field_config.d.ts.map +1 -0
- package/dist/components/layouts/reset_password/config/reset_password_field_config.js +53 -0
- package/dist/components/layouts/reset_password/hooks/use_reset_password_form.d.ts +28 -0
- package/dist/components/layouts/reset_password/hooks/use_reset_password_form.d.ts.map +1 -0
- package/dist/components/layouts/reset_password/hooks/use_reset_password_form.js +201 -0
- package/dist/components/layouts/reset_password/index.d.ts +23 -0
- package/dist/components/layouts/reset_password/index.d.ts.map +1 -0
- package/dist/components/layouts/reset_password/index.js +53 -0
- package/dist/components/layouts/shared/components/already_logged_in_guard.d.ts +20 -0
- package/dist/components/layouts/shared/components/already_logged_in_guard.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/already_logged_in_guard.js +32 -0
- package/dist/components/layouts/shared/components/auth_page_shell.d.ts +7 -0
- package/dist/components/layouts/shared/components/auth_page_shell.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/auth_page_shell.js +12 -0
- package/dist/components/layouts/shared/components/field_error_message.d.ts +7 -0
- package/dist/components/layouts/shared/components/field_error_message.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/field_error_message.js +6 -0
- package/dist/components/layouts/shared/components/form_action_buttons.d.ts +14 -0
- package/dist/components/layouts/shared/components/form_action_buttons.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/form_action_buttons.js +15 -0
- package/dist/components/layouts/shared/components/form_field_wrapper.d.ts +11 -0
- package/dist/components/layouts/shared/components/form_field_wrapper.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/form_field_wrapper.js +9 -0
- package/dist/components/layouts/shared/components/form_header.d.ts +10 -0
- package/dist/components/layouts/shared/components/form_header.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/form_header.js +5 -0
- package/dist/components/layouts/shared/components/logout_button.d.ts +7 -0
- package/dist/components/layouts/shared/components/logout_button.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/logout_button.js +44 -0
- package/dist/components/layouts/shared/components/password_field.d.ts +13 -0
- package/dist/components/layouts/shared/components/password_field.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/password_field.js +13 -0
- package/dist/components/layouts/shared/components/profile_pic_menu.d.ts +22 -0
- package/dist/components/layouts/shared/components/profile_pic_menu.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/profile_pic_menu.js +169 -0
- package/dist/components/layouts/shared/components/profile_pic_menu_wrapper.d.ts +12 -0
- package/dist/components/layouts/shared/components/profile_pic_menu_wrapper.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/profile_pic_menu_wrapper.js +16 -0
- package/dist/components/layouts/shared/components/sidebar_layout_wrapper.d.ts +6 -0
- package/dist/components/layouts/shared/components/sidebar_layout_wrapper.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/sidebar_layout_wrapper.js +15 -0
- package/dist/components/layouts/shared/components/standalone_layout_wrapper.d.ts +11 -0
- package/dist/components/layouts/shared/components/standalone_layout_wrapper.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/standalone_layout_wrapper.js +10 -0
- package/dist/components/layouts/shared/components/two_column_auth_layout.d.ts +12 -0
- package/dist/components/layouts/shared/components/two_column_auth_layout.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/two_column_auth_layout.js +8 -0
- package/dist/components/layouts/shared/components/unauthorized_guard.d.ts +14 -0
- package/dist/components/layouts/shared/components/unauthorized_guard.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/unauthorized_guard.js +30 -0
- package/dist/components/layouts/shared/components/visual_panel.d.ts +9 -0
- package/dist/components/layouts/shared/components/visual_panel.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/visual_panel.js +10 -0
- package/dist/components/layouts/shared/config/layout_customization.d.ts +38 -0
- package/dist/components/layouts/shared/config/layout_customization.d.ts.map +1 -0
- package/dist/components/layouts/shared/config/layout_customization.js +19 -0
- package/dist/components/layouts/shared/data/layout_data_client.d.ts +6 -0
- package/dist/components/layouts/shared/data/layout_data_client.d.ts.map +1 -0
- package/dist/components/layouts/shared/data/layout_data_client.js +9 -0
- package/dist/components/layouts/shared/hooks/use_auth_status.d.ts +20 -0
- package/dist/components/layouts/shared/hooks/use_auth_status.d.ts.map +1 -0
- package/dist/components/layouts/shared/hooks/use_auth_status.js +71 -0
- package/dist/components/layouts/shared/hooks/use_hazo_auth.d.ts +48 -0
- package/dist/components/layouts/shared/hooks/use_hazo_auth.d.ts.map +1 -0
- package/dist/components/layouts/shared/hooks/use_hazo_auth.js +90 -0
- package/dist/components/layouts/shared/index.d.ts +24 -0
- package/dist/components/layouts/shared/index.d.ts.map +1 -0
- package/dist/components/layouts/shared/index.js +27 -0
- package/dist/components/layouts/shared/utils/ip_address.d.ts +7 -0
- package/dist/components/layouts/shared/utils/ip_address.d.ts.map +1 -0
- package/dist/components/layouts/shared/utils/ip_address.js +34 -0
- package/dist/components/layouts/shared/utils/validation.d.ts +15 -0
- package/dist/components/layouts/shared/utils/validation.d.ts.map +1 -0
- package/dist/components/layouts/shared/utils/validation.js +45 -0
- package/dist/components/layouts/user_management/components/roles_matrix.d.ts +29 -0
- package/dist/components/layouts/user_management/components/roles_matrix.d.ts.map +1 -0
- package/dist/components/layouts/user_management/components/roles_matrix.js +287 -0
- package/dist/components/layouts/user_management/index.d.ts +13 -0
- package/dist/components/layouts/user_management/index.d.ts.map +1 -0
- package/dist/components/layouts/user_management/index.js +495 -0
- package/dist/components/ui/alert-dialog.d.ts +21 -0
- package/dist/components/ui/alert-dialog.d.ts.map +1 -0
- package/dist/components/ui/alert-dialog.js +62 -0
- package/dist/components/ui/avatar.d.ts +7 -0
- package/dist/components/ui/avatar.d.ts.map +1 -0
- package/dist/components/ui/avatar.js +32 -0
- package/dist/components/ui/button.d.ts +12 -0
- package/dist/components/ui/button.d.ts.map +1 -0
- package/dist/components/ui/button.js +45 -0
- package/dist/components/ui/checkbox.d.ts +5 -0
- package/dist/components/ui/checkbox.d.ts.map +1 -0
- package/dist/components/ui/checkbox.js +23 -0
- package/dist/components/ui/dialog.d.ts +20 -0
- package/dist/components/ui/dialog.d.ts.map +1 -0
- package/dist/components/ui/dialog.js +52 -0
- package/dist/components/ui/dropdown-menu.d.ts +28 -0
- package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
- package/dist/components/ui/dropdown-menu.js +72 -0
- package/dist/components/ui/hazo_ui_tooltip.d.ts +26 -0
- package/dist/components/ui/hazo_ui_tooltip.d.ts.map +1 -0
- package/dist/components/ui/hazo_ui_tooltip.js +17 -0
- package/dist/components/ui/index.d.ts +20 -0
- package/dist/components/ui/index.d.ts.map +1 -0
- package/dist/components/ui/index.js +21 -0
- package/dist/components/ui/input.d.ts +4 -0
- package/dist/components/ui/input.d.ts.map +1 -0
- package/dist/components/ui/input.js +20 -0
- package/dist/components/ui/label.d.ts +6 -0
- package/dist/components/ui/label.d.ts.map +1 -0
- package/dist/components/ui/label.js +24 -0
- package/dist/components/ui/separator.d.ts +5 -0
- package/dist/components/ui/separator.d.ts.map +1 -0
- package/dist/components/ui/separator.js +22 -0
- package/dist/components/ui/sheet.d.ts +23 -0
- package/dist/components/ui/sheet.d.ts.map +1 -0
- package/dist/components/ui/sheet.js +66 -0
- package/dist/components/ui/sidebar.d.ts +66 -0
- package/dist/components/ui/sidebar.d.ts.map +1 -0
- package/dist/components/ui/sidebar.js +267 -0
- package/dist/components/ui/skeleton.d.ts +3 -0
- package/dist/components/ui/skeleton.d.ts.map +1 -0
- package/dist/components/ui/skeleton.js +18 -0
- package/dist/components/ui/sonner.d.ts +5 -0
- package/dist/components/ui/sonner.d.ts.map +1 -0
- package/dist/components/ui/sonner.js +28 -0
- package/dist/components/ui/switch.d.ts +5 -0
- package/dist/components/ui/switch.d.ts.map +1 -0
- package/dist/components/ui/switch.js +22 -0
- package/dist/components/ui/table.d.ts +11 -0
- package/dist/components/ui/table.d.ts.map +1 -0
- package/dist/components/ui/table.js +55 -0
- package/dist/components/ui/tabs.d.ts +8 -0
- package/dist/components/ui/tabs.d.ts.map +1 -0
- package/dist/components/ui/tabs.js +33 -0
- package/dist/components/ui/tooltip.d.ts +8 -0
- package/dist/components/ui/tooltip.d.ts.map +1 -0
- package/dist/components/ui/tooltip.js +25 -0
- package/dist/components/ui/vertical-tabs.d.ts +8 -0
- package/dist/components/ui/vertical-tabs.d.ts.map +1 -0
- package/dist/components/ui/vertical-tabs.js +37 -0
- package/dist/hooks/use-mobile.d.ts +2 -0
- package/dist/hooks/use-mobile.d.ts.map +1 -0
- package/dist/hooks/use-mobile.js +15 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/lib/already_logged_in_config.server.d.ts +14 -0
- package/dist/lib/already_logged_in_config.server.d.ts.map +1 -0
- package/dist/lib/already_logged_in_config.server.js +29 -0
- package/dist/lib/app_logger.d.ts +12 -0
- package/dist/lib/app_logger.d.ts.map +1 -0
- package/dist/lib/app_logger.js +14 -0
- package/dist/lib/auth/auth_cache.d.ts +83 -0
- package/dist/lib/auth/auth_cache.d.ts.map +1 -0
- package/dist/lib/auth/auth_cache.js +158 -0
- package/dist/lib/auth/auth_rate_limiter.d.ts +39 -0
- package/dist/lib/auth/auth_rate_limiter.d.ts.map +1 -0
- package/dist/lib/auth/auth_rate_limiter.js +95 -0
- package/dist/lib/auth/auth_types.d.ts +53 -0
- package/dist/lib/auth/auth_types.d.ts.map +1 -0
- package/dist/lib/auth/auth_types.js +16 -0
- package/dist/lib/auth/auth_utils.server.d.ts +47 -0
- package/dist/lib/auth/auth_utils.server.d.ts.map +1 -0
- package/dist/lib/auth/auth_utils.server.js +150 -0
- package/dist/lib/auth/hazo_get_auth.server.d.ts +12 -0
- package/dist/lib/auth/hazo_get_auth.server.d.ts.map +1 -0
- package/dist/lib/auth/hazo_get_auth.server.js +256 -0
- package/dist/lib/auth/index.d.ts +9 -0
- package/dist/lib/auth/index.d.ts.map +1 -0
- package/dist/lib/auth/index.js +12 -0
- package/dist/lib/auth/server_auth.d.ts +26 -0
- package/dist/lib/auth/server_auth.d.ts.map +1 -0
- package/dist/lib/auth/server_auth.js +62 -0
- package/dist/lib/auth_utility_config.server.d.ts +20 -0
- package/dist/lib/auth_utility_config.server.d.ts.map +1 -0
- package/dist/lib/auth_utility_config.server.js +64 -0
- package/dist/lib/config/config_loader.server.d.ts +44 -0
- package/dist/lib/config/config_loader.server.d.ts.map +1 -0
- package/dist/lib/config/config_loader.server.js +122 -0
- package/dist/lib/email_verification_config.server.d.ts +14 -0
- package/dist/lib/email_verification_config.server.d.ts.map +1 -0
- package/dist/lib/email_verification_config.server.js +20 -0
- package/dist/lib/file_types_config.server.d.ts +11 -0
- package/dist/lib/file_types_config.server.d.ts.map +1 -0
- package/dist/lib/file_types_config.server.js +16 -0
- package/dist/lib/forgot_password_config.server.d.ts +14 -0
- package/dist/lib/forgot_password_config.server.d.ts.map +1 -0
- package/dist/lib/forgot_password_config.server.js +20 -0
- package/dist/lib/hazo_connect_instance.server.d.ts +17 -0
- package/dist/lib/hazo_connect_instance.server.d.ts.map +1 -0
- package/dist/lib/hazo_connect_instance.server.js +88 -0
- package/dist/lib/hazo_connect_setup.d.ts +2 -0
- package/dist/lib/hazo_connect_setup.d.ts.map +1 -0
- package/dist/lib/hazo_connect_setup.js +49 -0
- package/dist/lib/hazo_connect_setup.server.d.ts +20 -0
- package/dist/lib/hazo_connect_setup.server.d.ts.map +1 -0
- package/dist/lib/hazo_connect_setup.server.js +138 -0
- package/dist/lib/index.d.ts +28 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +35 -0
- package/dist/lib/login_config.server.d.ts +20 -0
- package/dist/lib/login_config.server.d.ts.map +1 -0
- package/dist/lib/login_config.server.js +37 -0
- package/dist/lib/messages_config.server.d.ts +13 -0
- package/dist/lib/messages_config.server.d.ts.map +1 -0
- package/dist/lib/messages_config.server.js +18 -0
- package/dist/lib/migrations/apply_migration.d.ts +22 -0
- package/dist/lib/migrations/apply_migration.d.ts.map +1 -0
- package/dist/lib/migrations/apply_migration.js +78 -0
- package/dist/lib/my_settings_config.server.d.ts +65 -0
- package/dist/lib/my_settings_config.server.d.ts.map +1 -0
- package/dist/lib/my_settings_config.server.js +67 -0
- package/dist/lib/password_requirements_config.server.d.ts +15 -0
- package/dist/lib/password_requirements_config.server.d.ts.map +1 -0
- package/dist/lib/password_requirements_config.server.js +26 -0
- package/dist/lib/profile_pic_menu_config.server.d.ts +26 -0
- package/dist/lib/profile_pic_menu_config.server.d.ts.map +1 -0
- package/dist/lib/profile_pic_menu_config.server.js +95 -0
- package/dist/lib/profile_picture_config.server.d.ts +16 -0
- package/dist/lib/profile_picture_config.server.d.ts.map +1 -0
- package/dist/lib/profile_picture_config.server.js +40 -0
- package/dist/lib/register_config.server.d.ts +24 -0
- package/dist/lib/register_config.server.d.ts.map +1 -0
- package/dist/lib/register_config.server.js +39 -0
- package/dist/lib/reset_password_config.server.d.ts +25 -0
- package/dist/lib/reset_password_config.server.d.ts.map +1 -0
- package/dist/lib/reset_password_config.server.js +38 -0
- package/dist/lib/services/email_service.d.ts +44 -0
- package/dist/lib/services/email_service.d.ts.map +1 -0
- package/dist/lib/services/email_service.js +480 -0
- package/dist/lib/services/email_verification_service.d.ts +35 -0
- package/dist/lib/services/email_verification_service.d.ts.map +1 -0
- package/dist/lib/services/email_verification_service.js +208 -0
- package/dist/lib/services/index.d.ts +13 -0
- package/dist/lib/services/index.d.ts.map +1 -0
- package/dist/lib/services/index.js +14 -0
- package/dist/lib/services/login_service.d.ts +20 -0
- package/dist/lib/services/login_service.d.ts.map +1 -0
- package/dist/lib/services/login_service.js +94 -0
- package/dist/lib/services/password_change_service.d.ts +19 -0
- package/dist/lib/services/password_change_service.d.ts.map +1 -0
- package/dist/lib/services/password_change_service.js +118 -0
- package/dist/lib/services/password_reset_service.d.ts +52 -0
- package/dist/lib/services/password_reset_service.d.ts.map +1 -0
- package/dist/lib/services/password_reset_service.js +318 -0
- package/dist/lib/services/profile_picture_remove_service.d.ts +15 -0
- package/dist/lib/services/profile_picture_remove_service.d.ts.map +1 -0
- package/dist/lib/services/profile_picture_remove_service.js +94 -0
- package/dist/lib/services/profile_picture_service.d.ts +45 -0
- package/dist/lib/services/profile_picture_service.d.ts.map +1 -0
- package/dist/lib/services/profile_picture_service.js +183 -0
- package/dist/lib/services/profile_picture_source_mapper.d.ts +23 -0
- package/dist/lib/services/profile_picture_source_mapper.d.ts.map +1 -0
- package/dist/lib/services/profile_picture_source_mapper.js +45 -0
- package/dist/lib/services/registration_service.d.ts +20 -0
- package/dist/lib/services/registration_service.d.ts.map +1 -0
- package/dist/lib/services/registration_service.js +147 -0
- package/dist/lib/services/token_service.d.ts +20 -0
- package/dist/lib/services/token_service.d.ts.map +1 -0
- package/dist/lib/services/token_service.js +201 -0
- package/dist/lib/services/user_profiles_service.d.ts +31 -0
- package/dist/lib/services/user_profiles_service.d.ts.map +1 -0
- package/dist/lib/services/user_profiles_service.js +99 -0
- package/dist/lib/services/user_update_service.d.ts +23 -0
- package/dist/lib/services/user_update_service.d.ts.map +1 -0
- package/dist/lib/services/user_update_service.js +103 -0
- package/dist/lib/ui_shell_config.server.d.ts +16 -0
- package/dist/lib/ui_shell_config.server.d.ts.map +1 -0
- package/dist/lib/ui_shell_config.server.js +28 -0
- package/dist/lib/ui_sizes_config.server.d.ts +17 -0
- package/dist/lib/ui_sizes_config.server.d.ts.map +1 -0
- package/dist/lib/ui_sizes_config.server.js +22 -0
- package/dist/lib/user_fields_config.server.d.ts +13 -0
- package/dist/lib/user_fields_config.server.d.ts.map +1 -0
- package/dist/lib/user_fields_config.server.js +21 -0
- package/dist/lib/user_management_config.server.d.ts +10 -0
- package/dist/lib/user_management_config.server.d.ts.map +1 -0
- package/dist/lib/user_management_config.server.js +26 -0
- package/dist/lib/utils/api_route_helpers.d.ts +13 -0
- package/dist/lib/utils/api_route_helpers.d.ts.map +1 -0
- package/dist/lib/utils/api_route_helpers.js +58 -0
- package/dist/lib/utils/error_sanitizer.d.ts +16 -0
- package/dist/lib/utils/error_sanitizer.d.ts.map +1 -0
- package/dist/lib/utils/error_sanitizer.js +39 -0
- package/dist/lib/utils.d.ts +4 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +9 -0
- package/dist/server/config/config_loader.d.ts +26 -0
- package/dist/server/config/config_loader.d.ts.map +1 -0
- package/dist/server/config/config_loader.js +329 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +32 -0
- package/dist/server/logging/logger_service.d.ts +3 -0
- package/dist/server/logging/logger_service.d.ts.map +1 -0
- package/dist/server/logging/logger_service.js +37 -0
- package/dist/server/routes/root_router.d.ts +3 -0
- package/dist/server/routes/root_router.d.ts.map +1 -0
- package/dist/server/routes/root_router.js +14 -0
- package/dist/server/server.d.ts +3 -0
- package/dist/server/server.d.ts.map +1 -0
- package/dist/server/server.js +25 -0
- package/dist/server/types/app_types.d.ts +53 -0
- package/dist/server/types/app_types.d.ts.map +1 -0
- package/dist/server/types/app_types.js +1 -0
- package/migrations/003_add_url_on_logon_to_hazo_users.sql +8 -0
- package/next.config.mjs +12 -0
- package/package.json +39 -2
- package/scripts/init_users.ts +9 -9
- package/src/components/index.ts +7 -0
- package/src/components/layouts/email_verification/config/email_verification_field_config.ts +2 -2
- package/src/components/layouts/email_verification/hooks/use_email_verification.ts +3 -3
- package/src/components/layouts/email_verification/index.tsx +11 -11
- package/src/components/layouts/forgot_password/config/forgot_password_field_config.ts +2 -2
- package/src/components/layouts/forgot_password/hooks/use_forgot_password_form.ts +3 -3
- package/src/components/layouts/forgot_password/index.tsx +10 -10
- package/src/components/layouts/index.ts +26 -0
- package/src/components/layouts/login/config/login_field_config.ts +2 -2
- package/src/components/layouts/login/hooks/use_login_form.ts +5 -5
- package/src/components/layouts/login/index.tsx +11 -11
- package/src/components/layouts/my_settings/components/editable_field.tsx +3 -3
- package/src/components/layouts/my_settings/components/password_change_dialog.tsx +5 -5
- package/src/components/layouts/my_settings/components/profile_picture_dialog.tsx +7 -7
- package/src/components/layouts/my_settings/components/profile_picture_display.tsx +2 -2
- package/src/components/layouts/my_settings/components/profile_picture_gravatar_tab.tsx +3 -3
- package/src/components/layouts/my_settings/components/profile_picture_library_tab.tsx +5 -5
- package/src/components/layouts/my_settings/components/profile_picture_upload_tab.tsx +4 -4
- package/src/components/layouts/my_settings/config/my_settings_field_config.ts +2 -2
- package/src/components/layouts/my_settings/hooks/use_my_settings.ts +2 -2
- package/src/components/layouts/my_settings/index.tsx +10 -10
- package/src/components/layouts/register/config/register_field_config.ts +2 -2
- package/src/components/layouts/register/hooks/use_register_form.ts +4 -4
- package/src/components/layouts/register/index.tsx +11 -11
- package/src/components/layouts/reset_password/config/reset_password_field_config.ts +2 -2
- package/src/components/layouts/reset_password/hooks/use_reset_password_form.ts +4 -4
- package/src/components/layouts/reset_password/index.tsx +10 -10
- package/src/components/layouts/shared/components/already_logged_in_guard.tsx +4 -4
- package/src/components/layouts/shared/components/auth_page_shell.tsx +3 -3
- package/src/components/layouts/shared/components/form_action_buttons.tsx +2 -2
- package/src/components/layouts/shared/components/form_field_wrapper.tsx +2 -2
- package/src/components/layouts/shared/components/logout_button.tsx +2 -2
- package/src/components/layouts/shared/components/password_field.tsx +3 -3
- package/src/components/layouts/shared/components/profile_pic_menu.tsx +5 -5
- package/src/components/layouts/shared/components/profile_pic_menu_wrapper.tsx +2 -2
- package/src/components/layouts/shared/components/sidebar_layout_wrapper.tsx +3 -3
- package/src/components/layouts/shared/components/standalone_layout_wrapper.tsx +1 -1
- package/src/components/layouts/shared/components/two_column_auth_layout.tsx +1 -1
- package/src/components/layouts/shared/components/unauthorized_guard.tsx +2 -2
- package/src/components/layouts/shared/hooks/use_hazo_auth.ts +1 -1
- package/src/components/layouts/shared/index.ts +34 -0
- package/src/components/layouts/shared/utils/validation.ts +1 -1
- package/src/components/layouts/user_management/components/roles_matrix.tsx +7 -7
- package/src/components/layouts/user_management/index.tsx +11 -11
- package/src/components/ui/alert-dialog.tsx +2 -2
- package/src/components/ui/avatar.tsx +1 -1
- package/src/components/ui/button.tsx +1 -1
- package/src/components/ui/checkbox.tsx +1 -1
- package/src/components/ui/dialog.tsx +1 -1
- package/src/components/ui/dropdown-menu.tsx +1 -1
- package/src/components/ui/hazo_ui_tooltip.tsx +1 -1
- package/src/components/ui/index.ts +22 -0
- package/src/components/ui/input.tsx +1 -1
- package/src/components/ui/label.tsx +1 -1
- package/src/components/ui/separator.tsx +1 -1
- package/src/components/ui/sheet.tsx +1 -1
- package/src/components/ui/sidebar.tsx +8 -8
- package/src/components/ui/skeleton.tsx +1 -1
- package/src/components/ui/switch.tsx +1 -1
- package/src/components/ui/table.tsx +1 -1
- package/src/components/ui/tabs.tsx +1 -1
- package/src/components/ui/tooltip.tsx +1 -1
- package/src/components/ui/vertical-tabs.tsx +1 -1
- package/src/index.ts +7 -0
- package/src/lib/already_logged_in_config.server.ts +1 -1
- package/src/lib/app_logger.ts +1 -1
- package/src/lib/auth/auth_cache.ts +1 -1
- package/src/lib/auth/auth_utils.server.ts +2 -2
- package/src/lib/auth/hazo_get_auth.server.ts +8 -8
- package/src/lib/auth/index.ts +23 -0
- package/src/lib/auth/server_auth.ts +2 -2
- package/src/lib/auth_utility_config.server.ts +1 -1
- package/src/lib/config/config_loader.server.ts +1 -1
- package/src/lib/email_verification_config.server.ts +1 -1
- package/src/lib/file_types_config.server.ts +1 -1
- package/src/lib/forgot_password_config.server.ts +1 -1
- package/src/lib/hazo_connect_instance.server.ts +2 -2
- package/src/lib/hazo_connect_setup.server.ts +2 -2
- package/src/lib/index.ts +44 -0
- package/src/lib/login_config.server.ts +2 -2
- package/src/lib/messages_config.server.ts +1 -1
- package/src/lib/my_settings_config.server.ts +7 -7
- package/src/lib/password_requirements_config.server.ts +1 -1
- package/src/lib/profile_pic_menu_config.server.ts +1 -1
- package/src/lib/profile_picture_config.server.ts +2 -2
- package/src/lib/register_config.server.ts +4 -4
- package/src/lib/reset_password_config.server.ts +3 -3
- package/src/lib/services/email_service.ts +2 -2
- package/src/lib/services/email_verification_service.ts +3 -3
- package/src/lib/services/index.ts +15 -0
- package/src/lib/services/login_service.ts +3 -3
- package/src/lib/services/password_change_service.ts +3 -3
- package/src/lib/services/password_reset_service.ts +3 -3
- package/src/lib/services/profile_picture_remove_service.ts +3 -3
- package/src/lib/services/profile_picture_service.ts +5 -5
- package/src/lib/services/registration_service.ts +8 -8
- package/src/lib/services/token_service.ts +2 -2
- package/src/lib/services/user_profiles_service.ts +2 -2
- package/src/lib/services/user_update_service.ts +4 -4
- package/src/lib/ui_shell_config.server.ts +1 -1
- package/src/lib/ui_sizes_config.server.ts +1 -1
- package/src/lib/user_fields_config.server.ts +1 -1
- package/src/lib/user_management_config.server.ts +1 -2
- package/src/lib/utils/error_sanitizer.ts +1 -1
- package/src/routes/index.ts +34 -0
- package/src/server/config/config_loader.ts +2 -2
- package/src/server/index.ts +2 -2
- package/src/server/logging/logger_service.ts +1 -1
- package/src/server/server.ts +2 -2
- package/src/server/types/express.d.ts +1 -1
- package/tsconfig.build.json +39 -0
- package/tsconfig.json +5 -1
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
// file_description: encapsulate register form state, validation, and data interactions
|
|
2
|
+
// section: imports
|
|
3
|
+
import { useCallback, useMemo, useState } from "react";
|
|
4
|
+
import { toast } from "sonner";
|
|
5
|
+
import { REGISTER_FIELD_IDS } from "hazo_auth/components/layouts/register/config/register_field_config";
|
|
6
|
+
import { validateEmail, validatePassword } from "hazo_auth/components/layouts/shared/utils/validation";
|
|
7
|
+
// section: constants
|
|
8
|
+
const PASSWORD_FIELDS = [
|
|
9
|
+
REGISTER_FIELD_IDS.PASSWORD,
|
|
10
|
+
REGISTER_FIELD_IDS.CONFIRM_PASSWORD,
|
|
11
|
+
];
|
|
12
|
+
// section: helpers
|
|
13
|
+
const buildInitialValues = () => ({
|
|
14
|
+
[REGISTER_FIELD_IDS.NAME]: "",
|
|
15
|
+
[REGISTER_FIELD_IDS.EMAIL]: "",
|
|
16
|
+
[REGISTER_FIELD_IDS.PASSWORD]: "",
|
|
17
|
+
[REGISTER_FIELD_IDS.CONFIRM_PASSWORD]: "",
|
|
18
|
+
});
|
|
19
|
+
// section: hook
|
|
20
|
+
export const use_register_form = ({ showNameField, passwordRequirements, dataClient, urlOnLogon, }) => {
|
|
21
|
+
const [values, setValues] = useState(buildInitialValues);
|
|
22
|
+
const [errors, setErrors] = useState({});
|
|
23
|
+
const [passwordVisibility, setPasswordVisibility] = useState({
|
|
24
|
+
password: false,
|
|
25
|
+
confirm_password: false,
|
|
26
|
+
});
|
|
27
|
+
const [emailTouched, setEmailTouched] = useState(false);
|
|
28
|
+
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
29
|
+
const isSubmitDisabled = useMemo(() => {
|
|
30
|
+
if (isSubmitting) {
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
const hasEmptyField = Object.entries(values).some(([fieldId, fieldValue]) => {
|
|
34
|
+
if (fieldId === REGISTER_FIELD_IDS.NAME && !showNameField) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
return fieldValue.trim() === "";
|
|
38
|
+
});
|
|
39
|
+
const hasErrors = Object.keys(errors).length > 0;
|
|
40
|
+
return hasEmptyField || hasErrors;
|
|
41
|
+
}, [errors, showNameField, values, isSubmitting]);
|
|
42
|
+
const togglePasswordVisibility = useCallback((fieldId) => {
|
|
43
|
+
setPasswordVisibility((previous) => (Object.assign(Object.assign({}, previous), { [fieldId]: !previous[fieldId] })));
|
|
44
|
+
}, []);
|
|
45
|
+
const handleFieldChange = useCallback((fieldId, value) => {
|
|
46
|
+
setValues((previousValues) => {
|
|
47
|
+
const nextValues = Object.assign(Object.assign({}, previousValues), { [fieldId]: value });
|
|
48
|
+
setErrors((previousErrors) => {
|
|
49
|
+
const updatedErrors = Object.assign({}, previousErrors);
|
|
50
|
+
// Only validate email on change if it has been touched (blurred)
|
|
51
|
+
if (fieldId === REGISTER_FIELD_IDS.EMAIL && emailTouched) {
|
|
52
|
+
const emailError = validateEmail(value);
|
|
53
|
+
if (emailError) {
|
|
54
|
+
updatedErrors[REGISTER_FIELD_IDS.EMAIL] = emailError;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
delete updatedErrors[REGISTER_FIELD_IDS.EMAIL];
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (PASSWORD_FIELDS.includes(fieldId)) {
|
|
61
|
+
const passwordError = validatePassword(nextValues[REGISTER_FIELD_IDS.PASSWORD], passwordRequirements);
|
|
62
|
+
if (passwordError) {
|
|
63
|
+
updatedErrors[REGISTER_FIELD_IDS.PASSWORD] = passwordError;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
delete updatedErrors[REGISTER_FIELD_IDS.PASSWORD];
|
|
67
|
+
}
|
|
68
|
+
if (nextValues[REGISTER_FIELD_IDS.CONFIRM_PASSWORD].trim().length > 0 &&
|
|
69
|
+
nextValues[REGISTER_FIELD_IDS.PASSWORD] !==
|
|
70
|
+
nextValues[REGISTER_FIELD_IDS.CONFIRM_PASSWORD]) {
|
|
71
|
+
updatedErrors[REGISTER_FIELD_IDS.CONFIRM_PASSWORD] = "passwords do not match";
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
delete updatedErrors[REGISTER_FIELD_IDS.CONFIRM_PASSWORD];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return updatedErrors;
|
|
78
|
+
});
|
|
79
|
+
return nextValues;
|
|
80
|
+
});
|
|
81
|
+
}, [passwordRequirements, emailTouched]);
|
|
82
|
+
const handleEmailBlur = useCallback(() => {
|
|
83
|
+
setEmailTouched(true);
|
|
84
|
+
// Validate email on blur
|
|
85
|
+
setErrors((previousErrors) => {
|
|
86
|
+
const updatedErrors = Object.assign({}, previousErrors);
|
|
87
|
+
const emailValue = values[REGISTER_FIELD_IDS.EMAIL];
|
|
88
|
+
const emailError = validateEmail(emailValue);
|
|
89
|
+
if (emailError) {
|
|
90
|
+
updatedErrors[REGISTER_FIELD_IDS.EMAIL] = emailError;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
delete updatedErrors[REGISTER_FIELD_IDS.EMAIL];
|
|
94
|
+
}
|
|
95
|
+
return updatedErrors;
|
|
96
|
+
});
|
|
97
|
+
}, [values]);
|
|
98
|
+
const handleSubmit = useCallback(async (event) => {
|
|
99
|
+
event.preventDefault();
|
|
100
|
+
// Final validation
|
|
101
|
+
const emailError = validateEmail(values[REGISTER_FIELD_IDS.EMAIL]);
|
|
102
|
+
const passwordError = validatePassword(values[REGISTER_FIELD_IDS.PASSWORD], passwordRequirements);
|
|
103
|
+
if (emailError || passwordError) {
|
|
104
|
+
setErrors(Object.assign(Object.assign({}, (emailError ? { [REGISTER_FIELD_IDS.EMAIL]: emailError } : {})), (passwordError ? { [REGISTER_FIELD_IDS.PASSWORD]: passwordError } : {})));
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
// Check password match
|
|
108
|
+
if (values[REGISTER_FIELD_IDS.PASSWORD] !==
|
|
109
|
+
values[REGISTER_FIELD_IDS.CONFIRM_PASSWORD]) {
|
|
110
|
+
setErrors({
|
|
111
|
+
[REGISTER_FIELD_IDS.CONFIRM_PASSWORD]: "passwords do not match",
|
|
112
|
+
});
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
setIsSubmitting(true);
|
|
116
|
+
setErrors({});
|
|
117
|
+
try {
|
|
118
|
+
const response = await fetch("/api/hazo_auth/register", {
|
|
119
|
+
method: "POST",
|
|
120
|
+
headers: {
|
|
121
|
+
"Content-Type": "application/json",
|
|
122
|
+
},
|
|
123
|
+
body: JSON.stringify({
|
|
124
|
+
name: values[REGISTER_FIELD_IDS.NAME] || undefined,
|
|
125
|
+
email: values[REGISTER_FIELD_IDS.EMAIL],
|
|
126
|
+
password: values[REGISTER_FIELD_IDS.PASSWORD],
|
|
127
|
+
url_on_logon: urlOnLogon,
|
|
128
|
+
}),
|
|
129
|
+
});
|
|
130
|
+
const data = await response.json();
|
|
131
|
+
if (!response.ok) {
|
|
132
|
+
throw new Error(data.error || "Registration failed");
|
|
133
|
+
}
|
|
134
|
+
// Show success notification
|
|
135
|
+
toast.success("Registration successful!", {
|
|
136
|
+
description: "Your account has been created successfully.",
|
|
137
|
+
});
|
|
138
|
+
// Reset form on success
|
|
139
|
+
setValues(buildInitialValues());
|
|
140
|
+
setErrors({});
|
|
141
|
+
setPasswordVisibility({
|
|
142
|
+
password: false,
|
|
143
|
+
confirm_password: false,
|
|
144
|
+
});
|
|
145
|
+
setEmailTouched(false);
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
const errorMessage = error instanceof Error ? error.message : "Registration failed. Please try again.";
|
|
149
|
+
// Show error notification
|
|
150
|
+
toast.error("Registration failed", {
|
|
151
|
+
description: errorMessage,
|
|
152
|
+
});
|
|
153
|
+
// Set error state
|
|
154
|
+
setErrors({
|
|
155
|
+
submit: errorMessage,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
finally {
|
|
159
|
+
setIsSubmitting(false);
|
|
160
|
+
}
|
|
161
|
+
}, [values, passwordRequirements, dataClient, urlOnLogon]);
|
|
162
|
+
const handleCancel = useCallback(() => {
|
|
163
|
+
setValues(buildInitialValues());
|
|
164
|
+
setErrors({});
|
|
165
|
+
setPasswordVisibility({
|
|
166
|
+
password: false,
|
|
167
|
+
confirm_password: false,
|
|
168
|
+
});
|
|
169
|
+
setEmailTouched(false);
|
|
170
|
+
}, []);
|
|
171
|
+
return {
|
|
172
|
+
values,
|
|
173
|
+
errors,
|
|
174
|
+
passwordVisibility,
|
|
175
|
+
isSubmitDisabled,
|
|
176
|
+
isSubmitting,
|
|
177
|
+
emailTouched,
|
|
178
|
+
handleFieldChange,
|
|
179
|
+
handleEmailBlur,
|
|
180
|
+
togglePasswordVisibility,
|
|
181
|
+
handleSubmit,
|
|
182
|
+
handleCancel,
|
|
183
|
+
};
|
|
184
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type ButtonPaletteOverrides, type LayoutFieldMapOverrides, type LayoutLabelOverrides, type PasswordRequirementOverrides } from "hazo_auth/components/layouts/shared/config/layout_customization";
|
|
2
|
+
import { type LayoutDataClient } from "hazo_auth/components/layouts/shared/data/layout_data_client";
|
|
3
|
+
export type RegisterLayoutProps<TClient = unknown> = {
|
|
4
|
+
image_src: string;
|
|
5
|
+
image_alt: string;
|
|
6
|
+
image_background_color?: string;
|
|
7
|
+
field_overrides?: LayoutFieldMapOverrides;
|
|
8
|
+
labels?: LayoutLabelOverrides;
|
|
9
|
+
button_colors?: ButtonPaletteOverrides;
|
|
10
|
+
password_requirements?: PasswordRequirementOverrides;
|
|
11
|
+
show_name_field?: boolean;
|
|
12
|
+
data_client: LayoutDataClient<TClient>;
|
|
13
|
+
alreadyLoggedInMessage?: string;
|
|
14
|
+
showLogoutButton?: boolean;
|
|
15
|
+
showReturnHomeButton?: boolean;
|
|
16
|
+
returnHomeButtonLabel?: string;
|
|
17
|
+
returnHomePath?: string;
|
|
18
|
+
signInPath?: string;
|
|
19
|
+
signInLabel?: string;
|
|
20
|
+
urlOnLogon?: string;
|
|
21
|
+
};
|
|
22
|
+
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, }: RegisterLayoutProps<TClient>): import("react/jsx-runtime").JSX.Element;
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/layouts/register/index.tsx"],"names":[],"mappings":"AAaA,OAAO,EACL,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EAClC,MAAM,iEAAiE,CAAC;AAYzE,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,6DAA6D,CAAC;AAGpG,MAAM,MAAM,mBAAmB,CAAC,OAAO,GAAG,OAAO,IAAI;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,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,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;CACrB,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,GACX,EAAE,mBAAmB,CAAC,OAAO,CAAC,2CA+I9B"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// file_description: register layout component built atop shared layout utilities
|
|
2
|
+
// section: client_directive
|
|
3
|
+
"use client";
|
|
4
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
5
|
+
// section: imports
|
|
6
|
+
import Link from "next/link";
|
|
7
|
+
import { Input } from "hazo_auth/components/ui/input";
|
|
8
|
+
import { PasswordField } from "hazo_auth/components/layouts/shared/components/password_field";
|
|
9
|
+
import { FormFieldWrapper } from "hazo_auth/components/layouts/shared/components/form_field_wrapper";
|
|
10
|
+
import { FormHeader } from "hazo_auth/components/layouts/shared/components/form_header";
|
|
11
|
+
import { FormActionButtons } from "hazo_auth/components/layouts/shared/components/form_action_buttons";
|
|
12
|
+
import { TwoColumnAuthLayout } from "hazo_auth/components/layouts/shared/components/two_column_auth_layout";
|
|
13
|
+
import { AlreadyLoggedInGuard } from "hazo_auth/components/layouts/shared/components/already_logged_in_guard";
|
|
14
|
+
import { REGISTER_FIELD_IDS, createRegisterFieldDefinitions, resolveRegisterButtonPalette, resolveRegisterLabels, resolveRegisterPasswordRequirements, } from "hazo_auth/components/layouts/register/config/register_field_config";
|
|
15
|
+
import { use_register_form, } from "hazo_auth/components/layouts/register/hooks/use_register_form";
|
|
16
|
+
const ORDERED_FIELDS = [
|
|
17
|
+
REGISTER_FIELD_IDS.NAME,
|
|
18
|
+
REGISTER_FIELD_IDS.EMAIL,
|
|
19
|
+
REGISTER_FIELD_IDS.PASSWORD,
|
|
20
|
+
REGISTER_FIELD_IDS.CONFIRM_PASSWORD,
|
|
21
|
+
];
|
|
22
|
+
// section: component
|
|
23
|
+
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, }) {
|
|
24
|
+
const fieldDefinitions = createRegisterFieldDefinitions(field_overrides);
|
|
25
|
+
const resolvedLabels = resolveRegisterLabels(labels);
|
|
26
|
+
const resolvedButtonPalette = resolveRegisterButtonPalette(button_colors);
|
|
27
|
+
const resolvedPasswordRequirements = resolveRegisterPasswordRequirements(password_requirements);
|
|
28
|
+
const form = use_register_form({
|
|
29
|
+
showNameField: show_name_field,
|
|
30
|
+
passwordRequirements: resolvedPasswordRequirements,
|
|
31
|
+
dataClient: data_client,
|
|
32
|
+
urlOnLogon: urlOnLogon,
|
|
33
|
+
});
|
|
34
|
+
const renderFields = (formState) => {
|
|
35
|
+
const renderOrder = ORDERED_FIELDS.filter((fieldId) => show_name_field || fieldId !== REGISTER_FIELD_IDS.NAME);
|
|
36
|
+
return renderOrder.map((fieldId) => {
|
|
37
|
+
const fieldDefinition = fieldDefinitions[fieldId];
|
|
38
|
+
const fieldValue = formState.values[fieldId];
|
|
39
|
+
const fieldError = formState.errors[fieldId];
|
|
40
|
+
const isPasswordField = fieldDefinition.type === "password" &&
|
|
41
|
+
(fieldId === REGISTER_FIELD_IDS.PASSWORD ||
|
|
42
|
+
fieldId === REGISTER_FIELD_IDS.CONFIRM_PASSWORD);
|
|
43
|
+
const inputElement = isPasswordField ? (_jsx(PasswordField, { inputId: fieldDefinition.id, ariaLabel: fieldDefinition.ariaLabel, value: fieldValue, placeholder: fieldDefinition.placeholder, autoComplete: fieldDefinition.autoComplete, isVisible: formState.passwordVisibility[fieldDefinition.id], onChange: (nextValue) => formState.handleFieldChange(fieldId, nextValue), onToggleVisibility: () => formState.togglePasswordVisibility(fieldDefinition.id), errorMessage: fieldError })) : (_jsx(Input, { id: fieldDefinition.id, type: fieldDefinition.type, value: fieldValue, onChange: (event) => formState.handleFieldChange(fieldId, event.target.value), onBlur: fieldId === REGISTER_FIELD_IDS.EMAIL
|
|
44
|
+
? formState.handleEmailBlur
|
|
45
|
+
: undefined, autoComplete: fieldDefinition.autoComplete, placeholder: fieldDefinition.placeholder, "aria-label": fieldDefinition.ariaLabel, className: "cls_register_layout_field_input" }));
|
|
46
|
+
// Only show email error if field has been touched (blurred)
|
|
47
|
+
const shouldShowError = isPasswordField
|
|
48
|
+
? undefined
|
|
49
|
+
: fieldId === REGISTER_FIELD_IDS.EMAIL
|
|
50
|
+
? formState.emailTouched && fieldError
|
|
51
|
+
? fieldError
|
|
52
|
+
: undefined
|
|
53
|
+
: fieldError;
|
|
54
|
+
return (_jsx(FormFieldWrapper, { fieldId: fieldDefinition.id, label: fieldDefinition.label, input: inputElement, errorMessage: shouldShowError }, fieldId));
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
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_register_layout_form_fields flex flex-col gap-5", onSubmit: form.handleSubmit, "aria-label": "Registration form", children: [renderFields(form), _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..." }))] })] }) }) }));
|
|
58
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { LayoutFieldMap, LayoutFieldMapOverrides } from "hazo_auth/components/layouts/shared/config/layout_customization";
|
|
2
|
+
import { type ButtonPaletteDefaults, type ButtonPaletteOverrides, type LayoutLabelDefaults, type LayoutLabelOverrides, type PasswordRequirementOptions, type PasswordRequirementOverrides } from "hazo_auth/components/layouts/shared/config/layout_customization";
|
|
3
|
+
export declare const RESET_PASSWORD_FIELD_IDS: {
|
|
4
|
+
readonly PASSWORD: "password";
|
|
5
|
+
readonly CONFIRM_PASSWORD: "confirm_password";
|
|
6
|
+
};
|
|
7
|
+
export type ResetPasswordFieldId = (typeof RESET_PASSWORD_FIELD_IDS)[keyof typeof RESET_PASSWORD_FIELD_IDS];
|
|
8
|
+
export declare const createResetPasswordFieldDefinitions: (overrides?: LayoutFieldMapOverrides) => LayoutFieldMap;
|
|
9
|
+
export declare const resolveResetPasswordLabels: (overrides?: LayoutLabelOverrides) => LayoutLabelDefaults;
|
|
10
|
+
export declare const resolveResetPasswordButtonPalette: (overrides?: ButtonPaletteOverrides) => ButtonPaletteDefaults;
|
|
11
|
+
export declare const resolveResetPasswordPasswordRequirements: (overrides?: PasswordRequirementOverrides) => PasswordRequirementOptions;
|
|
12
|
+
export declare const RESET_PASSWORD_ALREADY_LOGGED_IN_MESSAGE_DEFAULT = "You're already logged in.";
|
|
13
|
+
//# sourceMappingURL=reset_password_field_config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reset_password_field_config.d.ts","sourceRoot":"","sources":["../../../../../src/components/layouts/reset_password/config/reset_password_field_config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,iEAAiE,CAAC;AAC/H,OAAO,EAIL,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,4BAA4B,EAElC,MAAM,iEAAiE,CAAC;AAGzE,eAAO,MAAM,wBAAwB;;;CAG3B,CAAC;AAEX,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,OAAO,wBAAwB,CAAC,CAAC;AAsB5G,eAAO,MAAM,mCAAmC,GAC9C,YAAY,uBAAuB,mBACoC,CAAC;AAU1E,eAAO,MAAM,0BAA0B,GAAI,YAAY,oBAAoB,wBAClB,CAAC;AAU1D,eAAO,MAAM,iCAAiC,GAAI,YAAY,sBAAsB,0BACX,CAAC;AAW1E,eAAO,MAAM,wCAAwC,GACnD,YAAY,4BAA4B,+BAC+C,CAAC;AAG1F,eAAO,MAAM,gDAAgD,8BAA8B,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { resolveButtonPalette, resolveFieldDefinitions, resolveLabels, resolvePasswordRequirements, } from "hazo_auth/components/layouts/shared/config/layout_customization";
|
|
2
|
+
// section: field_identifiers
|
|
3
|
+
export const RESET_PASSWORD_FIELD_IDS = {
|
|
4
|
+
PASSWORD: "password",
|
|
5
|
+
CONFIRM_PASSWORD: "confirm_password",
|
|
6
|
+
};
|
|
7
|
+
// section: field_definitions
|
|
8
|
+
const RESET_PASSWORD_FIELD_DEFINITIONS = {
|
|
9
|
+
[RESET_PASSWORD_FIELD_IDS.PASSWORD]: {
|
|
10
|
+
id: RESET_PASSWORD_FIELD_IDS.PASSWORD,
|
|
11
|
+
label: "New password",
|
|
12
|
+
type: "password",
|
|
13
|
+
autoComplete: "new-password",
|
|
14
|
+
placeholder: "Enter your new password",
|
|
15
|
+
ariaLabel: "New password input field",
|
|
16
|
+
},
|
|
17
|
+
[RESET_PASSWORD_FIELD_IDS.CONFIRM_PASSWORD]: {
|
|
18
|
+
id: RESET_PASSWORD_FIELD_IDS.CONFIRM_PASSWORD,
|
|
19
|
+
label: "Confirm new password",
|
|
20
|
+
type: "password",
|
|
21
|
+
autoComplete: "new-password",
|
|
22
|
+
placeholder: "Re-enter your new password",
|
|
23
|
+
ariaLabel: "Confirm new password input field",
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
export const createResetPasswordFieldDefinitions = (overrides) => resolveFieldDefinitions(RESET_PASSWORD_FIELD_DEFINITIONS, overrides);
|
|
27
|
+
// section: label_defaults
|
|
28
|
+
const RESET_PASSWORD_LABEL_DEFAULTS = {
|
|
29
|
+
heading: "Reset your password",
|
|
30
|
+
subHeading: "Enter your new password below.",
|
|
31
|
+
submitButton: "Reset password",
|
|
32
|
+
cancelButton: "Cancel",
|
|
33
|
+
};
|
|
34
|
+
export const resolveResetPasswordLabels = (overrides) => resolveLabels(RESET_PASSWORD_LABEL_DEFAULTS, overrides);
|
|
35
|
+
// section: button_palette_defaults
|
|
36
|
+
const RESET_PASSWORD_BUTTON_PALETTE_DEFAULTS = {
|
|
37
|
+
submitBackground: "#0f172a",
|
|
38
|
+
submitText: "#ffffff",
|
|
39
|
+
cancelBorder: "#cbd5f5",
|
|
40
|
+
cancelText: "#0f172a",
|
|
41
|
+
};
|
|
42
|
+
export const resolveResetPasswordButtonPalette = (overrides) => resolveButtonPalette(RESET_PASSWORD_BUTTON_PALETTE_DEFAULTS, overrides);
|
|
43
|
+
// section: password_requirements_defaults
|
|
44
|
+
const RESET_PASSWORD_PASSWORD_REQUIREMENT_DEFAULTS = {
|
|
45
|
+
minimum_length: 8,
|
|
46
|
+
require_uppercase: false,
|
|
47
|
+
require_lowercase: false,
|
|
48
|
+
require_number: false,
|
|
49
|
+
require_special: false,
|
|
50
|
+
};
|
|
51
|
+
export const resolveResetPasswordPasswordRequirements = (overrides) => resolvePasswordRequirements(RESET_PASSWORD_PASSWORD_REQUIREMENT_DEFAULTS, overrides);
|
|
52
|
+
// section: already_logged_in_label
|
|
53
|
+
export const RESET_PASSWORD_ALREADY_LOGGED_IN_MESSAGE_DEFAULT = "You're already logged in.";
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { LayoutDataClient } from "hazo_auth/components/layouts/shared/data/layout_data_client";
|
|
2
|
+
import type { PasswordRequirementOptions } from "hazo_auth/components/layouts/shared/config/layout_customization";
|
|
3
|
+
import { type ResetPasswordFieldId } from "hazo_auth/components/layouts/reset_password/config/reset_password_field_config";
|
|
4
|
+
export type ResetPasswordFormValues = Record<ResetPasswordFieldId, string>;
|
|
5
|
+
export type ResetPasswordFormErrors = Partial<Record<ResetPasswordFieldId, string | string[]>>;
|
|
6
|
+
export type PasswordVisibilityState = Record<Extract<ResetPasswordFieldId, "password" | "confirm_password">, boolean>;
|
|
7
|
+
export type UseResetPasswordFormParams<TClient = unknown> = {
|
|
8
|
+
passwordRequirements: PasswordRequirementOptions;
|
|
9
|
+
dataClient: LayoutDataClient<TClient>;
|
|
10
|
+
loginPath?: string;
|
|
11
|
+
};
|
|
12
|
+
export type UseResetPasswordFormResult = {
|
|
13
|
+
values: ResetPasswordFormValues;
|
|
14
|
+
errors: ResetPasswordFormErrors;
|
|
15
|
+
passwordVisibility: PasswordVisibilityState;
|
|
16
|
+
isSubmitDisabled: boolean;
|
|
17
|
+
isSubmitting: boolean;
|
|
18
|
+
isSuccess: boolean;
|
|
19
|
+
token: string | null;
|
|
20
|
+
isValidatingToken: boolean;
|
|
21
|
+
tokenError: string | null;
|
|
22
|
+
handleFieldChange: (fieldId: ResetPasswordFieldId, value: string) => void;
|
|
23
|
+
togglePasswordVisibility: (fieldId: "password" | "confirm_password") => void;
|
|
24
|
+
handleSubmit: (event: React.FormEvent<HTMLFormElement>) => void;
|
|
25
|
+
handleCancel: () => void;
|
|
26
|
+
};
|
|
27
|
+
export declare const use_reset_password_form: <TClient>({ passwordRequirements, dataClient, loginPath, }: UseResetPasswordFormParams<TClient>) => UseResetPasswordFormResult;
|
|
28
|
+
//# sourceMappingURL=use_reset_password_form.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use_reset_password_form.d.ts","sourceRoot":"","sources":["../../../../../src/components/layouts/reset_password/hooks/use_reset_password_form.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6DAA6D,CAAC;AACpG,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,iEAAiE,CAAC;AAClH,OAAO,EAA4B,KAAK,oBAAoB,EAAE,MAAM,gFAAgF,CAAC;AAUrJ,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;AAC3E,MAAM,MAAM,uBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,oBAAoB,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC;AAC/F,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAC1C,OAAO,CAAC,oBAAoB,EAAE,UAAU,GAAG,kBAAkB,CAAC,EAC9D,OAAO,CACR,CAAC;AAEF,MAAM,MAAM,0BAA0B,CAAC,OAAO,GAAG,OAAO,IAAI;IAC1D,oBAAoB,EAAE,0BAA0B,CAAC;IACjD,UAAU,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,MAAM,EAAE,uBAAuB,CAAC;IAChC,MAAM,EAAE,uBAAuB,CAAC;IAChC,kBAAkB,EAAE,uBAAuB,CAAC;IAC5C,gBAAgB,EAAE,OAAO,CAAC;IAC1B,YAAY,EAAE,OAAO,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,iBAAiB,EAAE,CAAC,OAAO,EAAE,oBAAoB,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1E,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;CAC1B,CAAC;AASF,eAAO,MAAM,uBAAuB,GAAI,OAAO,EAAG,kDAI/C,0BAA0B,CAAC,OAAO,CAAC,KAAG,0BAyNxC,CAAC"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
// file_description: encapsulate reset password form state, validation, and data interactions
|
|
2
|
+
// section: imports
|
|
3
|
+
import { useCallback, useMemo, useState, useEffect } from "react";
|
|
4
|
+
import { useSearchParams, useRouter } from "next/navigation";
|
|
5
|
+
import { toast } from "sonner";
|
|
6
|
+
import { RESET_PASSWORD_FIELD_IDS } from "hazo_auth/components/layouts/reset_password/config/reset_password_field_config";
|
|
7
|
+
import { validatePassword } from "hazo_auth/components/layouts/shared/utils/validation";
|
|
8
|
+
// section: constants
|
|
9
|
+
const PASSWORD_FIELDS = [
|
|
10
|
+
RESET_PASSWORD_FIELD_IDS.PASSWORD,
|
|
11
|
+
RESET_PASSWORD_FIELD_IDS.CONFIRM_PASSWORD,
|
|
12
|
+
];
|
|
13
|
+
// section: helpers
|
|
14
|
+
const buildInitialValues = () => ({
|
|
15
|
+
[RESET_PASSWORD_FIELD_IDS.PASSWORD]: "",
|
|
16
|
+
[RESET_PASSWORD_FIELD_IDS.CONFIRM_PASSWORD]: "",
|
|
17
|
+
});
|
|
18
|
+
// section: hook
|
|
19
|
+
export const use_reset_password_form = ({ passwordRequirements, dataClient, loginPath = "/hazo_auth/login", }) => {
|
|
20
|
+
const router = useRouter();
|
|
21
|
+
const searchParams = useSearchParams();
|
|
22
|
+
const tokenParam = searchParams.get("token");
|
|
23
|
+
const [values, setValues] = useState(buildInitialValues);
|
|
24
|
+
const [errors, setErrors] = useState({});
|
|
25
|
+
const [passwordVisibility, setPasswordVisibility] = useState({
|
|
26
|
+
password: false,
|
|
27
|
+
confirm_password: false,
|
|
28
|
+
});
|
|
29
|
+
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
30
|
+
const [isSuccess, setIsSuccess] = useState(false);
|
|
31
|
+
const [token, setToken] = useState(tokenParam);
|
|
32
|
+
const [isValidatingToken, setIsValidatingToken] = useState(false);
|
|
33
|
+
const [tokenError, setTokenError] = useState(null);
|
|
34
|
+
// Validate token on mount
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
if (!tokenParam) {
|
|
37
|
+
setTokenError("Reset password link invalid or has expired. Please go to Reset Password page to get a new link.");
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
// Validate token by calling validation API
|
|
41
|
+
const validateToken = async () => {
|
|
42
|
+
setIsValidatingToken(true);
|
|
43
|
+
setTokenError(null);
|
|
44
|
+
try {
|
|
45
|
+
const response = await fetch(`/api/hazo_auth/validate_reset_token?token=${encodeURIComponent(tokenParam)}`, {
|
|
46
|
+
method: "GET",
|
|
47
|
+
});
|
|
48
|
+
const data = await response.json();
|
|
49
|
+
if (!response.ok || !data.success) {
|
|
50
|
+
const errorMessage = data.error || "Reset password link invalid or has expired. Please go to Reset Password page to get a new link.";
|
|
51
|
+
setTokenError(errorMessage);
|
|
52
|
+
setToken(null);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
// Token is valid
|
|
56
|
+
setToken(tokenParam);
|
|
57
|
+
setTokenError(null);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
const errorMessage = error instanceof Error ? error.message : "An error occurred while validating the token";
|
|
62
|
+
setTokenError("Reset password link invalid or has expired. Please go to Reset Password page to get a new link.");
|
|
63
|
+
setToken(null);
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
setIsValidatingToken(false);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
void validateToken();
|
|
70
|
+
}, [tokenParam]);
|
|
71
|
+
const isSubmitDisabled = useMemo(() => {
|
|
72
|
+
if (isSubmitting || isSuccess || !token || tokenError) {
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
const hasEmptyField = Object.values(values).some((value) => value.trim() === "");
|
|
76
|
+
if (hasEmptyField) {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
return Object.keys(errors).length > 0;
|
|
80
|
+
}, [isSubmitting, isSuccess, token, tokenError, values, errors]);
|
|
81
|
+
const handleFieldChange = useCallback((fieldId, value) => {
|
|
82
|
+
setValues((prev) => (Object.assign(Object.assign({}, prev), { [fieldId]: value })));
|
|
83
|
+
// Clear error for this field when user starts typing
|
|
84
|
+
if (errors[fieldId]) {
|
|
85
|
+
setErrors((prev) => {
|
|
86
|
+
const next = Object.assign({}, prev);
|
|
87
|
+
delete next[fieldId];
|
|
88
|
+
return next;
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
// Validate password fields in real-time
|
|
92
|
+
if (fieldId === RESET_PASSWORD_FIELD_IDS.PASSWORD) {
|
|
93
|
+
const passwordError = validatePassword(value, passwordRequirements);
|
|
94
|
+
if (passwordError) {
|
|
95
|
+
setErrors((prev) => (Object.assign(Object.assign({}, prev), { [RESET_PASSWORD_FIELD_IDS.PASSWORD]: passwordError })));
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
setErrors((prev) => {
|
|
99
|
+
const next = Object.assign({}, prev);
|
|
100
|
+
delete next[RESET_PASSWORD_FIELD_IDS.PASSWORD];
|
|
101
|
+
return next;
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
// Also validate confirm password if it has a value
|
|
105
|
+
if (values[RESET_PASSWORD_FIELD_IDS.CONFIRM_PASSWORD]) {
|
|
106
|
+
if (value !== values[RESET_PASSWORD_FIELD_IDS.CONFIRM_PASSWORD]) {
|
|
107
|
+
setErrors((prev) => (Object.assign(Object.assign({}, prev), { [RESET_PASSWORD_FIELD_IDS.CONFIRM_PASSWORD]: "Passwords do not match" })));
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
setErrors((prev) => {
|
|
111
|
+
const next = Object.assign({}, prev);
|
|
112
|
+
delete next[RESET_PASSWORD_FIELD_IDS.CONFIRM_PASSWORD];
|
|
113
|
+
return next;
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else if (fieldId === RESET_PASSWORD_FIELD_IDS.CONFIRM_PASSWORD) {
|
|
119
|
+
if (value !== values[RESET_PASSWORD_FIELD_IDS.PASSWORD]) {
|
|
120
|
+
setErrors((prev) => (Object.assign(Object.assign({}, prev), { [RESET_PASSWORD_FIELD_IDS.CONFIRM_PASSWORD]: "Passwords do not match" })));
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
setErrors((prev) => {
|
|
124
|
+
const next = Object.assign({}, prev);
|
|
125
|
+
delete next[RESET_PASSWORD_FIELD_IDS.CONFIRM_PASSWORD];
|
|
126
|
+
return next;
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}, [errors, passwordRequirements, values]);
|
|
131
|
+
const togglePasswordVisibility = useCallback((fieldId) => {
|
|
132
|
+
setPasswordVisibility((prev) => (Object.assign(Object.assign({}, prev), { [fieldId]: !prev[fieldId] })));
|
|
133
|
+
}, []);
|
|
134
|
+
const handleSubmit = useCallback(async (event) => {
|
|
135
|
+
event.preventDefault();
|
|
136
|
+
if (!token) {
|
|
137
|
+
toast.error("Reset token is missing");
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
// Validate all fields
|
|
141
|
+
const passwordError = validatePassword(values[RESET_PASSWORD_FIELD_IDS.PASSWORD], passwordRequirements);
|
|
142
|
+
const confirmPasswordError = values[RESET_PASSWORD_FIELD_IDS.PASSWORD] !== values[RESET_PASSWORD_FIELD_IDS.CONFIRM_PASSWORD]
|
|
143
|
+
? "Passwords do not match"
|
|
144
|
+
: undefined;
|
|
145
|
+
if (passwordError || confirmPasswordError) {
|
|
146
|
+
setErrors(Object.assign(Object.assign({}, (passwordError ? { [RESET_PASSWORD_FIELD_IDS.PASSWORD]: passwordError } : {})), (confirmPasswordError ? { [RESET_PASSWORD_FIELD_IDS.CONFIRM_PASSWORD]: confirmPasswordError } : {})));
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
setIsSubmitting(true);
|
|
150
|
+
try {
|
|
151
|
+
const response = await fetch("/api/hazo_auth/reset_password", {
|
|
152
|
+
method: "POST",
|
|
153
|
+
headers: {
|
|
154
|
+
"Content-Type": "application/json",
|
|
155
|
+
},
|
|
156
|
+
body: JSON.stringify({
|
|
157
|
+
token,
|
|
158
|
+
new_password: values[RESET_PASSWORD_FIELD_IDS.PASSWORD],
|
|
159
|
+
}),
|
|
160
|
+
});
|
|
161
|
+
const data = await response.json();
|
|
162
|
+
if (!response.ok || !data.success) {
|
|
163
|
+
const errorMessage = data.error || "Failed to reset password";
|
|
164
|
+
toast.error(errorMessage);
|
|
165
|
+
setTokenError(errorMessage);
|
|
166
|
+
setIsSubmitting(false);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
toast.success(data.message || "Password reset successfully");
|
|
170
|
+
setIsSuccess(true);
|
|
171
|
+
// Redirect to login after a short delay
|
|
172
|
+
setTimeout(() => {
|
|
173
|
+
router.push(loginPath);
|
|
174
|
+
}, 2000);
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
const errorMessage = error instanceof Error ? error.message : "An error occurred";
|
|
178
|
+
toast.error(errorMessage);
|
|
179
|
+
setTokenError(errorMessage);
|
|
180
|
+
setIsSubmitting(false);
|
|
181
|
+
}
|
|
182
|
+
}, [token, values, passwordRequirements, router, loginPath]);
|
|
183
|
+
const handleCancel = useCallback(() => {
|
|
184
|
+
router.push(loginPath);
|
|
185
|
+
}, [router, loginPath]);
|
|
186
|
+
return {
|
|
187
|
+
values,
|
|
188
|
+
errors,
|
|
189
|
+
passwordVisibility,
|
|
190
|
+
isSubmitDisabled,
|
|
191
|
+
isSubmitting,
|
|
192
|
+
isSuccess,
|
|
193
|
+
token,
|
|
194
|
+
isValidatingToken,
|
|
195
|
+
tokenError,
|
|
196
|
+
handleFieldChange,
|
|
197
|
+
togglePasswordVisibility,
|
|
198
|
+
handleSubmit,
|
|
199
|
+
handleCancel,
|
|
200
|
+
};
|
|
201
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type ButtonPaletteOverrides, type LayoutFieldMapOverrides, type LayoutLabelOverrides, type PasswordRequirementOverrides } from "hazo_auth/components/layouts/shared/config/layout_customization";
|
|
2
|
+
import { type LayoutDataClient } from "hazo_auth/components/layouts/shared/data/layout_data_client";
|
|
3
|
+
export type ResetPasswordLayoutProps<TClient = unknown> = {
|
|
4
|
+
image_src: string;
|
|
5
|
+
image_alt: string;
|
|
6
|
+
image_background_color?: string;
|
|
7
|
+
field_overrides?: LayoutFieldMapOverrides;
|
|
8
|
+
labels?: LayoutLabelOverrides;
|
|
9
|
+
button_colors?: ButtonPaletteOverrides;
|
|
10
|
+
password_requirements?: PasswordRequirementOverrides;
|
|
11
|
+
data_client: LayoutDataClient<TClient>;
|
|
12
|
+
alreadyLoggedInMessage?: string;
|
|
13
|
+
showLogoutButton?: boolean;
|
|
14
|
+
showReturnHomeButton?: boolean;
|
|
15
|
+
returnHomeButtonLabel?: string;
|
|
16
|
+
returnHomePath?: string;
|
|
17
|
+
errorMessage?: string;
|
|
18
|
+
successMessage?: string;
|
|
19
|
+
loginPath?: string;
|
|
20
|
+
forgotPasswordPath?: string;
|
|
21
|
+
};
|
|
22
|
+
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
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/layouts/reset_password/index.tsx"],"names":[],"mappings":"AAYA,OAAO,EACL,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EAClC,MAAM,iEAAiE,CAAC;AAYzE,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,6DAA6D,CAAC;AAIpG,MAAM,MAAM,wBAAwB,CAAC,OAAO,GAAG,OAAO,IAAI;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,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"}
|