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
package/README.md
CHANGED
|
@@ -2,36 +2,110 @@
|
|
|
2
2
|
|
|
3
3
|
A reusable authentication UI component package powered by Next.js, TailwindCSS, and shadcn. It integrates `hazo_config` for configuration management and `hazo_connect` for data access, enabling future components to stay aligned with platform conventions.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Installation](#installation)
|
|
8
|
+
- [Quick Start](#quick-start)
|
|
9
|
+
- [Configuration Setup](#configuration-setup)
|
|
10
|
+
- [Database Setup](#database-setup)
|
|
11
|
+
- [Using Components](#using-components)
|
|
12
|
+
- [Authentication Service](#authentication-service)
|
|
13
|
+
- [Profile Picture Menu Widget](#profile-picture-menu-widget)
|
|
14
|
+
- [User Profile Service](#user-profile-service)
|
|
15
|
+
- [Local Development](#local-development)
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
6
20
|
|
|
7
21
|
```bash
|
|
8
22
|
npm install hazo_auth
|
|
9
23
|
```
|
|
10
24
|
|
|
11
|
-
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
### 1. Install the package
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm install hazo_auth
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 2. Copy configuration files
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
cp node_modules/hazo_auth/hazo_auth_config.example.ini ./hazo_auth_config.ini
|
|
39
|
+
cp node_modules/hazo_auth/hazo_notify_config.example.ini ./hazo_notify_config.ini
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 3. Set up environment variables
|
|
43
|
+
|
|
44
|
+
Create a `.env.local` file:
|
|
45
|
+
|
|
46
|
+
```env
|
|
47
|
+
ZEPTOMAIL_API_KEY=your_api_key_here
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 4. Set up the database
|
|
51
|
+
|
|
52
|
+
Run the database setup SQL script (see [Database Setup](#database-setup)).
|
|
53
|
+
|
|
54
|
+
### 5. Import and use components
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
// Import layout components
|
|
58
|
+
import { LoginLayout } from "hazo_auth/components/layouts/login";
|
|
59
|
+
import { RegisterLayout } from "hazo_auth/components/layouts/register";
|
|
60
|
+
|
|
61
|
+
// Import UI components
|
|
62
|
+
import { Button } from "hazo_auth/components/ui/button";
|
|
63
|
+
import { Input } from "hazo_auth/components/ui/input";
|
|
64
|
+
|
|
65
|
+
// Import hooks
|
|
66
|
+
import { use_hazo_auth } from "hazo_auth/hooks/use_hazo_auth";
|
|
67
|
+
import { use_auth_status } from "hazo_auth/hooks/use_auth_status";
|
|
68
|
+
|
|
69
|
+
// Import server-side utilities
|
|
70
|
+
import { hazo_get_auth } from "hazo_auth/lib/auth/hazo_get_auth.server";
|
|
71
|
+
import { get_authenticated_user } from "hazo_auth/lib/auth/auth_utils.server";
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Configuration Setup
|
|
12
77
|
|
|
13
78
|
After installing the package, you need to set up configuration files in your project root:
|
|
14
79
|
|
|
15
|
-
1.
|
|
16
|
-
```bash
|
|
17
|
-
cp node_modules/hazo_auth/hazo_auth_config.example.ini ./hazo_auth_config.ini
|
|
18
|
-
cp node_modules/hazo_auth/hazo_notify_config.example.ini ./hazo_notify_config.ini
|
|
19
|
-
```
|
|
80
|
+
### 1. Copy the example config files to your project root:
|
|
20
81
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
82
|
+
```bash
|
|
83
|
+
cp node_modules/hazo_auth/hazo_auth_config.example.ini ./hazo_auth_config.ini
|
|
84
|
+
cp node_modules/hazo_auth/hazo_notify_config.example.ini ./hazo_notify_config.ini
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### 2. Customize the configuration files:
|
|
88
|
+
|
|
89
|
+
- Edit `hazo_auth_config.ini` to configure authentication settings, database connection, UI labels, and more
|
|
90
|
+
- Edit `hazo_notify_config.ini` to configure email service settings (Zeptomail, SMTP, etc.)
|
|
24
91
|
|
|
25
|
-
3.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
92
|
+
### 3. Set up environment variables (recommended for sensitive data):
|
|
93
|
+
|
|
94
|
+
- Create a `.env.local` file in your project root
|
|
95
|
+
- Add `ZEPTOMAIL_API_KEY=your_api_key_here` (if using Zeptomail)
|
|
96
|
+
- Add other sensitive configuration values as needed
|
|
29
97
|
|
|
30
98
|
**Important:** The configuration files must be located in your project root directory (where `process.cwd()` points to), not inside `node_modules`. The package reads configuration from `process.cwd()` at runtime, so storing them elsewhere (including `node_modules/hazo_auth`) will break runtime access.
|
|
31
99
|
|
|
32
|
-
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Database Setup
|
|
103
|
+
|
|
104
|
+
Before using `hazo_auth`, you need to create the required database tables. The package supports both **PostgreSQL** (for production) and **SQLite** (for local development/testing).
|
|
105
|
+
|
|
106
|
+
### PostgreSQL Setup
|
|
33
107
|
|
|
34
|
-
|
|
108
|
+
Run the following SQL scripts in your PostgreSQL database:
|
|
35
109
|
|
|
36
110
|
#### 1. Create the Profile Source Enum Type
|
|
37
111
|
|
|
@@ -65,6 +139,8 @@ CREATE TABLE hazo_users (
|
|
|
65
139
|
CREATE INDEX idx_hazo_users_email ON hazo_users(email_address);
|
|
66
140
|
```
|
|
67
141
|
|
|
142
|
+
**Note:** The `url_on_logon` field is used to store a custom redirect URL for users after successful login. This allows per-user customization of post-login navigation.
|
|
143
|
+
|
|
68
144
|
#### 3. Create the Refresh Tokens Table
|
|
69
145
|
|
|
70
146
|
```sql
|
|
@@ -88,7 +164,7 @@ CREATE INDEX idx_hazo_refresh_tokens_token_type ON hazo_refresh_tokens(token_typ
|
|
|
88
164
|
```sql
|
|
89
165
|
-- Permissions table for RBAC
|
|
90
166
|
CREATE TABLE hazo_permissions (
|
|
91
|
-
id
|
|
167
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
92
168
|
permission_name TEXT NOT NULL UNIQUE,
|
|
93
169
|
description TEXT,
|
|
94
170
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
@@ -101,7 +177,7 @@ CREATE TABLE hazo_permissions (
|
|
|
101
177
|
```sql
|
|
102
178
|
-- Roles table for RBAC
|
|
103
179
|
CREATE TABLE hazo_roles (
|
|
104
|
-
id
|
|
180
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
105
181
|
role_name TEXT NOT NULL UNIQUE,
|
|
106
182
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
107
183
|
changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
@@ -113,8 +189,8 @@ CREATE TABLE hazo_roles (
|
|
|
113
189
|
```sql
|
|
114
190
|
-- Junction table linking roles to permissions
|
|
115
191
|
CREATE TABLE hazo_role_permissions (
|
|
116
|
-
role_id
|
|
117
|
-
permission_id
|
|
192
|
+
role_id UUID NOT NULL REFERENCES hazo_roles(id) ON DELETE CASCADE,
|
|
193
|
+
permission_id UUID NOT NULL REFERENCES hazo_permissions(id) ON DELETE CASCADE,
|
|
118
194
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
119
195
|
changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
120
196
|
PRIMARY KEY (role_id, permission_id)
|
|
@@ -131,7 +207,7 @@ CREATE INDEX idx_hazo_role_permissions_permission_id ON hazo_role_permissions(pe
|
|
|
131
207
|
-- Junction table linking users to roles
|
|
132
208
|
CREATE TABLE hazo_user_roles (
|
|
133
209
|
user_id UUID NOT NULL REFERENCES hazo_users(id) ON DELETE CASCADE,
|
|
134
|
-
role_id
|
|
210
|
+
role_id UUID NOT NULL REFERENCES hazo_roles(id) ON DELETE CASCADE,
|
|
135
211
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
136
212
|
changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
137
213
|
PRIMARY KEY (user_id, role_id)
|
|
@@ -142,13 +218,13 @@ CREATE INDEX idx_hazo_user_roles_user_id ON hazo_user_roles(user_id);
|
|
|
142
218
|
CREATE INDEX idx_hazo_user_roles_role_id ON hazo_user_roles(role_id);
|
|
143
219
|
```
|
|
144
220
|
|
|
145
|
-
|
|
221
|
+
### Complete PostgreSQL Setup Script
|
|
146
222
|
|
|
147
223
|
For convenience, here's the complete SQL script to create all tables at once:
|
|
148
224
|
|
|
149
225
|
```sql
|
|
150
226
|
-- ============================================
|
|
151
|
-
-- hazo_auth Database Setup Script
|
|
227
|
+
-- hazo_auth Database Setup Script (PostgreSQL)
|
|
152
228
|
-- ============================================
|
|
153
229
|
|
|
154
230
|
-- 1. Create enum type
|
|
@@ -187,7 +263,7 @@ CREATE INDEX idx_hazo_refresh_tokens_token_type ON hazo_refresh_tokens(token_typ
|
|
|
187
263
|
|
|
188
264
|
-- 4. Create permissions table
|
|
189
265
|
CREATE TABLE hazo_permissions (
|
|
190
|
-
id
|
|
266
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
191
267
|
permission_name TEXT NOT NULL UNIQUE,
|
|
192
268
|
description TEXT,
|
|
193
269
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
@@ -196,7 +272,7 @@ CREATE TABLE hazo_permissions (
|
|
|
196
272
|
|
|
197
273
|
-- 5. Create roles table
|
|
198
274
|
CREATE TABLE hazo_roles (
|
|
199
|
-
id
|
|
275
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
200
276
|
role_name TEXT NOT NULL UNIQUE,
|
|
201
277
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
202
278
|
changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
@@ -204,8 +280,8 @@ CREATE TABLE hazo_roles (
|
|
|
204
280
|
|
|
205
281
|
-- 6. Create role-permissions junction table
|
|
206
282
|
CREATE TABLE hazo_role_permissions (
|
|
207
|
-
role_id
|
|
208
|
-
permission_id
|
|
283
|
+
role_id UUID NOT NULL REFERENCES hazo_roles(id) ON DELETE CASCADE,
|
|
284
|
+
permission_id UUID NOT NULL REFERENCES hazo_permissions(id) ON DELETE CASCADE,
|
|
209
285
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
210
286
|
changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
211
287
|
PRIMARY KEY (role_id, permission_id)
|
|
@@ -216,7 +292,7 @@ CREATE INDEX idx_hazo_role_permissions_permission_id ON hazo_role_permissions(pe
|
|
|
216
292
|
-- 7. Create user-roles junction table
|
|
217
293
|
CREATE TABLE hazo_user_roles (
|
|
218
294
|
user_id UUID NOT NULL REFERENCES hazo_users(id) ON DELETE CASCADE,
|
|
219
|
-
role_id
|
|
295
|
+
role_id UUID NOT NULL REFERENCES hazo_roles(id) ON DELETE CASCADE,
|
|
220
296
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
221
297
|
changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
222
298
|
PRIMARY KEY (user_id, role_id)
|
|
@@ -225,7 +301,80 @@ CREATE INDEX idx_hazo_user_roles_user_id ON hazo_user_roles(user_id);
|
|
|
225
301
|
CREATE INDEX idx_hazo_user_roles_role_id ON hazo_user_roles(role_id);
|
|
226
302
|
```
|
|
227
303
|
|
|
228
|
-
|
|
304
|
+
### SQLite Setup (for local development)
|
|
305
|
+
|
|
306
|
+
For local development and testing, you can use SQLite. The SQLite schema is slightly different (no UUID type, TEXT used instead):
|
|
307
|
+
|
|
308
|
+
```sql
|
|
309
|
+
-- ============================================
|
|
310
|
+
-- hazo_auth Database Setup Script (SQLite)
|
|
311
|
+
-- ============================================
|
|
312
|
+
|
|
313
|
+
-- Users table
|
|
314
|
+
CREATE TABLE IF NOT EXISTS hazo_users (
|
|
315
|
+
id TEXT PRIMARY KEY,
|
|
316
|
+
email_address TEXT NOT NULL UNIQUE,
|
|
317
|
+
password_hash TEXT NOT NULL,
|
|
318
|
+
name TEXT,
|
|
319
|
+
email_verified INTEGER NOT NULL DEFAULT 0,
|
|
320
|
+
is_active INTEGER NOT NULL DEFAULT 1,
|
|
321
|
+
login_attempts INTEGER NOT NULL DEFAULT 0,
|
|
322
|
+
last_logon TEXT,
|
|
323
|
+
profile_picture_url TEXT,
|
|
324
|
+
profile_source TEXT,
|
|
325
|
+
mfa_secret TEXT,
|
|
326
|
+
url_on_logon TEXT,
|
|
327
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
328
|
+
changed_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
329
|
+
);
|
|
330
|
+
|
|
331
|
+
-- Refresh tokens table
|
|
332
|
+
CREATE TABLE IF NOT EXISTS hazo_refresh_tokens (
|
|
333
|
+
id TEXT PRIMARY KEY,
|
|
334
|
+
user_id TEXT NOT NULL REFERENCES hazo_users(id) ON DELETE CASCADE,
|
|
335
|
+
token_hash TEXT NOT NULL,
|
|
336
|
+
token_type TEXT NOT NULL,
|
|
337
|
+
expires_at TEXT NOT NULL,
|
|
338
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
339
|
+
);
|
|
340
|
+
|
|
341
|
+
-- Permissions table
|
|
342
|
+
CREATE TABLE IF NOT EXISTS hazo_permissions (
|
|
343
|
+
id TEXT PRIMARY KEY,
|
|
344
|
+
permission_name TEXT NOT NULL UNIQUE,
|
|
345
|
+
description TEXT,
|
|
346
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
347
|
+
changed_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
348
|
+
);
|
|
349
|
+
|
|
350
|
+
-- Roles table
|
|
351
|
+
CREATE TABLE IF NOT EXISTS hazo_roles (
|
|
352
|
+
id TEXT PRIMARY KEY,
|
|
353
|
+
role_name TEXT NOT NULL UNIQUE,
|
|
354
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
355
|
+
changed_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
356
|
+
);
|
|
357
|
+
|
|
358
|
+
-- Role-permissions junction table
|
|
359
|
+
CREATE TABLE IF NOT EXISTS hazo_role_permissions (
|
|
360
|
+
role_id TEXT NOT NULL REFERENCES hazo_roles(id) ON DELETE CASCADE,
|
|
361
|
+
permission_id TEXT NOT NULL REFERENCES hazo_permissions(id) ON DELETE CASCADE,
|
|
362
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
363
|
+
changed_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
364
|
+
PRIMARY KEY (role_id, permission_id)
|
|
365
|
+
);
|
|
366
|
+
|
|
367
|
+
-- User-roles junction table
|
|
368
|
+
CREATE TABLE IF NOT EXISTS hazo_user_roles (
|
|
369
|
+
user_id TEXT NOT NULL REFERENCES hazo_users(id) ON DELETE CASCADE,
|
|
370
|
+
role_id TEXT NOT NULL REFERENCES hazo_roles(id) ON DELETE CASCADE,
|
|
371
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
372
|
+
changed_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
373
|
+
PRIMARY KEY (user_id, role_id)
|
|
374
|
+
);
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### Initialize Default Permissions and Super User
|
|
229
378
|
|
|
230
379
|
After creating the tables, you can use the `init-users` script to set up default permissions and a super user:
|
|
231
380
|
|
|
@@ -238,67 +387,82 @@ This script reads from `hazo_auth_config.ini` and:
|
|
|
238
387
|
2. Creates a `default_super_user_role` role with all permissions
|
|
239
388
|
3. Assigns the role to the user specified in `default_super_user_email`
|
|
240
389
|
|
|
241
|
-
###
|
|
390
|
+
### Apply Migrations
|
|
242
391
|
|
|
243
|
-
|
|
392
|
+
To apply database migrations (e.g., adding new fields):
|
|
244
393
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
ln -s ../../node_modules/hazo_auth/src/app/api/hazo_auth src/app/api/hazo_auth
|
|
249
|
-
ln -s ../../node_modules/hazo_auth/src/app/hazo_auth src/app/hazo_auth
|
|
250
|
-
```
|
|
251
|
-
Adjust the relative paths if your project structure differs.
|
|
394
|
+
```bash
|
|
395
|
+
# Apply a specific migration
|
|
396
|
+
npx tsx scripts/apply_migration.ts migrations/003_add_url_on_logon_to_hazo_users.sql
|
|
252
397
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
cp -R node_modules/hazo_auth/src/app/hazo_auth src/app/hazo_auth
|
|
257
|
-
```
|
|
258
|
-
Add an npm script (e.g., `postinstall`) to automate copying after installations or updates.
|
|
398
|
+
# Or apply all pending migrations
|
|
399
|
+
npx tsx scripts/apply_migration.ts
|
|
400
|
+
```
|
|
259
401
|
|
|
260
|
-
|
|
402
|
+
---
|
|
261
403
|
|
|
262
|
-
|
|
404
|
+
## Using Components
|
|
263
405
|
|
|
264
|
-
|
|
406
|
+
### Package Exports
|
|
265
407
|
|
|
266
|
-
|
|
267
|
-
[hazo_auth__ui_shell]
|
|
268
|
-
# Options: test_sidebar | standalone
|
|
269
|
-
layout_mode = standalone
|
|
270
|
-
# Optional tweaks for the standalone header wrapper/classes:
|
|
271
|
-
# standalone_heading = Welcome back
|
|
272
|
-
# standalone_description = Your description here
|
|
273
|
-
# standalone_wrapper_class = min-h-screen bg-background py-8
|
|
274
|
-
# standalone_content_class = mx-auto w-full max-w-4xl rounded-2xl border bg-card
|
|
275
|
-
```
|
|
408
|
+
The package exports components through these paths:
|
|
276
409
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
410
|
+
```typescript
|
|
411
|
+
// Main entry point - exports all public APIs
|
|
412
|
+
import { ... } from "hazo_auth";
|
|
413
|
+
|
|
414
|
+
// Layout components
|
|
415
|
+
import { LoginLayout } from "hazo_auth/components/layouts/login";
|
|
416
|
+
import { RegisterLayout } from "hazo_auth/components/layouts/register";
|
|
417
|
+
import { ForgotPasswordLayout } from "hazo_auth/components/layouts/forgot_password";
|
|
418
|
+
import { ResetPasswordLayout } from "hazo_auth/components/layouts/reset_password";
|
|
419
|
+
import { EmailVerificationLayout } from "hazo_auth/components/layouts/verify_email";
|
|
420
|
+
import { MySettingsLayout } from "hazo_auth/components/layouts/my_settings";
|
|
421
|
+
import { UserManagementLayout } from "hazo_auth/components/layouts/user_management";
|
|
280
422
|
|
|
281
|
-
|
|
423
|
+
// UI components
|
|
424
|
+
import { Button } from "hazo_auth/components/ui/button";
|
|
425
|
+
import { Input } from "hazo_auth/components/ui/input";
|
|
426
|
+
import { Avatar } from "hazo_auth/components/ui/avatar";
|
|
427
|
+
// ... and more shadcn-based components
|
|
282
428
|
|
|
283
|
-
|
|
429
|
+
// Shared layout components
|
|
430
|
+
import { ProfilePicMenu } from "hazo_auth/components/layouts/shared/components/profile_pic_menu";
|
|
431
|
+
import { ProfilePicMenuWrapper } from "hazo_auth/components/layouts/shared/components/profile_pic_menu_wrapper";
|
|
432
|
+
import { FormActionButtons } from "hazo_auth/components/layouts/shared/components/form_action_buttons";
|
|
284
433
|
|
|
285
|
-
|
|
434
|
+
// Hooks (client-side)
|
|
435
|
+
import { use_hazo_auth } from "hazo_auth/hooks/use_hazo_auth";
|
|
436
|
+
import { use_auth_status } from "hazo_auth/hooks/use_auth_status";
|
|
437
|
+
import { use_login_form } from "hazo_auth/hooks/use_login_form";
|
|
438
|
+
|
|
439
|
+
// Library utilities
|
|
440
|
+
import { hazo_get_auth } from "hazo_auth/lib/auth/hazo_get_auth.server";
|
|
441
|
+
import { get_authenticated_user } from "hazo_auth/lib/auth/auth_utils.server";
|
|
442
|
+
import { get_server_auth_user } from "hazo_auth/lib/auth/server_auth";
|
|
443
|
+
|
|
444
|
+
// Server utilities
|
|
445
|
+
import { get_hazo_connect_instance } from "hazo_auth/server/hazo_connect_instance.server";
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
### Using Layout Components
|
|
449
|
+
|
|
450
|
+
Prefer to drop the forms into your own routes without using the pre-built pages? Import the layouts directly and feed them a `data_client` plus any label/button overrides:
|
|
286
451
|
|
|
287
452
|
```tsx
|
|
288
453
|
// app/(auth)/login/page.tsx in your project
|
|
289
|
-
import
|
|
290
|
-
import {
|
|
291
|
-
import { create_sqlite_hazo_connect } from "hazo_auth/lib/hazo_connect_setup";
|
|
454
|
+
import { LoginLayout, createLayoutDataClient } from "hazo_auth";
|
|
455
|
+
import { create_postgrest_hazo_connect } from "hazo_auth/lib/hazo_connect_setup";
|
|
292
456
|
|
|
293
457
|
export default async function LoginPage() {
|
|
294
|
-
const hazoConnect =
|
|
458
|
+
const hazoConnect = create_postgrest_hazo_connect();
|
|
295
459
|
const dataClient = createLayoutDataClient(hazoConnect);
|
|
296
|
-
const LoginLayout = login_layout;
|
|
297
460
|
|
|
298
461
|
return (
|
|
299
462
|
<div className="my-app-shell">
|
|
300
463
|
<LoginLayout
|
|
301
464
|
image_src="/marketing/login-hero.svg"
|
|
465
|
+
image_alt="Login hero image"
|
|
302
466
|
data_client={dataClient}
|
|
303
467
|
redirectRoute="/dashboard"
|
|
304
468
|
/>
|
|
@@ -307,7 +471,40 @@ export default async function LoginPage() {
|
|
|
307
471
|
}
|
|
308
472
|
```
|
|
309
473
|
|
|
310
|
-
|
|
474
|
+
**Available Layout Components:**
|
|
475
|
+
- `LoginLayout` - Login form with email/password
|
|
476
|
+
- `RegisterLayout` - Registration form with password requirements
|
|
477
|
+
- `ForgotPasswordLayout` - Request password reset
|
|
478
|
+
- `ResetPasswordLayout` - Set new password with token
|
|
479
|
+
- `EmailVerificationLayout` - Verify email address
|
|
480
|
+
- `MySettingsLayout` - User profile and settings
|
|
481
|
+
- `UserManagementLayout` - Admin user/role management
|
|
482
|
+
|
|
483
|
+
**Shared Components:**
|
|
484
|
+
- `ProfilePicMenu` / `ProfilePicMenuWrapper` - Navbar profile menu
|
|
485
|
+
- `FormActionButtons`, `FormFieldWrapper`, `PasswordField`
|
|
486
|
+
- And more under `hazo_auth/components/layouts/shared/`
|
|
487
|
+
|
|
488
|
+
### Choose the UI Shell (Test Sidebar vs Standalone)
|
|
489
|
+
|
|
490
|
+
By default, the pages render inside the "test workspace" sidebar so you can quickly preview every flow. When you reuse the routes inside another project you'll usually want a clean, standalone wrapper instead. Set this in `hazo_auth_config.ini`:
|
|
491
|
+
|
|
492
|
+
```ini
|
|
493
|
+
[hazo_auth__ui_shell]
|
|
494
|
+
# Options: test_sidebar | standalone
|
|
495
|
+
layout_mode = standalone
|
|
496
|
+
# Optional tweaks for the standalone header wrapper/classes:
|
|
497
|
+
# standalone_heading = Welcome back
|
|
498
|
+
# standalone_description = Your description here
|
|
499
|
+
# standalone_wrapper_class = min-h-screen bg-background py-8
|
|
500
|
+
# standalone_content_class = mx-auto w-full max-w-4xl rounded-2xl border bg-card
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
- `test_sidebar`: keeps the developer sidebar (perfect for the demo workspace or Storybook screenshots).
|
|
504
|
+
- `standalone`: renders the page body directly so it inherits your own app shell, layout, and theme tokens.
|
|
505
|
+
- The wrapper and content class overrides let you align spacing/borders with your design system without editing package code.
|
|
506
|
+
|
|
507
|
+
---
|
|
311
508
|
|
|
312
509
|
## Authentication Service
|
|
313
510
|
|
|
@@ -347,6 +544,7 @@ type HazoAuthResult =
|
|
|
347
544
|
email_address: string;
|
|
348
545
|
is_active: boolean;
|
|
349
546
|
profile_picture_url: string | null;
|
|
547
|
+
url_on_logon: string | null;
|
|
350
548
|
};
|
|
351
549
|
permissions: string[];
|
|
352
550
|
permission_ok: boolean;
|
|
@@ -391,6 +589,9 @@ export async function GET(request: NextRequest) {
|
|
|
391
589
|
}
|
|
392
590
|
|
|
393
591
|
// User is authenticated and has required permissions
|
|
592
|
+
// Access url_on_logon for custom redirect
|
|
593
|
+
const redirectUrl = authResult.user.url_on_logon || "/dashboard";
|
|
594
|
+
|
|
394
595
|
return NextResponse.json({
|
|
395
596
|
message: "Access granted",
|
|
396
597
|
user: authResult.user,
|
|
@@ -412,43 +613,13 @@ export async function GET(request: NextRequest) {
|
|
|
412
613
|
}
|
|
413
614
|
```
|
|
414
615
|
|
|
415
|
-
**Non-strict mode (returns permission status without throwing):**
|
|
416
|
-
|
|
417
|
-
```typescript
|
|
418
|
-
// Check permissions without throwing errors
|
|
419
|
-
const authResult = await hazo_get_auth(request, {
|
|
420
|
-
required_permissions: ["admin_user_management"],
|
|
421
|
-
strict: false, // Returns permission_ok: false if missing
|
|
422
|
-
});
|
|
423
|
-
|
|
424
|
-
if (authResult.authenticated && authResult.permission_ok) {
|
|
425
|
-
// User has required permissions
|
|
426
|
-
} else if (authResult.authenticated) {
|
|
427
|
-
// User is authenticated but missing permissions
|
|
428
|
-
console.log("Missing permissions:", authResult.missing_permissions);
|
|
429
|
-
} else {
|
|
430
|
-
// User is not authenticated
|
|
431
|
-
}
|
|
432
|
-
```
|
|
433
|
-
|
|
434
616
|
#### `get_authenticated_user`
|
|
435
617
|
|
|
436
618
|
Basic authentication check for API routes. Returns user info if authenticated, or `{ authenticated: false }` if not.
|
|
437
619
|
|
|
438
620
|
**Location:** `src/lib/auth/auth_utils.server.ts`
|
|
439
621
|
|
|
440
|
-
**Function Signature:**
|
|
441
|
-
```typescript
|
|
442
|
-
import { get_authenticated_user } from "hazo_auth/lib/auth/auth_utils.server";
|
|
443
|
-
import type { AuthResult } from "hazo_auth/lib/auth/auth_utils.server";
|
|
444
|
-
|
|
445
|
-
async function get_authenticated_user(request: NextRequest): Promise<AuthResult>
|
|
446
|
-
```
|
|
447
|
-
|
|
448
|
-
**Example Usage:**
|
|
449
|
-
|
|
450
622
|
```typescript
|
|
451
|
-
import { NextRequest, NextResponse } from "next/server";
|
|
452
623
|
import { get_authenticated_user } from "hazo_auth/lib/auth/auth_utils.server";
|
|
453
624
|
|
|
454
625
|
export async function GET(request: NextRequest) {
|
|
@@ -469,89 +640,12 @@ export async function GET(request: NextRequest) {
|
|
|
469
640
|
}
|
|
470
641
|
```
|
|
471
642
|
|
|
472
|
-
#### `require_auth`
|
|
473
|
-
|
|
474
|
-
Requires authentication and throws an error if the user is not authenticated. Useful for protected API routes.
|
|
475
|
-
|
|
476
|
-
**Location:** `src/lib/auth/auth_utils.server.ts`
|
|
477
|
-
|
|
478
|
-
**Function Signature:**
|
|
479
|
-
```typescript
|
|
480
|
-
import { require_auth } from "hazo_auth/lib/auth/auth_utils.server";
|
|
481
|
-
import type { AuthUser } from "hazo_auth/lib/auth/auth_utils.server";
|
|
482
|
-
|
|
483
|
-
async function require_auth(request: NextRequest): Promise<AuthUser>
|
|
484
|
-
```
|
|
485
|
-
|
|
486
|
-
**Example Usage:**
|
|
487
|
-
|
|
488
|
-
```typescript
|
|
489
|
-
import { NextRequest, NextResponse } from "next/server";
|
|
490
|
-
import { require_auth } from "hazo_auth/lib/auth/auth_utils.server";
|
|
491
|
-
|
|
492
|
-
export async function GET(request: NextRequest) {
|
|
493
|
-
try {
|
|
494
|
-
const user = await require_auth(request);
|
|
495
|
-
// User is guaranteed to be authenticated here
|
|
496
|
-
return NextResponse.json({ user_id: user.user_id, email: user.email });
|
|
497
|
-
} catch (error) {
|
|
498
|
-
return NextResponse.json(
|
|
499
|
-
{ error: "Authentication required" },
|
|
500
|
-
{ status: 401 }
|
|
501
|
-
);
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
```
|
|
505
|
-
|
|
506
|
-
#### `is_authenticated`
|
|
507
|
-
|
|
508
|
-
Simple boolean check for authentication status.
|
|
509
|
-
|
|
510
|
-
**Location:** `src/lib/auth/auth_utils.server.ts`
|
|
511
|
-
|
|
512
|
-
**Function Signature:**
|
|
513
|
-
```typescript
|
|
514
|
-
import { is_authenticated } from "hazo_auth/lib/auth/auth_utils.server";
|
|
515
|
-
|
|
516
|
-
async function is_authenticated(request: NextRequest): Promise<boolean>
|
|
517
|
-
```
|
|
518
|
-
|
|
519
|
-
**Example Usage:**
|
|
520
|
-
|
|
521
|
-
```typescript
|
|
522
|
-
import { NextRequest, NextResponse } from "next/server";
|
|
523
|
-
import { is_authenticated } from "hazo_auth/lib/auth/auth_utils.server";
|
|
524
|
-
|
|
525
|
-
export async function GET(request: NextRequest) {
|
|
526
|
-
const authenticated = await is_authenticated(request);
|
|
527
|
-
|
|
528
|
-
if (!authenticated) {
|
|
529
|
-
return NextResponse.json(
|
|
530
|
-
{ error: "Authentication required" },
|
|
531
|
-
{ status: 401 }
|
|
532
|
-
);
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
// Continue with authenticated logic
|
|
536
|
-
}
|
|
537
|
-
```
|
|
538
|
-
|
|
539
643
|
#### `get_server_auth_user`
|
|
540
644
|
|
|
541
645
|
Gets authenticated user in server components and pages (uses Next.js `cookies()` function).
|
|
542
646
|
|
|
543
647
|
**Location:** `src/lib/auth/server_auth.ts`
|
|
544
648
|
|
|
545
|
-
**Function Signature:**
|
|
546
|
-
```typescript
|
|
547
|
-
import { get_server_auth_user } from "hazo_auth/lib/auth/server_auth";
|
|
548
|
-
import type { ServerAuthResult } from "hazo_auth/lib/auth/server_auth";
|
|
549
|
-
|
|
550
|
-
async function get_server_auth_user(): Promise<ServerAuthResult>
|
|
551
|
-
```
|
|
552
|
-
|
|
553
|
-
**Example Usage:**
|
|
554
|
-
|
|
555
649
|
```typescript
|
|
556
650
|
// In a server component (src/app/dashboard/page.tsx)
|
|
557
651
|
import { get_server_auth_user } from "hazo_auth/lib/auth/server_auth";
|
|
@@ -578,36 +672,12 @@ export default async function DashboardPage() {
|
|
|
578
672
|
|
|
579
673
|
React hook for fetching authentication status and permissions on the client side.
|
|
580
674
|
|
|
581
|
-
**Location:** `src/
|
|
582
|
-
|
|
583
|
-
**Function Signature:**
|
|
584
|
-
```typescript
|
|
585
|
-
import { use_hazo_auth } from "hazo_auth/components/layouts/shared/hooks/use_hazo_auth";
|
|
586
|
-
import type { UseHazoAuthOptions, UseHazoAuthResult } from "hazo_auth/components/layouts/shared/hooks/use_hazo_auth";
|
|
587
|
-
|
|
588
|
-
function use_hazo_auth(options?: UseHazoAuthOptions): UseHazoAuthResult
|
|
589
|
-
```
|
|
590
|
-
|
|
591
|
-
**Options:**
|
|
592
|
-
- `required_permissions?: string[]` - Array of permission names to check
|
|
593
|
-
- `strict?: boolean` - If `true`, throws error when permissions are missing (default: `false`)
|
|
594
|
-
- `skip?: boolean` - Skip fetch (for conditional use)
|
|
595
|
-
|
|
596
|
-
**Return Type:**
|
|
597
|
-
```typescript
|
|
598
|
-
type UseHazoAuthResult = HazoAuthResult & {
|
|
599
|
-
loading: boolean;
|
|
600
|
-
error: Error | null;
|
|
601
|
-
refetch: () => Promise<void>;
|
|
602
|
-
};
|
|
603
|
-
```
|
|
604
|
-
|
|
605
|
-
**Example Usage:**
|
|
675
|
+
**Location:** `src/hooks/use_hazo_auth.ts`
|
|
606
676
|
|
|
607
677
|
```typescript
|
|
608
678
|
"use client";
|
|
609
679
|
|
|
610
|
-
import { use_hazo_auth } from "hazo_auth/
|
|
680
|
+
import { use_hazo_auth } from "hazo_auth/hooks/use_hazo_auth";
|
|
611
681
|
|
|
612
682
|
export function ProtectedComponent() {
|
|
613
683
|
const { authenticated, user, permissions, permission_ok, loading, error, refetch } =
|
|
@@ -616,21 +686,10 @@ export function ProtectedComponent() {
|
|
|
616
686
|
strict: false,
|
|
617
687
|
});
|
|
618
688
|
|
|
619
|
-
if (loading)
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
if (error) {
|
|
624
|
-
return <div>Error: {error.message}</div>;
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
if (!authenticated) {
|
|
628
|
-
return <div>Please log in to access this page.</div>;
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
if (!permission_ok) {
|
|
632
|
-
return <div>You don't have permission to access this page.</div>;
|
|
633
|
-
}
|
|
689
|
+
if (loading) return <div>Loading...</div>;
|
|
690
|
+
if (error) return <div>Error: {error.message}</div>;
|
|
691
|
+
if (!authenticated) return <div>Please log in to access this page.</div>;
|
|
692
|
+
if (!permission_ok) return <div>You don't have permission to access this page.</div>;
|
|
634
693
|
|
|
635
694
|
return (
|
|
636
695
|
<div>
|
|
@@ -642,298 +701,48 @@ export function ProtectedComponent() {
|
|
|
642
701
|
}
|
|
643
702
|
```
|
|
644
703
|
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
```typescript
|
|
648
|
-
"use client";
|
|
704
|
+
#### `use_auth_status`
|
|
649
705
|
|
|
650
|
-
|
|
706
|
+
Simpler hook for basic authentication status checking.
|
|
651
707
|
|
|
652
|
-
|
|
653
|
-
// Check multiple permissions
|
|
654
|
-
const userManagementAuth = use_hazo_auth({
|
|
655
|
-
required_permissions: ["admin_user_management"],
|
|
656
|
-
});
|
|
657
|
-
|
|
658
|
-
const roleManagementAuth = use_hazo_auth({
|
|
659
|
-
required_permissions: ["admin_role_management"],
|
|
660
|
-
});
|
|
661
|
-
|
|
662
|
-
return (
|
|
663
|
-
<div>
|
|
664
|
-
{userManagementAuth.permission_ok && (
|
|
665
|
-
<button>Manage Users</button>
|
|
666
|
-
)}
|
|
667
|
-
{roleManagementAuth.permission_ok && (
|
|
668
|
-
<button>Manage Roles</button>
|
|
669
|
-
)}
|
|
670
|
-
</div>
|
|
671
|
-
);
|
|
672
|
-
}
|
|
673
|
-
```
|
|
674
|
-
|
|
675
|
-
#### `trigger_hazo_auth_refresh`
|
|
676
|
-
|
|
677
|
-
Triggers a refresh of authentication status across all components using `use_hazo_auth`. Useful after login, logout, or permission changes.
|
|
678
|
-
|
|
679
|
-
**Location:** `src/components/layouts/shared/hooks/use_hazo_auth.ts`
|
|
680
|
-
|
|
681
|
-
**Function Signature:**
|
|
682
|
-
```typescript
|
|
683
|
-
import { trigger_hazo_auth_refresh } from "hazo_auth/components/layouts/shared/hooks/use_hazo_auth";
|
|
684
|
-
|
|
685
|
-
function trigger_hazo_auth_refresh(): void
|
|
686
|
-
```
|
|
687
|
-
|
|
688
|
-
**Example Usage:**
|
|
708
|
+
**Location:** `src/hooks/use_auth_status.ts`
|
|
689
709
|
|
|
690
710
|
```typescript
|
|
691
711
|
"use client";
|
|
692
712
|
|
|
693
|
-
import {
|
|
713
|
+
import { use_auth_status } from "hazo_auth/hooks/use_auth_status";
|
|
714
|
+
|
|
715
|
+
export function UserGreeting() {
|
|
716
|
+
const { authenticated, name, email, loading } = use_auth_status();
|
|
694
717
|
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
await fetch("/api/hazo_auth/logout", { method: "POST" });
|
|
698
|
-
trigger_hazo_auth_refresh(); // Notify all components to refresh auth status
|
|
699
|
-
window.location.href = "/hazo_auth/login";
|
|
700
|
-
};
|
|
718
|
+
if (loading) return <div>Loading...</div>;
|
|
719
|
+
if (!authenticated) return <div>Please log in</div>;
|
|
701
720
|
|
|
702
|
-
return <
|
|
721
|
+
return <div>Welcome, {name || email}!</div>;
|
|
703
722
|
}
|
|
704
723
|
```
|
|
705
724
|
|
|
706
725
|
### Configuration
|
|
707
726
|
|
|
708
|
-
|
|
727
|
+
Configure the authentication utility in `hazo_auth_config.ini`:
|
|
709
728
|
|
|
710
729
|
```ini
|
|
711
730
|
[hazo_auth__auth_utility]
|
|
712
731
|
# Cache settings
|
|
713
|
-
# Maximum number of users to cache (LRU eviction, default: 10000)
|
|
714
732
|
cache_max_users = 10000
|
|
715
|
-
|
|
716
|
-
# Cache TTL in minutes (default: 15)
|
|
717
733
|
cache_ttl_minutes = 15
|
|
718
|
-
|
|
719
|
-
# Force cache refresh if older than this many minutes (default: 30)
|
|
720
734
|
cache_max_age_minutes = 30
|
|
721
735
|
|
|
722
|
-
# Rate limiting
|
|
723
|
-
# Per-user rate limit (requests per minute, default: 100)
|
|
736
|
+
# Rate limiting
|
|
724
737
|
rate_limit_per_user = 100
|
|
725
|
-
|
|
726
|
-
# Per-IP rate limit for unauthenticated requests (default: 200)
|
|
727
738
|
rate_limit_per_ip = 200
|
|
728
739
|
|
|
729
740
|
# Permission check behavior
|
|
730
|
-
# Log all permission denials for security audit (default: true)
|
|
731
741
|
log_permission_denials = true
|
|
732
|
-
|
|
733
|
-
# User-friendly error messages
|
|
734
|
-
# Enable mapping of technical permissions to user-friendly messages (default: true)
|
|
735
742
|
enable_friendly_error_messages = true
|
|
736
|
-
|
|
737
|
-
# Permission message mappings (optional, comma-separated: permission_name:user_message)
|
|
738
|
-
# Example: admin_user_management:You don't have access to user management,admin_role_management:You don't have access to role management
|
|
739
|
-
permission_error_messages =
|
|
740
|
-
```
|
|
741
|
-
|
|
742
|
-
### Testing Authentication and RBAC
|
|
743
|
-
|
|
744
|
-
#### Testing User Authentication
|
|
745
|
-
|
|
746
|
-
To test if a user is authenticated, use the `hazo_get_auth` function or the `use_hazo_auth` hook:
|
|
747
|
-
|
|
748
|
-
```typescript
|
|
749
|
-
// Server-side test
|
|
750
|
-
const authResult = await hazo_get_auth(request);
|
|
751
|
-
if (authResult.authenticated) {
|
|
752
|
-
console.log("User is authenticated:", authResult.user.email_address);
|
|
753
|
-
console.log("User permissions:", authResult.permissions);
|
|
754
|
-
} else {
|
|
755
|
-
console.log("User is not authenticated");
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
// Client-side test
|
|
759
|
-
const { authenticated, user, permissions } = use_hazo_auth();
|
|
760
|
-
if (authenticated) {
|
|
761
|
-
console.log("User is authenticated:", user?.email_address);
|
|
762
|
-
console.log("User permissions:", permissions);
|
|
763
|
-
}
|
|
764
|
-
```
|
|
765
|
-
|
|
766
|
-
#### Testing RBAC Permissions
|
|
767
|
-
|
|
768
|
-
To test if a user has specific permissions:
|
|
769
|
-
|
|
770
|
-
```typescript
|
|
771
|
-
// Server-side - strict mode (throws error if missing)
|
|
772
|
-
try {
|
|
773
|
-
const authResult = await hazo_get_auth(request, {
|
|
774
|
-
required_permissions: ["admin_user_management", "admin_role_management"],
|
|
775
|
-
strict: true,
|
|
776
|
-
});
|
|
777
|
-
// User has all required permissions
|
|
778
|
-
console.log("Access granted");
|
|
779
|
-
} catch (error) {
|
|
780
|
-
if (error instanceof PermissionError) {
|
|
781
|
-
console.log("Missing permissions:", error.missing_permissions);
|
|
782
|
-
console.log("User permissions:", error.user_permissions);
|
|
783
|
-
console.log("User-friendly message:", error.user_friendly_message);
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
// Server-side - non-strict mode (returns status)
|
|
788
|
-
const authResult = await hazo_get_auth(request, {
|
|
789
|
-
required_permissions: ["admin_user_management"],
|
|
790
|
-
strict: false,
|
|
791
|
-
});
|
|
792
|
-
|
|
793
|
-
if (authResult.authenticated && authResult.permission_ok) {
|
|
794
|
-
console.log("User has required permissions");
|
|
795
|
-
} else if (authResult.authenticated) {
|
|
796
|
-
console.log("User is missing permissions:", authResult.missing_permissions);
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
// Client-side test
|
|
800
|
-
const { permission_ok, missing_permissions, permissions } = use_hazo_auth({
|
|
801
|
-
required_permissions: ["admin_user_management"],
|
|
802
|
-
});
|
|
803
|
-
|
|
804
|
-
if (permission_ok) {
|
|
805
|
-
console.log("User has required permissions");
|
|
806
|
-
} else {
|
|
807
|
-
console.log("Missing permissions:", missing_permissions);
|
|
808
|
-
console.log("User permissions:", permissions);
|
|
809
|
-
}
|
|
810
743
|
```
|
|
811
744
|
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
To get all permissions for the current user:
|
|
815
|
-
|
|
816
|
-
```typescript
|
|
817
|
-
// Server-side
|
|
818
|
-
const authResult = await hazo_get_auth(request);
|
|
819
|
-
if (authResult.authenticated) {
|
|
820
|
-
console.log("All user permissions:", authResult.permissions);
|
|
821
|
-
// Check if user has a specific permission
|
|
822
|
-
const hasPermission = authResult.permissions.includes("admin_user_management");
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
// Client-side
|
|
826
|
-
const { permissions } = use_hazo_auth();
|
|
827
|
-
console.log("All user permissions:", permissions);
|
|
828
|
-
const hasPermission = permissions.includes("admin_user_management");
|
|
829
|
-
```
|
|
830
|
-
|
|
831
|
-
#### Testing in API Routes
|
|
832
|
-
|
|
833
|
-
Example of a protected API route with permission checking:
|
|
834
|
-
|
|
835
|
-
```typescript
|
|
836
|
-
// src/app/api/admin/users/route.ts
|
|
837
|
-
import { NextRequest, NextResponse } from "next/server";
|
|
838
|
-
import { hazo_get_auth } from "hazo_auth/lib/auth/hazo_get_auth.server";
|
|
839
|
-
import { PermissionError } from "hazo_auth/lib/auth/auth_types";
|
|
840
|
-
|
|
841
|
-
export async function GET(request: NextRequest) {
|
|
842
|
-
try {
|
|
843
|
-
// Require authentication and specific permission
|
|
844
|
-
const authResult = await hazo_get_auth(request, {
|
|
845
|
-
required_permissions: ["admin_user_management"],
|
|
846
|
-
strict: true,
|
|
847
|
-
});
|
|
848
|
-
|
|
849
|
-
// Fetch users (only accessible to admins)
|
|
850
|
-
const users = await fetchUsers();
|
|
851
|
-
|
|
852
|
-
return NextResponse.json({ users });
|
|
853
|
-
} catch (error) {
|
|
854
|
-
if (error instanceof PermissionError) {
|
|
855
|
-
return NextResponse.json(
|
|
856
|
-
{
|
|
857
|
-
error: "Permission denied",
|
|
858
|
-
missing_permissions: error.missing_permissions,
|
|
859
|
-
user_friendly_message: error.user_friendly_message,
|
|
860
|
-
},
|
|
861
|
-
{ status: 403 }
|
|
862
|
-
);
|
|
863
|
-
}
|
|
864
|
-
|
|
865
|
-
return NextResponse.json(
|
|
866
|
-
{ error: "Authentication required" },
|
|
867
|
-
{ status: 401 }
|
|
868
|
-
);
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
```
|
|
872
|
-
|
|
873
|
-
#### Testing in React Components
|
|
874
|
-
|
|
875
|
-
Example of a protected component with permission-based UI:
|
|
876
|
-
|
|
877
|
-
```typescript
|
|
878
|
-
"use client";
|
|
879
|
-
|
|
880
|
-
import { use_hazo_auth } from "hazo_auth/components/layouts/shared/hooks/use_hazo_auth";
|
|
881
|
-
|
|
882
|
-
export function AdminDashboard() {
|
|
883
|
-
const userManagementAuth = use_hazo_auth({
|
|
884
|
-
required_permissions: ["admin_user_management"],
|
|
885
|
-
});
|
|
886
|
-
|
|
887
|
-
const roleManagementAuth = use_hazo_auth({
|
|
888
|
-
required_permissions: ["admin_role_management"],
|
|
889
|
-
});
|
|
890
|
-
|
|
891
|
-
if (userManagementAuth.loading || roleManagementAuth.loading) {
|
|
892
|
-
return <div>Loading...</div>;
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
if (!userManagementAuth.authenticated) {
|
|
896
|
-
return <div>Please log in to access this page.</div>;
|
|
897
|
-
}
|
|
898
|
-
|
|
899
|
-
return (
|
|
900
|
-
<div>
|
|
901
|
-
<h1>Admin Dashboard</h1>
|
|
902
|
-
{userManagementAuth.permission_ok && (
|
|
903
|
-
<section>
|
|
904
|
-
<h2>User Management</h2>
|
|
905
|
-
{/* User management UI */}
|
|
906
|
-
</section>
|
|
907
|
-
)}
|
|
908
|
-
{roleManagementAuth.permission_ok && (
|
|
909
|
-
<section>
|
|
910
|
-
<h2>Role Management</h2>
|
|
911
|
-
{/* Role management UI */}
|
|
912
|
-
</section>
|
|
913
|
-
)}
|
|
914
|
-
{!userManagementAuth.permission_ok && !roleManagementAuth.permission_ok && (
|
|
915
|
-
<div>You don't have permission to access any admin features.</div>
|
|
916
|
-
)}
|
|
917
|
-
</div>
|
|
918
|
-
);
|
|
919
|
-
}
|
|
920
|
-
```
|
|
921
|
-
|
|
922
|
-
### Cache Invalidation
|
|
923
|
-
|
|
924
|
-
The authentication cache is automatically invalidated in the following scenarios:
|
|
925
|
-
- User logout
|
|
926
|
-
- Password change
|
|
927
|
-
- User deactivation
|
|
928
|
-
- Role assignment changes
|
|
929
|
-
- Permission changes to roles
|
|
930
|
-
|
|
931
|
-
You can also manually invalidate the cache using the API endpoint:
|
|
932
|
-
|
|
933
|
-
```typescript
|
|
934
|
-
// POST /api/hazo_auth/invalidate_cache
|
|
935
|
-
// Body: { user_id?: string, role_ids?: number[], invalidate_all?: boolean }
|
|
936
|
-
```
|
|
745
|
+
---
|
|
937
746
|
|
|
938
747
|
## Profile Picture Menu Widget
|
|
939
748
|
|
|
@@ -962,357 +771,157 @@ export function Navbar() {
|
|
|
962
771
|
}
|
|
963
772
|
```
|
|
964
773
|
|
|
965
|
-
### Direct Usage (Manual Configuration)
|
|
966
|
-
|
|
967
|
-
If you prefer to configure the component directly without using the config file:
|
|
968
|
-
|
|
969
|
-
```typescript
|
|
970
|
-
"use client";
|
|
971
|
-
|
|
972
|
-
import { ProfilePicMenu } from "hazo_auth/components/layouts/shared/components/profile_pic_menu";
|
|
973
|
-
|
|
974
|
-
export function Navbar() {
|
|
975
|
-
return (
|
|
976
|
-
<nav className="flex items-center justify-between p-4">
|
|
977
|
-
<div>Logo</div>
|
|
978
|
-
<ProfilePicMenu
|
|
979
|
-
show_single_button={false}
|
|
980
|
-
sign_up_label="Sign Up"
|
|
981
|
-
sign_in_label="Sign In"
|
|
982
|
-
register_path="/hazo_auth/register"
|
|
983
|
-
login_path="/hazo_auth/login"
|
|
984
|
-
settings_path="/hazo_auth/my_settings"
|
|
985
|
-
logout_path="/api/hazo_auth/logout"
|
|
986
|
-
avatar_size="default"
|
|
987
|
-
className="ml-auto"
|
|
988
|
-
/>
|
|
989
|
-
</nav>
|
|
990
|
-
);
|
|
991
|
-
}
|
|
992
|
-
```
|
|
993
|
-
|
|
994
774
|
### Configuration
|
|
995
775
|
|
|
996
|
-
Configure the Profile Picture Menu in `hazo_auth_config.ini` under the `[hazo_auth__profile_pic_menu]` section:
|
|
997
|
-
|
|
998
776
|
```ini
|
|
999
777
|
[hazo_auth__profile_pic_menu]
|
|
1000
|
-
# Button configuration for unauthenticated users
|
|
1001
|
-
# Show only "Sign Up" button when true, show both "Sign Up" and "Sign In" buttons when false (default)
|
|
1002
778
|
show_single_button = false
|
|
1003
|
-
|
|
1004
|
-
# Sign up button label
|
|
1005
779
|
sign_up_label = Sign Up
|
|
1006
|
-
|
|
1007
|
-
# Sign in button label
|
|
1008
780
|
sign_in_label = Sign In
|
|
1009
|
-
|
|
1010
|
-
# Register page path
|
|
1011
781
|
register_path = /hazo_auth/register
|
|
1012
|
-
|
|
1013
|
-
# Login page path
|
|
1014
782
|
login_path = /hazo_auth/login
|
|
1015
|
-
|
|
1016
|
-
# Settings page path (shown in dropdown menu when authenticated)
|
|
1017
783
|
settings_path = /hazo_auth/my_settings
|
|
1018
|
-
|
|
1019
|
-
# Logout API endpoint path
|
|
1020
784
|
logout_path = /api/hazo_auth/logout
|
|
1021
|
-
|
|
1022
785
|
# Custom menu items (optional)
|
|
1023
|
-
|
|
1024
|
-
# Examples:
|
|
1025
|
-
# - Info item: "info:Phone:+1234567890:3"
|
|
1026
|
-
# - Link item: "link:My Account:/account:4"
|
|
1027
|
-
# - Separator: "separator:2"
|
|
1028
|
-
# Custom items are added to the default menu items (name, email, separator, Settings, Logout)
|
|
1029
|
-
# Items are sorted by type (info first, then separators, then links) and then by order within each type
|
|
1030
|
-
custom_menu_items =
|
|
786
|
+
custom_menu_items = info:Phone:+1234567890:3,separator:2,link:My Account:/account:4
|
|
1031
787
|
```
|
|
1032
788
|
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
#### `ProfilePicMenuWrapper` Props
|
|
789
|
+
---
|
|
1036
790
|
|
|
1037
|
-
|
|
1038
|
-
- `avatar_size?: "sm" | "default" | "lg"` - Size of the profile picture avatar (default: "default")
|
|
1039
|
-
|
|
1040
|
-
#### `ProfilePicMenu` Props
|
|
1041
|
-
|
|
1042
|
-
- `show_single_button?: boolean` - Show only "Sign Up" button when true (default: false)
|
|
1043
|
-
- `sign_up_label?: string` - Label for sign up button (default: "Sign Up")
|
|
1044
|
-
- `sign_in_label?: string` - Label for sign in button (default: "Sign In")
|
|
1045
|
-
- `register_path?: string` - Path to registration page (default: "/hazo_auth/register")
|
|
1046
|
-
- `login_path?: string` - Path to login page (default: "/hazo_auth/login")
|
|
1047
|
-
- `settings_path?: string` - Path to settings page (default: "/hazo_auth/my_settings")
|
|
1048
|
-
- `logout_path?: string` - Path to logout API endpoint (default: "/api/hazo_auth/logout")
|
|
1049
|
-
- `custom_menu_items?: ProfilePicMenuMenuItem[]` - Array of custom menu items
|
|
1050
|
-
- `className?: string` - Additional CSS classes
|
|
1051
|
-
- `avatar_size?: "sm" | "default" | "lg"` - Size of the profile picture avatar (default: "default")
|
|
791
|
+
## User Profile Service
|
|
1052
792
|
|
|
1053
|
-
|
|
793
|
+
The `hazo_auth` package provides a batch user profile retrieval service for applications that need basic user information, such as chat applications or user lists.
|
|
1054
794
|
|
|
1055
|
-
|
|
795
|
+
### `hazo_get_user_profiles`
|
|
1056
796
|
|
|
1057
|
-
|
|
797
|
+
Retrieves basic profile information for multiple users in a single batch call.
|
|
1058
798
|
|
|
1059
|
-
|
|
1060
|
-
- Format: `"info:label:value:order"`
|
|
1061
|
-
- Example: `"info:Phone:+1234567890:3"`
|
|
799
|
+
**Location:** `src/lib/services/user_profiles_service.ts`
|
|
1062
800
|
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
801
|
+
```typescript
|
|
802
|
+
import { hazo_get_user_profiles } from "hazo_auth/lib/services/user_profiles_service";
|
|
803
|
+
import { get_hazo_connect_instance } from "hazo_auth/server/hazo_connect_instance.server";
|
|
1066
804
|
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
805
|
+
export async function GET(request: NextRequest) {
|
|
806
|
+
const adapter = get_hazo_connect_instance();
|
|
807
|
+
|
|
808
|
+
const result = await hazo_get_user_profiles(adapter, [
|
|
809
|
+
"user-id-1",
|
|
810
|
+
"user-id-2",
|
|
811
|
+
"user-id-3",
|
|
812
|
+
]);
|
|
1070
813
|
|
|
1071
|
-
|
|
814
|
+
if (!result.success) {
|
|
815
|
+
return NextResponse.json({ error: result.error }, { status: 500 });
|
|
816
|
+
}
|
|
1072
817
|
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
818
|
+
return NextResponse.json({
|
|
819
|
+
profiles: result.profiles,
|
|
820
|
+
not_found: result.not_found_ids,
|
|
821
|
+
});
|
|
822
|
+
}
|
|
1077
823
|
```
|
|
1078
824
|
|
|
1079
|
-
|
|
1080
|
-
1. Default items (name, email, separator, Settings, Logout)
|
|
1081
|
-
2. Custom info item: "Phone: +1234567890" (order 3)
|
|
1082
|
-
3. Custom separator (order 2)
|
|
1083
|
-
4. Custom link: "My Account" → `/account` (order 4)
|
|
1084
|
-
5. Custom link: "Help" → `/help` (order 5)
|
|
825
|
+
---
|
|
1085
826
|
|
|
1086
|
-
|
|
827
|
+
## Local Development (for package contributors)
|
|
1087
828
|
|
|
1088
|
-
###
|
|
829
|
+
### Prerequisites
|
|
1089
830
|
|
|
1090
|
-
|
|
1091
|
-
-
|
|
1092
|
-
- User's email address
|
|
1093
|
-
- Separator
|
|
1094
|
-
- Settings link (with Settings icon)
|
|
1095
|
-
- Logout link (with LogOut icon, triggers logout action)
|
|
831
|
+
- Node.js 18+
|
|
832
|
+
- npm 9+
|
|
1096
833
|
|
|
1097
|
-
###
|
|
834
|
+
### Setup
|
|
1098
835
|
|
|
1099
|
-
|
|
836
|
+
```bash
|
|
837
|
+
# Clone the repository
|
|
838
|
+
git clone <repository-url>
|
|
839
|
+
cd hazo_auth
|
|
1100
840
|
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
import { ProfilePicMenuWrapper } from "hazo_auth/components/layouts/shared/components/profile_pic_menu_wrapper";
|
|
841
|
+
# Install dependencies
|
|
842
|
+
npm install
|
|
1104
843
|
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
<nav className="container mx-auto flex items-center justify-between p-4">
|
|
1109
|
-
<div className="text-xl font-bold">My App</div>
|
|
1110
|
-
<ProfilePicMenuWrapper />
|
|
1111
|
-
</nav>
|
|
1112
|
-
</header>
|
|
1113
|
-
);
|
|
1114
|
-
}
|
|
844
|
+
# Copy configuration files
|
|
845
|
+
cp hazo_auth_config.example.ini hazo_auth_config.ini
|
|
846
|
+
cp hazo_notify_config.example.ini hazo_notify_config.ini
|
|
1115
847
|
```
|
|
1116
848
|
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
```typescript
|
|
1120
|
-
// app/components/navbar.tsx
|
|
1121
|
-
import { ProfilePicMenuWrapper } from "hazo_auth/components/layouts/shared/components/profile_pic_menu_wrapper";
|
|
849
|
+
### Development Commands
|
|
1122
850
|
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
<nav className="container mx-auto flex items-center justify-between p-4">
|
|
1127
|
-
<div className="text-xl font-bold">My App</div>
|
|
1128
|
-
<ProfilePicMenuWrapper
|
|
1129
|
-
avatar_size="sm"
|
|
1130
|
-
className="bg-slate-800 rounded-lg p-2"
|
|
1131
|
-
/>
|
|
1132
|
-
</nav>
|
|
1133
|
-
</header>
|
|
1134
|
-
);
|
|
1135
|
-
}
|
|
1136
|
-
```
|
|
851
|
+
```bash
|
|
852
|
+
# Start development server
|
|
853
|
+
npm run dev
|
|
1137
854
|
|
|
1138
|
-
|
|
855
|
+
# Run Storybook
|
|
856
|
+
npm run storybook
|
|
1139
857
|
|
|
1140
|
-
|
|
1141
|
-
|
|
858
|
+
# Build the package for distribution
|
|
859
|
+
npm run build:pkg
|
|
1142
860
|
|
|
1143
|
-
|
|
1144
|
-
|
|
861
|
+
# Run tests
|
|
862
|
+
npm test
|
|
1145
863
|
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
{
|
|
1149
|
-
type: "info",
|
|
1150
|
-
label: "Department",
|
|
1151
|
-
value: "Engineering",
|
|
1152
|
-
order: 3,
|
|
1153
|
-
id: "dept_info",
|
|
1154
|
-
},
|
|
1155
|
-
{
|
|
1156
|
-
type: "separator",
|
|
1157
|
-
order: 2,
|
|
1158
|
-
id: "custom_sep",
|
|
1159
|
-
},
|
|
1160
|
-
{
|
|
1161
|
-
type: "link",
|
|
1162
|
-
label: "Documentation",
|
|
1163
|
-
href: "/docs",
|
|
1164
|
-
order: 4,
|
|
1165
|
-
id: "docs_link",
|
|
1166
|
-
},
|
|
1167
|
-
];
|
|
864
|
+
# Initialize database users/roles
|
|
865
|
+
npm run init-users
|
|
1168
866
|
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
<div>Logo</div>
|
|
1172
|
-
<ProfilePicMenu
|
|
1173
|
-
custom_menu_items={customItems}
|
|
1174
|
-
avatar_size="default"
|
|
1175
|
-
/>
|
|
1176
|
-
</nav>
|
|
1177
|
-
);
|
|
1178
|
-
}
|
|
867
|
+
# Apply database migrations
|
|
868
|
+
npx tsx scripts/apply_migration.ts [migration_file_path]
|
|
1179
869
|
```
|
|
1180
870
|
|
|
1181
|
-
|
|
871
|
+
### Project Structure
|
|
1182
872
|
|
|
1183
|
-
```typescript
|
|
1184
|
-
// In hazo_auth_config.ini
|
|
1185
|
-
[hazo_auth__profile_pic_menu]
|
|
1186
|
-
show_single_button = true
|
|
1187
|
-
sign_up_label = Get Started
|
|
1188
873
|
```
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
Example custom styling:
|
|
1209
|
-
|
|
1210
|
-
```css
|
|
1211
|
-
/* Target specific elements */
|
|
1212
|
-
.cls_profile_pic_menu_avatar {
|
|
1213
|
-
border: 2px solid #3b82f6;
|
|
1214
|
-
}
|
|
1215
|
-
|
|
1216
|
-
.cls_profile_pic_menu_dropdown {
|
|
1217
|
-
min-width: 200px;
|
|
1218
|
-
}
|
|
874
|
+
hazo_auth/
|
|
875
|
+
├── src/
|
|
876
|
+
│ ├── app/ # Next.js app directory (demo pages)
|
|
877
|
+
│ ├── components/ # React components
|
|
878
|
+
│ │ ├── layouts/ # Layout components (login, register, etc.)
|
|
879
|
+
│ │ └── ui/ # Reusable UI components (shadcn-based)
|
|
880
|
+
│ ├── hooks/ # Client-side React hooks
|
|
881
|
+
│ ├── lib/ # Shared utilities and services
|
|
882
|
+
│ │ ├── auth/ # Authentication utilities
|
|
883
|
+
│ │ ├── config/ # Configuration loaders
|
|
884
|
+
│ │ └── services/ # Business logic services
|
|
885
|
+
│ ├── server/ # Server-only utilities
|
|
886
|
+
│ └── index.ts # Main entry point
|
|
887
|
+
├── dist/ # Compiled package output
|
|
888
|
+
├── migrations/ # Database migration files
|
|
889
|
+
├── scripts/ # Utility scripts
|
|
890
|
+
├── __tests__/ # Test files and fixtures
|
|
891
|
+
└── public/ # Static assets
|
|
1219
892
|
```
|
|
1220
893
|
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
The `hazo_auth` package provides a batch user profile retrieval service for applications that need basic user information, such as chat applications or user lists.
|
|
1224
|
-
|
|
1225
|
-
### `hazo_get_user_profiles`
|
|
1226
|
-
|
|
1227
|
-
Retrieves basic profile information for multiple users in a single batch call.
|
|
894
|
+
### Building the Package
|
|
1228
895
|
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
**Function Signature:**
|
|
1232
|
-
```typescript
|
|
1233
|
-
import { hazo_get_user_profiles } from "hazo_auth/lib/services/user_profiles_service";
|
|
1234
|
-
import type { GetProfilesResult, UserProfileInfo } from "hazo_auth/lib/services/user_profiles_service";
|
|
1235
|
-
|
|
1236
|
-
async function hazo_get_user_profiles(
|
|
1237
|
-
adapter: HazoConnectAdapter,
|
|
1238
|
-
user_ids: string[],
|
|
1239
|
-
): Promise<GetProfilesResult>
|
|
1240
|
-
```
|
|
896
|
+
The package is built using TypeScript with a separate build configuration:
|
|
1241
897
|
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
type UserProfileInfo = {
|
|
1245
|
-
user_id: string;
|
|
1246
|
-
profile_picture_url: string | null;
|
|
1247
|
-
email: string;
|
|
1248
|
-
name: string | null;
|
|
1249
|
-
days_since_created: number;
|
|
1250
|
-
};
|
|
1251
|
-
|
|
1252
|
-
type GetProfilesResult = {
|
|
1253
|
-
success: boolean;
|
|
1254
|
-
profiles: UserProfileInfo[];
|
|
1255
|
-
not_found_ids: string[];
|
|
1256
|
-
error?: string;
|
|
1257
|
-
};
|
|
898
|
+
```bash
|
|
899
|
+
npm run build:pkg
|
|
1258
900
|
```
|
|
1259
901
|
|
|
1260
|
-
|
|
1261
|
-
-
|
|
1262
|
-
-
|
|
1263
|
-
-
|
|
1264
|
-
- **Profile Picture:** Returns the resolved profile picture URL (Gravatar, library, or uploaded)
|
|
1265
|
-
- **Account Age:** Calculates days since account creation
|
|
902
|
+
This compiles the `src/` directory to `dist/` with:
|
|
903
|
+
- Type declarations (`.d.ts` files)
|
|
904
|
+
- ES modules output
|
|
905
|
+
- Excludes Next.js app directory and Storybook stories
|
|
1266
906
|
|
|
1267
|
-
|
|
907
|
+
### Package Exports
|
|
1268
908
|
|
|
1269
|
-
|
|
1270
|
-
// In an API route or server component
|
|
1271
|
-
import { hazo_get_user_profiles } from "hazo_auth/lib/services/user_profiles_service";
|
|
1272
|
-
import { get_hazo_connect_instance } from "hazo_auth/lib/hazo_connect_instance.server";
|
|
909
|
+
The `package.json` exports field defines the public API:
|
|
1273
910
|
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
"
|
|
1280
|
-
"
|
|
1281
|
-
"
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
if (!result.success) {
|
|
1285
|
-
return NextResponse.json({ error: result.error }, { status: 500 });
|
|
911
|
+
```json
|
|
912
|
+
{
|
|
913
|
+
"exports": {
|
|
914
|
+
".": "./dist/index.js",
|
|
915
|
+
"./components/*": "./dist/components/*.js",
|
|
916
|
+
"./components/ui/*": "./dist/components/ui/*.js",
|
|
917
|
+
"./components/layouts/*": "./dist/components/layouts/*.js",
|
|
918
|
+
"./lib/*": "./dist/lib/*.js",
|
|
919
|
+
"./hooks/*": "./dist/hooks/*.js",
|
|
920
|
+
"./server/*": "./dist/server/*.js"
|
|
1286
921
|
}
|
|
1287
|
-
|
|
1288
|
-
// result.profiles contains found user profiles
|
|
1289
|
-
// result.not_found_ids contains IDs that weren't found
|
|
1290
|
-
return NextResponse.json({
|
|
1291
|
-
profiles: result.profiles,
|
|
1292
|
-
not_found: result.not_found_ids,
|
|
1293
|
-
});
|
|
1294
922
|
}
|
|
1295
923
|
```
|
|
1296
924
|
|
|
1297
|
-
**Use Cases:**
|
|
1298
|
-
- Chat applications displaying participant information
|
|
1299
|
-
- User lists with profile pictures and names
|
|
1300
|
-
- Activity feeds showing user details
|
|
1301
|
-
- Any feature requiring batch user profile lookups
|
|
1302
|
-
|
|
1303
|
-
### Local Development (for package contributors)
|
|
1304
|
-
|
|
1305
|
-
- `npm install` to install dependencies.
|
|
1306
|
-
- `npm run dev` launches the Next.js app at `http://localhost:3000`.
|
|
1307
|
-
- `npm run storybook` launches Storybook at `http://localhost:6006`.
|
|
1308
|
-
|
|
1309
|
-
### Project Structure
|
|
1310
|
-
|
|
1311
|
-
- `src/app` contains the application shell and route composition.
|
|
1312
|
-
- `src/lib` is the home for shared utilities and authentication functions.
|
|
1313
|
-
- `src/components` contains React components and hooks.
|
|
1314
|
-
- `src/stories` holds Storybook stories for documenting components.
|
|
1315
|
-
|
|
1316
925
|
### Next Steps
|
|
1317
926
|
|
|
1318
927
|
- Use `npx shadcn@latest add <component>` to scaffold new UI primitives.
|