hazo_auth 4.6.2 → 5.1.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 +41 -8
- package/bin/hazo_auth.mjs +0 -0
- package/cli-src/cli/index.ts +12 -0
- package/cli-src/cli/init_permissions.ts +164 -0
- package/cli-src/cli/init_users.ts +92 -2
- package/cli-src/lib/app_permissions_config.server.ts +94 -0
- package/cli-src/lib/app_user_data_config.server.ts +191 -0
- package/cli-src/lib/auth/auth_types.ts +14 -53
- package/cli-src/lib/auth/auth_utils.server.ts +6 -6
- package/cli-src/lib/auth/hazo_get_auth.server.ts +55 -162
- package/cli-src/lib/auth/scope_cache.ts +15 -23
- package/cli-src/lib/auth/server_auth.ts +3 -3
- package/cli-src/lib/config/default_config.ts +0 -13
- package/cli-src/lib/scope_hierarchy_config.server.ts +19 -76
- package/cli-src/lib/services/firm_service.ts +320 -0
- package/cli-src/lib/services/index.ts +6 -0
- package/cli-src/lib/services/invitation_service.ts +542 -0
- package/cli-src/lib/services/login_service.ts +2 -2
- package/cli-src/lib/services/oauth_service.ts +1 -1
- package/cli-src/lib/services/post_verification_service.ts +231 -0
- package/cli-src/lib/services/registration_service.ts +1 -1
- package/cli-src/lib/services/scope_service.ts +273 -243
- package/cli-src/lib/services/user_scope_service.ts +189 -158
- package/dist/cli/index.js +11 -0
- package/dist/cli/init_permissions.d.ts +11 -0
- package/dist/cli/init_permissions.d.ts.map +1 -0
- package/dist/cli/init_permissions.js +138 -0
- package/dist/cli/init_users.d.ts.map +1 -1
- package/dist/cli/init_users.js +78 -2
- package/dist/components/layouts/create_firm/hooks/use_create_firm_form.d.ts +32 -0
- package/dist/components/layouts/create_firm/hooks/use_create_firm_form.d.ts.map +1 -0
- package/dist/components/layouts/create_firm/hooks/use_create_firm_form.js +99 -0
- package/dist/components/layouts/create_firm/index.d.ts +44 -0
- package/dist/components/layouts/create_firm/index.d.ts.map +1 -0
- package/dist/components/layouts/create_firm/index.js +40 -0
- package/dist/components/layouts/shared/components/form_action_buttons.d.ts +5 -3
- package/dist/components/layouts/shared/components/form_action_buttons.d.ts.map +1 -1
- package/dist/components/layouts/shared/components/form_action_buttons.js +3 -3
- package/dist/components/layouts/shared/components/standalone_layout_wrapper.d.ts.map +1 -1
- package/dist/components/layouts/shared/components/standalone_layout_wrapper.js +4 -1
- package/dist/components/layouts/user_management/components/app_user_data_editor.d.ts +12 -0
- package/dist/components/layouts/user_management/components/app_user_data_editor.d.ts.map +1 -0
- package/dist/components/layouts/user_management/components/app_user_data_editor.js +204 -0
- package/dist/components/layouts/user_management/components/scope_hierarchy_tab.d.ts +1 -2
- package/dist/components/layouts/user_management/components/scope_hierarchy_tab.d.ts.map +1 -1
- package/dist/components/layouts/user_management/components/scope_hierarchy_tab.js +31 -87
- package/dist/components/layouts/user_management/components/user_scopes_tab.d.ts.map +1 -1
- package/dist/components/layouts/user_management/components/user_scopes_tab.js +12 -27
- package/dist/components/layouts/user_management/index.d.ts +1 -3
- package/dist/components/layouts/user_management/index.d.ts.map +1 -1
- package/dist/components/layouts/user_management/index.js +63 -187
- package/dist/lib/app_permissions_config.server.d.ts +37 -0
- package/dist/lib/app_permissions_config.server.d.ts.map +1 -0
- package/dist/lib/app_permissions_config.server.js +64 -0
- package/dist/lib/app_user_data_config.server.d.ts +57 -0
- package/dist/lib/app_user_data_config.server.d.ts.map +1 -0
- package/dist/lib/app_user_data_config.server.js +132 -0
- package/dist/lib/auth/auth_types.d.ts +13 -47
- package/dist/lib/auth/auth_types.d.ts.map +1 -1
- package/dist/lib/auth/auth_types.js +7 -17
- package/dist/lib/auth/auth_utils.server.js +6 -6
- package/dist/lib/auth/hazo_get_auth.server.d.ts +2 -2
- package/dist/lib/auth/hazo_get_auth.server.d.ts.map +1 -1
- package/dist/lib/auth/hazo_get_auth.server.js +25 -121
- package/dist/lib/auth/scope_cache.d.ts +6 -8
- package/dist/lib/auth/scope_cache.d.ts.map +1 -1
- package/dist/lib/auth/scope_cache.js +13 -14
- package/dist/lib/auth/server_auth.js +3 -3
- package/dist/lib/config/default_config.d.ts +0 -20
- package/dist/lib/config/default_config.d.ts.map +1 -1
- package/dist/lib/config/default_config.js +0 -12
- package/dist/lib/scope_hierarchy_config.server.d.ts +5 -12
- package/dist/lib/scope_hierarchy_config.server.d.ts.map +1 -1
- package/dist/lib/scope_hierarchy_config.server.js +6 -57
- package/dist/lib/services/firm_service.d.ts +38 -0
- package/dist/lib/services/firm_service.d.ts.map +1 -0
- package/dist/lib/services/firm_service.js +261 -0
- package/dist/lib/services/index.d.ts +6 -0
- package/dist/lib/services/index.d.ts.map +1 -1
- package/dist/lib/services/index.js +6 -0
- package/dist/lib/services/invitation_service.d.ts +66 -0
- package/dist/lib/services/invitation_service.d.ts.map +1 -0
- package/dist/lib/services/invitation_service.js +422 -0
- package/dist/lib/services/login_service.js +2 -2
- package/dist/lib/services/oauth_service.js +1 -1
- package/dist/lib/services/post_verification_service.d.ts +45 -0
- package/dist/lib/services/post_verification_service.d.ts.map +1 -0
- package/dist/lib/services/post_verification_service.js +164 -0
- package/dist/lib/services/registration_service.js +1 -1
- package/dist/lib/services/scope_service.d.ts +53 -57
- package/dist/lib/services/scope_service.d.ts.map +1 -1
- package/dist/lib/services/scope_service.js +241 -175
- package/dist/lib/services/user_scope_service.d.ts +39 -21
- package/dist/lib/services/user_scope_service.d.ts.map +1 -1
- package/dist/lib/services/user_scope_service.js +146 -112
- package/dist/page_components/create_firm.d.ts +7 -0
- package/dist/page_components/create_firm.d.ts.map +1 -0
- package/dist/page_components/create_firm.js +31 -0
- package/dist/page_components/index.d.ts +1 -1
- package/dist/page_components/index.d.ts.map +1 -1
- package/dist/page_components/index.js +1 -1
- package/dist/server/routes/create_firm.d.ts +2 -0
- package/dist/server/routes/create_firm.d.ts.map +1 -0
- package/dist/server/routes/create_firm.js +2 -0
- package/dist/server/routes/index.d.ts +2 -1
- package/dist/server/routes/index.d.ts.map +1 -1
- package/dist/server/routes/index.js +4 -2
- package/dist/server/routes/invitations.d.ts +2 -0
- package/dist/server/routes/invitations.d.ts.map +1 -0
- package/dist/server/routes/invitations.js +2 -0
- package/package.json +12 -8
- package/public/hazo_auth/images/new_firm_default.jpg +0 -0
- package/dist/app/api/hazo_auth/app_user_data/route.d.ts +0 -64
- package/dist/app/api/hazo_auth/app_user_data/route.d.ts.map +0 -1
- package/dist/app/api/hazo_auth/app_user_data/route.js +0 -208
- package/dist/app/api/hazo_auth/change_password/route.d.ts +0 -8
- package/dist/app/api/hazo_auth/change_password/route.d.ts.map +0 -1
- package/dist/app/api/hazo_auth/change_password/route.js +0 -98
- package/dist/app/api/hazo_auth/forgot_password/route.d.ts +0 -8
- package/dist/app/api/hazo_auth/forgot_password/route.d.ts.map +0 -1
- package/dist/app/api/hazo_auth/forgot_password/route.js +0 -93
- package/dist/app/api/hazo_auth/get_auth/route.d.ts +0 -10
- package/dist/app/api/hazo_auth/get_auth/route.d.ts.map +0 -1
- package/dist/app/api/hazo_auth/get_auth/route.js +0 -63
- package/dist/app/api/hazo_auth/invalidate_cache/route.d.ts +0 -14
- package/dist/app/api/hazo_auth/invalidate_cache/route.d.ts.map +0 -1
- package/dist/app/api/hazo_auth/invalidate_cache/route.js +0 -96
- package/dist/app/api/hazo_auth/library_photo/[category]/[filename]/route.d.ts +0 -9
- package/dist/app/api/hazo_auth/library_photo/[category]/[filename]/route.d.ts.map +0 -1
- package/dist/app/api/hazo_auth/library_photo/[category]/[filename]/route.js +0 -82
- package/dist/app/api/hazo_auth/library_photos/route.d.ts +0 -22
- package/dist/app/api/hazo_auth/library_photos/route.d.ts.map +0 -1
- package/dist/app/api/hazo_auth/library_photos/route.js +0 -80
- package/dist/app/api/hazo_auth/login/route.d.ts +0 -12
- package/dist/app/api/hazo_auth/login/route.d.ts.map +0 -1
- package/dist/app/api/hazo_auth/login/route.js +0 -156
- package/dist/app/api/hazo_auth/logout/route.d.ts +0 -8
- package/dist/app/api/hazo_auth/logout/route.d.ts.map +0 -1
- package/dist/app/api/hazo_auth/logout/route.js +0 -103
- package/dist/app/api/hazo_auth/me/route.d.ts +0 -36
- package/dist/app/api/hazo_auth/me/route.d.ts.map +0 -1
- package/dist/app/api/hazo_auth/me/route.js +0 -132
- package/dist/app/api/hazo_auth/org_management/orgs/route.d.ts +0 -26
- package/dist/app/api/hazo_auth/org_management/orgs/route.d.ts.map +0 -1
- package/dist/app/api/hazo_auth/org_management/orgs/route.js +0 -315
- package/dist/app/api/hazo_auth/profile_picture/[filename]/route.d.ts +0 -7
- package/dist/app/api/hazo_auth/profile_picture/[filename]/route.d.ts.map +0 -1
- package/dist/app/api/hazo_auth/profile_picture/[filename]/route.js +0 -43
- package/dist/app/api/hazo_auth/register/route.d.ts +0 -9
- package/dist/app/api/hazo_auth/register/route.d.ts.map +0 -1
- package/dist/app/api/hazo_auth/register/route.js +0 -80
- package/dist/app/api/hazo_auth/remove_profile_picture/route.d.ts +0 -8
- package/dist/app/api/hazo_auth/remove_profile_picture/route.d.ts.map +0 -1
- package/dist/app/api/hazo_auth/remove_profile_picture/route.js +0 -64
- package/dist/app/api/hazo_auth/resend_verification/route.d.ts +0 -8
- package/dist/app/api/hazo_auth/resend_verification/route.d.ts.map +0 -1
- package/dist/app/api/hazo_auth/resend_verification/route.js +0 -79
- package/dist/app/api/hazo_auth/reset_password/route.d.ts +0 -8
- package/dist/app/api/hazo_auth/reset_password/route.d.ts.map +0 -1
- package/dist/app/api/hazo_auth/reset_password/route.js +0 -76
- package/dist/app/api/hazo_auth/update_user/route.d.ts +0 -9
- package/dist/app/api/hazo_auth/update_user/route.d.ts.map +0 -1
- package/dist/app/api/hazo_auth/update_user/route.js +0 -98
- package/dist/app/api/hazo_auth/upload_profile_picture/route.d.ts +0 -9
- package/dist/app/api/hazo_auth/upload_profile_picture/route.d.ts.map +0 -1
- package/dist/app/api/hazo_auth/upload_profile_picture/route.js +0 -204
- package/dist/app/api/hazo_auth/user_management/permissions/route.d.ts +0 -50
- package/dist/app/api/hazo_auth/user_management/permissions/route.d.ts.map +0 -1
- package/dist/app/api/hazo_auth/user_management/permissions/route.js +0 -257
- package/dist/app/api/hazo_auth/user_management/roles/route.d.ts +0 -40
- package/dist/app/api/hazo_auth/user_management/roles/route.d.ts.map +0 -1
- package/dist/app/api/hazo_auth/user_management/roles/route.js +0 -352
- package/dist/app/api/hazo_auth/user_management/users/roles/route.d.ts +0 -37
- package/dist/app/api/hazo_auth/user_management/users/roles/route.d.ts.map +0 -1
- package/dist/app/api/hazo_auth/user_management/users/roles/route.js +0 -276
- package/dist/app/api/hazo_auth/user_management/users/route.d.ts +0 -49
- package/dist/app/api/hazo_auth/user_management/users/route.d.ts.map +0 -1
- package/dist/app/api/hazo_auth/user_management/users/route.js +0 -275
- package/dist/app/api/hazo_auth/validate_reset_token/route.d.ts +0 -6
- package/dist/app/api/hazo_auth/validate_reset_token/route.d.ts.map +0 -1
- package/dist/app/api/hazo_auth/validate_reset_token/route.js +0 -58
- package/dist/app/api/hazo_auth/verify_email/route.d.ts +0 -11
- package/dist/app/api/hazo_auth/verify_email/route.d.ts.map +0 -1
- package/dist/app/api/hazo_auth/verify_email/route.js +0 -63
- package/dist/components/layouts/app_user_data_test/index.d.ts +0 -6
- package/dist/components/layouts/app_user_data_test/index.d.ts.map +0 -1
- package/dist/components/layouts/app_user_data_test/index.js +0 -145
- package/dist/components/layouts/org_management/index.d.ts +0 -26
- package/dist/components/layouts/org_management/index.d.ts.map +0 -1
- package/dist/components/layouts/org_management/index.js +0 -75
- package/dist/components/layouts/profile_stamp_test/index.d.ts +0 -10
- package/dist/components/layouts/profile_stamp_test/index.d.ts.map +0 -1
- package/dist/components/layouts/profile_stamp_test/index.js +0 -51
- package/dist/components/layouts/rbac_test/index.d.ts +0 -13
- package/dist/components/layouts/rbac_test/index.d.ts.map +0 -1
- package/dist/components/layouts/rbac_test/index.js +0 -378
- package/dist/components/layouts/user_management/components/org_hierarchy_tab.d.ts +0 -13
- package/dist/components/layouts/user_management/components/org_hierarchy_tab.d.ts.map +0 -1
- package/dist/components/layouts/user_management/components/org_hierarchy_tab.js +0 -276
- package/dist/components/layouts/user_management/components/scope_labels_tab.d.ts +0 -14
- package/dist/components/layouts/user_management/components/scope_labels_tab.d.ts.map +0 -1
- package/dist/components/layouts/user_management/components/scope_labels_tab.js +0 -186
- package/dist/lib/auth/org_cache.d.ts +0 -65
- package/dist/lib/auth/org_cache.d.ts.map +0 -1
- package/dist/lib/auth/org_cache.js +0 -103
- package/dist/lib/multi_tenancy_config.server.d.ts +0 -30
- package/dist/lib/multi_tenancy_config.server.d.ts.map +0 -1
- package/dist/lib/multi_tenancy_config.server.js +0 -41
- package/dist/lib/services/org_service.d.ts +0 -191
- package/dist/lib/services/org_service.d.ts.map +0 -1
- package/dist/lib/services/org_service.js +0 -746
- package/dist/lib/services/scope_labels_service.d.ts +0 -48
- package/dist/lib/services/scope_labels_service.d.ts.map +0 -1
- package/dist/lib/services/scope_labels_service.js +0 -277
- package/dist/page_components/org_management.d.ts +0 -27
- package/dist/page_components/org_management.d.ts.map +0 -1
- package/dist/page_components/org_management.js +0 -18
- package/dist/pages/forgot_password.d.ts +0 -52
- package/dist/pages/forgot_password.d.ts.map +0 -1
- package/dist/pages/forgot_password.js +0 -41
- package/dist/pages/index.d.ts +0 -33
- package/dist/pages/index.d.ts.map +0 -1
- package/dist/pages/index.js +0 -28
- package/dist/pages/login.d.ts +0 -43
- package/dist/pages/login.d.ts.map +0 -1
- package/dist/pages/login.js +0 -45
- package/dist/pages/my_settings.d.ts +0 -54
- package/dist/pages/my_settings.d.ts.map +0 -1
- package/dist/pages/my_settings.js +0 -57
- package/dist/pages/register.d.ts +0 -44
- package/dist/pages/register.d.ts.map +0 -1
- package/dist/pages/register.js +0 -46
- package/dist/pages/reset_password.d.ts +0 -43
- package/dist/pages/reset_password.d.ts.map +0 -1
- package/dist/pages/reset_password.js +0 -42
- package/dist/pages/verify_email.d.ts +0 -52
- package/dist/pages/verify_email.d.ts.map +0 -1
- package/dist/pages/verify_email.js +0 -41
- package/dist/server/logging/logger_service.d.ts +0 -3
- package/dist/server/logging/logger_service.d.ts.map +0 -1
- package/dist/server/logging/logger_service.js +0 -37
- package/dist/server/routes/org_management_orgs.d.ts +0 -2
- package/dist/server/routes/org_management_orgs.d.ts.map +0 -1
- package/dist/server/routes/org_management_orgs.js +0 -2
package/README.md
CHANGED
|
@@ -2,7 +2,34 @@
|
|
|
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
|
-
### What's New in
|
|
5
|
+
### What's New in v5.0 🚀
|
|
6
|
+
|
|
7
|
+
**BREAKING CHANGE: Scope-Based Multi-Tenancy** - Complete architectural redesign for simpler, more flexible multi-tenancy!
|
|
8
|
+
|
|
9
|
+
- ✅ **Unified Scope System** - Single `hazo_scopes` table replaces 8 separate tables (1 org + 7 scope levels)
|
|
10
|
+
- ✅ **Membership-Based** - Users assigned to scopes via `hazo_user_scopes` (not org_id on user record)
|
|
11
|
+
- ✅ **Invitation System** - Built-in invitation flow for onboarding new users to existing scopes
|
|
12
|
+
- ✅ **Create Firm Flow** - New users create their own firm (scope) after email verification
|
|
13
|
+
- ✅ **Post-Verification Routing** - Smart routing after email verification: invitations → create firm → default redirect
|
|
14
|
+
- ✅ **Unlimited Hierarchy** - Flexible parent-child relationships, no fixed depth limit
|
|
15
|
+
- ✅ **Simpler Architecture** - Fewer tables, fewer joins, easier to understand
|
|
16
|
+
- ✅ **New CLI Command** - `npx hazo_auth init-permissions` for flexible permission setup
|
|
17
|
+
|
|
18
|
+
**Migrating from v4.x?** This is a breaking change. Run the migration:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# 1. Backup your database first!
|
|
22
|
+
# 2. Run the scope consolidation migration
|
|
23
|
+
npm run migrate migrations/009_scope_consolidation.sql
|
|
24
|
+
|
|
25
|
+
# 3. Update configuration (remove org settings, add invitation/create firm settings)
|
|
26
|
+
# 4. Update code (remove org-related API calls and components)
|
|
27
|
+
# 5. Test thoroughly
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
See [CHANGE_LOG.md](./CHANGE_LOG.md) for detailed migration guide, rationale, and breaking changes.
|
|
31
|
+
|
|
32
|
+
### What's New in v2.0
|
|
6
33
|
|
|
7
34
|
**Zero-Config Server Components** - Authentication pages now work out-of-the-box with ZERO configuration required!
|
|
8
35
|
|
|
@@ -12,8 +39,6 @@ A reusable authentication UI component package powered by Next.js, TailwindCSS,
|
|
|
12
39
|
- ✅ **Embeddable Components** - MySettings and UserManagement adapt to any layout
|
|
13
40
|
- ✅ **Sensible Defaults** - INI files are now optional, defaults built-in
|
|
14
41
|
|
|
15
|
-
**Migrating from v1.x?** See [MIGRATION.md](./MIGRATION.md) for a complete upgrade guide.
|
|
16
|
-
|
|
17
42
|
### Also Includes (v1.6.6+)
|
|
18
43
|
|
|
19
44
|
- **JWT Session Tokens for Edge-Compatible Authentication**: Secure Edge Runtime authentication in Next.js proxy/middleware files. See [Proxy/Middleware Authentication](#proxymiddleware-authentication) for details.
|
|
@@ -1102,6 +1127,9 @@ The `UserManagementLayout` component provides a comprehensive admin interface fo
|
|
|
1102
1127
|
- `admin_user_management` - Access to Users tab
|
|
1103
1128
|
- `admin_role_management` - Access to Roles tab
|
|
1104
1129
|
- `admin_permission_management` - Access to Permissions tab
|
|
1130
|
+
- `admin_scope_hierarchy_management` - Access to Scope Hierarchy tab (HRBAC)
|
|
1131
|
+
- `admin_system` - Access to Scope Labels tab (HRBAC)
|
|
1132
|
+
- `admin_user_scope_assignment` - Access to User Scopes tab (HRBAC)
|
|
1105
1133
|
|
|
1106
1134
|
**Required API Routes:**
|
|
1107
1135
|
The `UserManagementLayout` component requires the following API routes to be created in your project:
|
|
@@ -1735,7 +1763,8 @@ Users assigned to a higher-level scope automatically have access to all descenda
|
|
|
1735
1763
|
|
|
1736
1764
|
### Required Permissions for Management
|
|
1737
1765
|
|
|
1738
|
-
- `admin_scope_hierarchy_management` - Manage
|
|
1766
|
+
- `admin_scope_hierarchy_management` - Manage scope hierarchy (create, edit, delete scopes)
|
|
1767
|
+
- `admin_system` - System-level administration (scope labels configuration)
|
|
1739
1768
|
- `admin_user_scope_assignment` - Assign scopes to users
|
|
1740
1769
|
- `admin_test_access` - Access the RBAC/HRBAC test tool
|
|
1741
1770
|
|
|
@@ -1743,15 +1772,19 @@ Add these to your `application_permission_list_defaults` in `hazo_auth_config.in
|
|
|
1743
1772
|
|
|
1744
1773
|
```ini
|
|
1745
1774
|
[hazo_auth__user_management]
|
|
1746
|
-
application_permission_list_defaults = admin_user_management,admin_role_management,admin_permission_management,admin_scope_hierarchy_management,admin_user_scope_assignment,admin_test_access
|
|
1775
|
+
application_permission_list_defaults = admin_user_management,admin_role_management,admin_permission_management,admin_scope_hierarchy_management,admin_system,admin_user_scope_assignment,admin_test_access
|
|
1747
1776
|
```
|
|
1748
1777
|
|
|
1749
1778
|
### User Management UI
|
|
1750
1779
|
|
|
1751
1780
|
When HRBAC is enabled and the user has appropriate permissions, three new tabs appear in the User Management layout:
|
|
1752
|
-
- **Scope Hierarchy** - Create, edit, and delete scopes at each level
|
|
1753
|
-
- **Scope Labels** - Customize labels for scope levels per organization
|
|
1754
|
-
- **User Scopes** - Assign and remove scope assignments for users
|
|
1781
|
+
- **Scope Hierarchy** - Create, edit, and delete scopes at each level (requires `admin_scope_hierarchy_management`)
|
|
1782
|
+
- **Scope Labels** - Customize labels for scope levels per organization (requires `admin_system`)
|
|
1783
|
+
- **User Scopes** - Assign and remove scope assignments for users (requires `admin_user_scope_assignment`)
|
|
1784
|
+
|
|
1785
|
+
**Organization Assignment (when multi-tenancy enabled):**
|
|
1786
|
+
- **Global admins** (`hazo_org_global_admin` permission) can assign users to any organization
|
|
1787
|
+
- **Non-global admins** can only assign users to organizations within their own org tree (filtered by `root_org_id`)
|
|
1755
1788
|
|
|
1756
1789
|
### RBAC/HRBAC Test Tool
|
|
1757
1790
|
|
package/bin/hazo_auth.mjs
CHANGED
|
File without changes
|
package/cli-src/cli/index.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { run_validation } from "./validate.js";
|
|
|
7
7
|
import { generate_routes, type GenerateOptions } from "./generate.js";
|
|
8
8
|
import { handle_init } from "./init.js";
|
|
9
9
|
import { handle_init_users, show_init_users_help } from "./init_users.js";
|
|
10
|
+
import { handle_init_permissions, show_init_permissions_help } from "./init_permissions.js";
|
|
10
11
|
|
|
11
12
|
// section: constants
|
|
12
13
|
const VERSION = "1.6.0";
|
|
@@ -18,6 +19,7 @@ Usage: hazo_auth <command> [options]
|
|
|
18
19
|
|
|
19
20
|
Commands:
|
|
20
21
|
init Initialize hazo_auth in your project (creates directories, copies config)
|
|
22
|
+
init-permissions Create default permissions from config (no user required)
|
|
21
23
|
init-users Initialize permissions, roles, and super user from config
|
|
22
24
|
validate Check your hazo_auth setup and configuration
|
|
23
25
|
generate-routes Generate API route files and pages in your project
|
|
@@ -28,6 +30,7 @@ Options:
|
|
|
28
30
|
|
|
29
31
|
Examples:
|
|
30
32
|
npx hazo_auth init
|
|
33
|
+
npx hazo_auth init-permissions
|
|
31
34
|
npx hazo_auth init-users
|
|
32
35
|
npx hazo_auth validate
|
|
33
36
|
npx hazo_auth generate-routes
|
|
@@ -154,6 +157,15 @@ Actions:
|
|
|
154
157
|
handle_init();
|
|
155
158
|
break;
|
|
156
159
|
|
|
160
|
+
case "init-permissions": {
|
|
161
|
+
if (help) {
|
|
162
|
+
show_init_permissions_help();
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
await handle_init_permissions();
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
|
|
157
169
|
case "init-users": {
|
|
158
170
|
if (help) {
|
|
159
171
|
show_init_users_help();
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// file_description: CLI command to initialize permissions from configuration
|
|
2
|
+
// section: imports
|
|
3
|
+
import { randomUUID } from "crypto";
|
|
4
|
+
import { get_hazo_connect_instance } from "../lib/hazo_connect_instance.server.js";
|
|
5
|
+
import { createCrudService } from "hazo_connect/server";
|
|
6
|
+
import { get_user_management_config } from "../lib/user_management_config.server.js";
|
|
7
|
+
import { create_app_logger } from "../lib/app_logger.js";
|
|
8
|
+
|
|
9
|
+
// section: types
|
|
10
|
+
type InitPermissionsSummary = {
|
|
11
|
+
inserted: string[];
|
|
12
|
+
existing: string[];
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
// section: helpers
|
|
16
|
+
/**
|
|
17
|
+
* Prints a summary of what was inserted vs what already existed
|
|
18
|
+
*/
|
|
19
|
+
function print_summary(summary: InitPermissionsSummary): void {
|
|
20
|
+
console.log("=".repeat(60));
|
|
21
|
+
console.log("INITIALIZATION SUMMARY");
|
|
22
|
+
console.log("=".repeat(60));
|
|
23
|
+
console.log();
|
|
24
|
+
|
|
25
|
+
if (summary.inserted.length > 0) {
|
|
26
|
+
console.log(`✓ Inserted (${summary.inserted.length}):`);
|
|
27
|
+
summary.inserted.forEach((name) => console.log(` - ${name}`));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (summary.existing.length > 0) {
|
|
31
|
+
console.log(`⊙ Already existed (${summary.existing.length}):`);
|
|
32
|
+
summary.existing.forEach((name) => console.log(` - ${name}`));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (summary.inserted.length === 0 && summary.existing.length === 0) {
|
|
36
|
+
console.log("No permissions found in configuration.");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
console.log();
|
|
40
|
+
console.log("=".repeat(60));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// section: main_function
|
|
44
|
+
/**
|
|
45
|
+
* Initializes permissions from configuration
|
|
46
|
+
* This function reads from hazo_auth_config.ini and sets up permissions
|
|
47
|
+
* without requiring any users to exist.
|
|
48
|
+
*/
|
|
49
|
+
export async function handle_init_permissions(): Promise<void> {
|
|
50
|
+
const logger = create_app_logger();
|
|
51
|
+
const summary: InitPermissionsSummary = {
|
|
52
|
+
inserted: [],
|
|
53
|
+
existing: [],
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
console.log("\n🐸 hazo_auth init-permissions\n");
|
|
58
|
+
console.log("Creating permissions from configuration...\n");
|
|
59
|
+
|
|
60
|
+
// Get hazo_connect instance
|
|
61
|
+
const hazoConnect = get_hazo_connect_instance();
|
|
62
|
+
const permissions_service = createCrudService(hazoConnect, "hazo_permissions");
|
|
63
|
+
|
|
64
|
+
// Get permissions from config
|
|
65
|
+
const config = get_user_management_config();
|
|
66
|
+
const permission_names = config.application_permission_list_defaults || [];
|
|
67
|
+
|
|
68
|
+
if (permission_names.length === 0) {
|
|
69
|
+
console.log("⚠ No permissions found in configuration.");
|
|
70
|
+
console.log(" Add permissions to [hazo_auth__user_management] application_permission_list_defaults\n");
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
console.log(`Found ${permission_names.length} permission(s) in configuration:`);
|
|
75
|
+
permission_names.forEach((name) => console.log(` - ${name}`));
|
|
76
|
+
console.log();
|
|
77
|
+
|
|
78
|
+
// Add permissions to hazo_permissions table
|
|
79
|
+
const now = new Date().toISOString();
|
|
80
|
+
|
|
81
|
+
for (const permission_name of permission_names) {
|
|
82
|
+
const trimmed_name = permission_name.trim();
|
|
83
|
+
if (!trimmed_name) continue;
|
|
84
|
+
|
|
85
|
+
// Check if permission already exists
|
|
86
|
+
const existing_permissions = await permissions_service.findBy({
|
|
87
|
+
permission_name: trimmed_name,
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
if (Array.isArray(existing_permissions) && existing_permissions.length > 0) {
|
|
91
|
+
const existing_permission = existing_permissions[0];
|
|
92
|
+
const perm_id = existing_permission.id as string;
|
|
93
|
+
summary.existing.push(trimmed_name);
|
|
94
|
+
console.log(`⊙ Permission already exists: ${trimmed_name} (ID: ${perm_id})`);
|
|
95
|
+
} else {
|
|
96
|
+
// Insert new permission with generated UUID
|
|
97
|
+
const perm_id = randomUUID();
|
|
98
|
+
await permissions_service.insert({
|
|
99
|
+
id: perm_id,
|
|
100
|
+
permission_name: trimmed_name,
|
|
101
|
+
description: `Permission for ${trimmed_name}`,
|
|
102
|
+
created_at: now,
|
|
103
|
+
changed_at: now,
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
summary.inserted.push(trimmed_name);
|
|
107
|
+
console.log(`✓ Inserted permission: ${trimmed_name} (ID: ${perm_id})`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
console.log();
|
|
112
|
+
|
|
113
|
+
// Print summary
|
|
114
|
+
print_summary(summary);
|
|
115
|
+
|
|
116
|
+
logger.info("init_permissions_completed", {
|
|
117
|
+
filename: "init_permissions.ts",
|
|
118
|
+
line_number: 0,
|
|
119
|
+
summary,
|
|
120
|
+
});
|
|
121
|
+
} catch (error) {
|
|
122
|
+
const error_message = error instanceof Error ? error.message : "Unknown error";
|
|
123
|
+
const error_stack = error instanceof Error ? error.stack : undefined;
|
|
124
|
+
|
|
125
|
+
console.error("\n✗ Error initializing permissions:");
|
|
126
|
+
console.error(` ${error_message}`);
|
|
127
|
+
if (error_stack) {
|
|
128
|
+
console.error("\nStack trace:");
|
|
129
|
+
console.error(error_stack);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
logger.error("init_permissions_failed", {
|
|
133
|
+
filename: "init_permissions.ts",
|
|
134
|
+
line_number: 0,
|
|
135
|
+
error_message,
|
|
136
|
+
error_stack,
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
process.exit(1);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// section: help
|
|
144
|
+
/**
|
|
145
|
+
* Shows help for the init-permissions command
|
|
146
|
+
*/
|
|
147
|
+
export function show_init_permissions_help(): void {
|
|
148
|
+
console.log(`
|
|
149
|
+
hazo_auth init-permissions
|
|
150
|
+
|
|
151
|
+
Create default permissions from configuration.
|
|
152
|
+
|
|
153
|
+
This command reads permissions from hazo_auth_config.ini and inserts them
|
|
154
|
+
into the hazo_permissions table. Does not require any users to exist.
|
|
155
|
+
|
|
156
|
+
Configuration required in hazo_auth_config.ini:
|
|
157
|
+
|
|
158
|
+
[hazo_auth__user_management]
|
|
159
|
+
application_permission_list_defaults = admin_user_management,admin_role_management,...
|
|
160
|
+
|
|
161
|
+
Usage:
|
|
162
|
+
npx hazo_auth init-permissions
|
|
163
|
+
`);
|
|
164
|
+
}
|
|
@@ -5,6 +5,7 @@ import { createCrudService } from "hazo_connect/server";
|
|
|
5
5
|
import { get_user_management_config } from "../lib/user_management_config.server.js";
|
|
6
6
|
import { get_config_value } from "../lib/config/config_loader.server.js";
|
|
7
7
|
import { create_app_logger } from "../lib/app_logger.js";
|
|
8
|
+
import { SUPER_ADMIN_SCOPE_ID } from "../lib/services/scope_service.js";
|
|
8
9
|
|
|
9
10
|
// section: types
|
|
10
11
|
type InitSummary = {
|
|
@@ -25,6 +26,14 @@ type InitSummary = {
|
|
|
25
26
|
inserted: boolean;
|
|
26
27
|
existing: boolean;
|
|
27
28
|
};
|
|
29
|
+
super_admin_scope: {
|
|
30
|
+
inserted: boolean;
|
|
31
|
+
existing: boolean;
|
|
32
|
+
};
|
|
33
|
+
user_scope: {
|
|
34
|
+
inserted: boolean;
|
|
35
|
+
existing: boolean;
|
|
36
|
+
};
|
|
28
37
|
};
|
|
29
38
|
|
|
30
39
|
// section: helpers
|
|
@@ -79,6 +88,26 @@ function print_summary(summary: InitSummary): void {
|
|
|
79
88
|
}
|
|
80
89
|
console.log();
|
|
81
90
|
|
|
91
|
+
// Super admin scope summary
|
|
92
|
+
console.log("Super Admin Scope:");
|
|
93
|
+
if (summary.super_admin_scope.inserted) {
|
|
94
|
+
console.log(` ✓ Inserted: Super Admin scope (ID: ${SUPER_ADMIN_SCOPE_ID})`);
|
|
95
|
+
}
|
|
96
|
+
if (summary.super_admin_scope.existing) {
|
|
97
|
+
console.log(` ⊙ Already existed: Super Admin scope (ID: ${SUPER_ADMIN_SCOPE_ID})`);
|
|
98
|
+
}
|
|
99
|
+
console.log();
|
|
100
|
+
|
|
101
|
+
// User scope summary
|
|
102
|
+
console.log("User-Scope Assignment:");
|
|
103
|
+
if (summary.user_scope.inserted) {
|
|
104
|
+
console.log(` ✓ Inserted: User assigned to Super Admin scope`);
|
|
105
|
+
}
|
|
106
|
+
if (summary.user_scope.existing) {
|
|
107
|
+
console.log(` ⊙ Already existed: User already in Super Admin scope`);
|
|
108
|
+
}
|
|
109
|
+
console.log();
|
|
110
|
+
|
|
82
111
|
console.log("=".repeat(60));
|
|
83
112
|
}
|
|
84
113
|
|
|
@@ -116,6 +145,14 @@ export async function handle_init_users(options: InitUsersOptions = {}): Promise
|
|
|
116
145
|
inserted: false,
|
|
117
146
|
existing: false,
|
|
118
147
|
},
|
|
148
|
+
super_admin_scope: {
|
|
149
|
+
inserted: false,
|
|
150
|
+
existing: false,
|
|
151
|
+
},
|
|
152
|
+
user_scope: {
|
|
153
|
+
inserted: false,
|
|
154
|
+
existing: false,
|
|
155
|
+
},
|
|
119
156
|
};
|
|
120
157
|
|
|
121
158
|
try {
|
|
@@ -129,6 +166,12 @@ export async function handle_init_users(options: InitUsersOptions = {}): Promise
|
|
|
129
166
|
const role_permissions_service = createCrudService(hazoConnect, "hazo_role_permissions");
|
|
130
167
|
const users_service = createCrudService(hazoConnect, "hazo_users");
|
|
131
168
|
const user_roles_service = createCrudService(hazoConnect, "hazo_user_roles");
|
|
169
|
+
const scopes_service = createCrudService(hazoConnect, "hazo_scopes");
|
|
170
|
+
// hazo_user_scopes uses composite primary key (user_id, scope_id), no 'id' column
|
|
171
|
+
const user_scopes_service = createCrudService(hazoConnect, "hazo_user_scopes", {
|
|
172
|
+
primaryKeys: ["user_id", "scope_id"],
|
|
173
|
+
autoId: false,
|
|
174
|
+
});
|
|
132
175
|
|
|
133
176
|
// 1. Get permissions from config
|
|
134
177
|
const config = get_user_management_config();
|
|
@@ -307,7 +350,52 @@ export async function handle_init_users(options: InitUsersOptions = {}): Promise
|
|
|
307
350
|
|
|
308
351
|
console.log();
|
|
309
352
|
|
|
310
|
-
// 8.
|
|
353
|
+
// 8. Ensure super admin scope exists
|
|
354
|
+
const existing_scopes = await scopes_service.findBy({ id: SUPER_ADMIN_SCOPE_ID });
|
|
355
|
+
|
|
356
|
+
if (Array.isArray(existing_scopes) && existing_scopes.length > 0) {
|
|
357
|
+
summary.super_admin_scope.existing = true;
|
|
358
|
+
console.log(`✓ Super Admin scope already exists (ID: ${SUPER_ADMIN_SCOPE_ID})`);
|
|
359
|
+
} else {
|
|
360
|
+
await scopes_service.insert({
|
|
361
|
+
id: SUPER_ADMIN_SCOPE_ID,
|
|
362
|
+
parent_id: null,
|
|
363
|
+
name: "Super Admin",
|
|
364
|
+
level: "system",
|
|
365
|
+
created_at: now,
|
|
366
|
+
changed_at: now,
|
|
367
|
+
});
|
|
368
|
+
summary.super_admin_scope.inserted = true;
|
|
369
|
+
console.log(`✓ Created Super Admin scope (ID: ${SUPER_ADMIN_SCOPE_ID})`);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
console.log();
|
|
373
|
+
|
|
374
|
+
// 9. Assign user to super admin scope
|
|
375
|
+
const existing_user_scopes = await user_scopes_service.findBy({
|
|
376
|
+
user_id,
|
|
377
|
+
scope_id: SUPER_ADMIN_SCOPE_ID,
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
if (Array.isArray(existing_user_scopes) && existing_user_scopes.length > 0) {
|
|
381
|
+
summary.user_scope.existing = true;
|
|
382
|
+
console.log(`✓ User already assigned to Super Admin scope`);
|
|
383
|
+
} else {
|
|
384
|
+
await user_scopes_service.insert({
|
|
385
|
+
user_id,
|
|
386
|
+
scope_id: SUPER_ADMIN_SCOPE_ID,
|
|
387
|
+
root_scope_id: SUPER_ADMIN_SCOPE_ID,
|
|
388
|
+
role_id,
|
|
389
|
+
created_at: now,
|
|
390
|
+
changed_at: now,
|
|
391
|
+
});
|
|
392
|
+
summary.user_scope.inserted = true;
|
|
393
|
+
console.log(`✓ Assigned user to Super Admin scope`);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
console.log();
|
|
397
|
+
|
|
398
|
+
// 10. Print summary
|
|
311
399
|
print_summary(summary);
|
|
312
400
|
|
|
313
401
|
logger.info("init_users_completed", {
|
|
@@ -345,7 +433,7 @@ export function show_init_users_help(): void {
|
|
|
345
433
|
console.log(`
|
|
346
434
|
hazo_auth init-users
|
|
347
435
|
|
|
348
|
-
Initialize users, roles, and
|
|
436
|
+
Initialize users, roles, permissions, and super admin scope from configuration.
|
|
349
437
|
|
|
350
438
|
This command reads from hazo_auth_config.ini and:
|
|
351
439
|
1. Creates permissions from [hazo_auth__user_management] application_permission_list_defaults
|
|
@@ -353,6 +441,8 @@ This command reads from hazo_auth_config.ini and:
|
|
|
353
441
|
3. Assigns all permissions to the super user role
|
|
354
442
|
4. Finds user by email (from --email parameter or config)
|
|
355
443
|
5. Assigns the super user role to that user
|
|
444
|
+
6. Creates the Super Admin scope (${SUPER_ADMIN_SCOPE_ID})
|
|
445
|
+
7. Assigns the user to the Super Admin scope
|
|
356
446
|
|
|
357
447
|
Options:
|
|
358
448
|
--email=<email> Email address of the user to assign super user role
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// file_description: server-only helper to read app permissions configuration from hazo_auth_config.ini
|
|
2
|
+
// This allows consuming apps to declare their required permissions with descriptions for debugging
|
|
3
|
+
// section: imports
|
|
4
|
+
import { read_config_section } from "./config/config_loader.server.js";
|
|
5
|
+
|
|
6
|
+
// section: types
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A single app permission declaration
|
|
10
|
+
*/
|
|
11
|
+
export type AppPermission = {
|
|
12
|
+
permission_name: string;
|
|
13
|
+
description: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* App permissions configuration
|
|
18
|
+
*/
|
|
19
|
+
export type AppPermissionsConfig = {
|
|
20
|
+
permissions: AppPermission[];
|
|
21
|
+
permissions_map: Map<string, string>; // permission_name -> description
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// section: helpers
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Reads app permissions configuration from hazo_auth_config.ini file
|
|
28
|
+
* Format in INI file:
|
|
29
|
+
* [hazo_auth__app_permissions]
|
|
30
|
+
* app_permission_1 = permission_name:Description for debugging
|
|
31
|
+
* app_permission_2 = another_perm:Another description
|
|
32
|
+
*
|
|
33
|
+
* @returns App permissions configuration with list and map of permissions
|
|
34
|
+
*/
|
|
35
|
+
export function get_app_permissions_config(): AppPermissionsConfig {
|
|
36
|
+
const section = read_config_section("hazo_auth__app_permissions");
|
|
37
|
+
const permissions: AppPermission[] = [];
|
|
38
|
+
const permissions_map = new Map<string, string>();
|
|
39
|
+
|
|
40
|
+
if (section) {
|
|
41
|
+
// Iterate through all keys in section that start with "app_permission_"
|
|
42
|
+
for (const [key, value] of Object.entries(section)) {
|
|
43
|
+
if (key.startsWith("app_permission_") && typeof value === "string") {
|
|
44
|
+
const colonIndex = value.indexOf(":");
|
|
45
|
+
if (colonIndex > 0) {
|
|
46
|
+
const permission_name = value.substring(0, colonIndex).trim();
|
|
47
|
+
const description = value.substring(colonIndex + 1).trim();
|
|
48
|
+
if (permission_name && description) {
|
|
49
|
+
permissions.push({ permission_name, description });
|
|
50
|
+
permissions_map.set(permission_name, description);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
permissions,
|
|
59
|
+
permissions_map,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Gets the description for a specific permission
|
|
65
|
+
* @param permission_name - The permission name to look up
|
|
66
|
+
* @returns Description or undefined if not found in app permissions config
|
|
67
|
+
*/
|
|
68
|
+
export function get_app_permission_description(
|
|
69
|
+
permission_name: string,
|
|
70
|
+
): string | undefined {
|
|
71
|
+
const config = get_app_permissions_config();
|
|
72
|
+
return config.permissions_map.get(permission_name);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Gets descriptions for multiple permissions
|
|
77
|
+
* @param permission_names - Array of permission names to look up
|
|
78
|
+
* @returns Map of permission names to descriptions (only includes found permissions)
|
|
79
|
+
*/
|
|
80
|
+
export function get_app_permission_descriptions(
|
|
81
|
+
permission_names: string[],
|
|
82
|
+
): Map<string, string> {
|
|
83
|
+
const config = get_app_permissions_config();
|
|
84
|
+
const result = new Map<string, string>();
|
|
85
|
+
|
|
86
|
+
for (const name of permission_names) {
|
|
87
|
+
const description = config.permissions_map.get(name);
|
|
88
|
+
if (description) {
|
|
89
|
+
result.set(name, description);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return result;
|
|
94
|
+
}
|