hazo_auth 4.2.0 → 4.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/bin/hazo_auth.mjs +35 -0
- package/cli-src/assets/images/forgot_password_default.jpg +0 -0
- package/cli-src/assets/images/login_default.jpg +0 -0
- package/cli-src/assets/images/register_default.jpg +0 -0
- package/cli-src/assets/images/reset_password_default.jpg +0 -0
- package/cli-src/assets/images/verify_email_default.jpg +0 -0
- package/cli-src/cli/generate.ts +276 -0
- package/cli-src/cli/index.ts +207 -0
- package/cli-src/cli/init.ts +254 -0
- package/cli-src/cli/init_users.ts +376 -0
- package/cli-src/cli/validate.ts +581 -0
- package/cli-src/lib/already_logged_in_config.server.ts +46 -0
- package/cli-src/lib/app_logger.ts +24 -0
- package/cli-src/lib/auth/auth_cache.ts +220 -0
- package/cli-src/lib/auth/auth_rate_limiter.ts +121 -0
- package/cli-src/lib/auth/auth_types.ts +117 -0
- package/cli-src/lib/auth/auth_utils.server.ts +196 -0
- package/cli-src/lib/auth/dev_lock_validator.edge.ts +171 -0
- package/cli-src/lib/auth/hazo_get_auth.server.ts +583 -0
- package/cli-src/lib/auth/index.ts +23 -0
- package/cli-src/lib/auth/nextauth_config.ts +227 -0
- package/cli-src/lib/auth/org_cache.ts +148 -0
- package/cli-src/lib/auth/scope_cache.ts +233 -0
- package/cli-src/lib/auth/server_auth.ts +88 -0
- package/cli-src/lib/auth/session_token_validator.edge.ts +92 -0
- package/cli-src/lib/auth_utility_config.server.ts +136 -0
- package/cli-src/lib/config/config_loader.server.ts +164 -0
- package/cli-src/lib/config/default_config.ts +243 -0
- package/cli-src/lib/dev_lock_config.server.ts +148 -0
- package/cli-src/lib/email_verification_config.server.ts +63 -0
- package/cli-src/lib/file_types_config.server.ts +25 -0
- package/cli-src/lib/forgot_password_config.server.ts +63 -0
- package/cli-src/lib/hazo_connect_instance.server.ts +101 -0
- package/cli-src/lib/hazo_connect_setup.server.ts +194 -0
- package/cli-src/lib/hazo_connect_setup.ts +54 -0
- package/cli-src/lib/index.ts +46 -0
- package/cli-src/lib/login_config.server.ts +106 -0
- package/cli-src/lib/messages_config.server.ts +45 -0
- package/cli-src/lib/migrations/apply_migration.ts +105 -0
- package/cli-src/lib/multi_tenancy_config.server.ts +94 -0
- package/cli-src/lib/my_settings_config.server.ts +135 -0
- package/cli-src/lib/oauth_config.server.ts +87 -0
- package/cli-src/lib/password_requirements_config.server.ts +40 -0
- package/cli-src/lib/profile_pic_menu_config.server.ts +138 -0
- package/cli-src/lib/profile_picture_config.server.ts +56 -0
- package/cli-src/lib/register_config.server.ts +101 -0
- package/cli-src/lib/reset_password_config.server.ts +103 -0
- package/cli-src/lib/scope_hierarchy_config.server.ts +151 -0
- package/cli-src/lib/services/email_service.ts +587 -0
- package/cli-src/lib/services/email_verification_service.ts +270 -0
- package/cli-src/lib/services/index.ts +16 -0
- package/cli-src/lib/services/login_service.ts +150 -0
- package/cli-src/lib/services/oauth_service.ts +494 -0
- package/cli-src/lib/services/org_service.ts +965 -0
- package/cli-src/lib/services/password_change_service.ts +154 -0
- package/cli-src/lib/services/password_reset_service.ts +418 -0
- package/cli-src/lib/services/profile_picture_remove_service.ts +120 -0
- package/cli-src/lib/services/profile_picture_service.ts +451 -0
- package/cli-src/lib/services/profile_picture_source_mapper.ts +62 -0
- package/cli-src/lib/services/registration_service.ts +185 -0
- package/cli-src/lib/services/scope_labels_service.ts +348 -0
- package/cli-src/lib/services/scope_service.ts +778 -0
- package/cli-src/lib/services/session_token_service.ts +178 -0
- package/cli-src/lib/services/token_service.ts +240 -0
- package/cli-src/lib/services/user_profiles_cache.ts +189 -0
- package/cli-src/lib/services/user_profiles_service.ts +264 -0
- package/cli-src/lib/services/user_scope_service.ts +554 -0
- package/cli-src/lib/services/user_update_service.ts +141 -0
- package/cli-src/lib/ui_shell_config.server.ts +73 -0
- package/cli-src/lib/ui_sizes_config.server.ts +37 -0
- package/cli-src/lib/user_fields_config.server.ts +31 -0
- package/cli-src/lib/user_management_config.server.ts +39 -0
- package/cli-src/lib/user_profiles_config.server.ts +55 -0
- package/cli-src/lib/utils/api_route_helpers.ts +60 -0
- package/cli-src/lib/utils/error_sanitizer.ts +75 -0
- package/cli-src/lib/utils/password_validator.ts +65 -0
- package/cli-src/lib/utils.ts +11 -0
- package/cli-src/server/logging/logger_service.ts +56 -0
- package/cli-src/server/types/app_types.ts +74 -0
- package/cli-src/server/types/express.d.ts +16 -0
- package/dist/cli/index.js +18 -0
- package/dist/cli/init_users.d.ts +17 -0
- package/dist/cli/init_users.d.ts.map +1 -0
- package/dist/cli/init_users.js +307 -0
- package/dist/components/layouts/dev_lock/index.d.ts +29 -0
- package/dist/components/layouts/dev_lock/index.d.ts.map +1 -0
- package/dist/components/layouts/dev_lock/index.js +60 -0
- package/dist/components/layouts/index.d.ts +2 -0
- package/dist/components/layouts/index.d.ts.map +1 -1
- package/dist/components/layouts/index.js +1 -0
- package/dist/components/layouts/org_management/index.d.ts +26 -0
- package/dist/components/layouts/org_management/index.d.ts.map +1 -0
- package/dist/components/layouts/org_management/index.js +75 -0
- package/dist/components/layouts/shared/config/layout_customization.d.ts +2 -7
- package/dist/components/layouts/shared/config/layout_customization.d.ts.map +1 -1
- package/dist/components/layouts/user_management/components/org_hierarchy_tab.d.ts +13 -0
- package/dist/components/layouts/user_management/components/org_hierarchy_tab.d.ts.map +1 -0
- package/dist/components/layouts/user_management/components/org_hierarchy_tab.js +276 -0
- package/dist/components/layouts/user_management/index.d.ts +3 -1
- package/dist/components/layouts/user_management/index.d.ts.map +1 -1
- package/dist/components/layouts/user_management/index.js +10 -4
- package/dist/lib/auth/auth_types.d.ts +6 -0
- package/dist/lib/auth/auth_types.d.ts.map +1 -1
- package/dist/lib/auth/dev_lock_validator.edge.d.ts +38 -0
- package/dist/lib/auth/dev_lock_validator.edge.d.ts.map +1 -0
- package/dist/lib/auth/dev_lock_validator.edge.js +122 -0
- package/dist/lib/auth/hazo_get_auth.server.d.ts.map +1 -1
- package/dist/lib/auth/hazo_get_auth.server.js +61 -1
- package/dist/lib/auth/org_cache.d.ts +65 -0
- package/dist/lib/auth/org_cache.d.ts.map +1 -0
- package/dist/lib/auth/org_cache.js +103 -0
- package/dist/lib/config/default_config.d.ts +76 -0
- package/dist/lib/config/default_config.d.ts.map +1 -1
- package/dist/lib/config/default_config.js +42 -0
- package/dist/lib/dev_lock_config.server.d.ts +41 -0
- package/dist/lib/dev_lock_config.server.d.ts.map +1 -0
- package/dist/lib/dev_lock_config.server.js +50 -0
- package/dist/lib/multi_tenancy_config.server.d.ts +30 -0
- package/dist/lib/multi_tenancy_config.server.d.ts.map +1 -0
- package/dist/lib/multi_tenancy_config.server.js +41 -0
- package/dist/lib/services/org_service.d.ts +191 -0
- package/dist/lib/services/org_service.d.ts.map +1 -0
- package/dist/lib/services/org_service.js +746 -0
- package/dist/lib/utils/password_validator.d.ts +7 -1
- package/dist/lib/utils/password_validator.d.ts.map +1 -1
- package/dist/page_components/dev_lock.d.ts +11 -0
- package/dist/page_components/dev_lock.d.ts.map +1 -0
- package/dist/page_components/dev_lock.js +17 -0
- package/dist/page_components/index.d.ts +1 -0
- package/dist/page_components/index.d.ts.map +1 -1
- package/dist/page_components/index.js +1 -0
- package/dist/page_components/org_management.d.ts +27 -0
- package/dist/page_components/org_management.d.ts.map +1 -0
- package/dist/page_components/org_management.js +18 -0
- package/hazo_auth_config.example.ini +30 -0
- package/package.json +27 -3
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
// file_description: CLI command to initialize users, roles, and permissions from configuration
|
|
2
|
+
// section: imports
|
|
3
|
+
import { get_hazo_connect_instance } from "../lib/hazo_connect_instance.server.js";
|
|
4
|
+
import { createCrudService } from "hazo_connect/server";
|
|
5
|
+
import { get_user_management_config } from "../lib/user_management_config.server.js";
|
|
6
|
+
import { get_config_value } from "../lib/config/config_loader.server.js";
|
|
7
|
+
import { create_app_logger } from "../lib/app_logger.js";
|
|
8
|
+
// section: helpers
|
|
9
|
+
/**
|
|
10
|
+
* Prints a summary of what was inserted vs what already existed
|
|
11
|
+
*/
|
|
12
|
+
function print_summary(summary) {
|
|
13
|
+
console.log("=".repeat(60));
|
|
14
|
+
console.log("INITIALIZATION SUMMARY");
|
|
15
|
+
console.log("=".repeat(60));
|
|
16
|
+
console.log();
|
|
17
|
+
// Permissions summary
|
|
18
|
+
console.log("Permissions:");
|
|
19
|
+
if (summary.permissions.inserted.length > 0) {
|
|
20
|
+
console.log(` ✓ Inserted (${summary.permissions.inserted.length}):`);
|
|
21
|
+
summary.permissions.inserted.forEach((name) => console.log(` - ${name}`));
|
|
22
|
+
}
|
|
23
|
+
if (summary.permissions.existing.length > 0) {
|
|
24
|
+
console.log(` ⊙ Already existed (${summary.permissions.existing.length}):`);
|
|
25
|
+
summary.permissions.existing.forEach((name) => console.log(` - ${name}`));
|
|
26
|
+
}
|
|
27
|
+
console.log();
|
|
28
|
+
// Role summary
|
|
29
|
+
console.log("Role:");
|
|
30
|
+
if (summary.role.inserted) {
|
|
31
|
+
console.log(` ✓ Inserted: default_super_user_role (ID: ${summary.role.role_id})`);
|
|
32
|
+
}
|
|
33
|
+
if (summary.role.existing) {
|
|
34
|
+
console.log(` ⊙ Already existed: default_super_user_role (ID: ${summary.role.role_id})`);
|
|
35
|
+
}
|
|
36
|
+
console.log();
|
|
37
|
+
// Role permissions summary
|
|
38
|
+
console.log("Role-Permission Assignments:");
|
|
39
|
+
if (summary.role_permissions.inserted > 0) {
|
|
40
|
+
console.log(` ✓ Inserted: ${summary.role_permissions.inserted} assignment(s)`);
|
|
41
|
+
}
|
|
42
|
+
if (summary.role_permissions.existing > 0) {
|
|
43
|
+
console.log(` ⊙ Already existed: ${summary.role_permissions.existing} assignment(s)`);
|
|
44
|
+
}
|
|
45
|
+
console.log();
|
|
46
|
+
// User role summary
|
|
47
|
+
console.log("User-Role Assignment:");
|
|
48
|
+
if (summary.user_role.inserted) {
|
|
49
|
+
console.log(` ✓ Inserted: Super user role assigned to user`);
|
|
50
|
+
}
|
|
51
|
+
if (summary.user_role.existing) {
|
|
52
|
+
console.log(` ⊙ Already existed: User already has super user role`);
|
|
53
|
+
}
|
|
54
|
+
console.log();
|
|
55
|
+
console.log("=".repeat(60));
|
|
56
|
+
}
|
|
57
|
+
// section: main_function
|
|
58
|
+
/**
|
|
59
|
+
* Initializes users, roles, and permissions from configuration
|
|
60
|
+
* This function reads from hazo_auth_config.ini and sets up:
|
|
61
|
+
* 1. Permissions from [hazo_auth__user_management] application_permission_list_defaults
|
|
62
|
+
* 2. A default_super_user_role with all permissions
|
|
63
|
+
* 3. Assigns the role to user from --email parameter or [hazo_auth__initial_setup] default_super_user_email
|
|
64
|
+
*/
|
|
65
|
+
export async function handle_init_users(options = {}) {
|
|
66
|
+
var _a;
|
|
67
|
+
const logger = create_app_logger();
|
|
68
|
+
const summary = {
|
|
69
|
+
permissions: {
|
|
70
|
+
inserted: [],
|
|
71
|
+
existing: [],
|
|
72
|
+
},
|
|
73
|
+
role: {
|
|
74
|
+
inserted: false,
|
|
75
|
+
existing: false,
|
|
76
|
+
role_id: null,
|
|
77
|
+
},
|
|
78
|
+
role_permissions: {
|
|
79
|
+
inserted: 0,
|
|
80
|
+
existing: 0,
|
|
81
|
+
},
|
|
82
|
+
user_role: {
|
|
83
|
+
inserted: false,
|
|
84
|
+
existing: false,
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
try {
|
|
88
|
+
console.log("\n🐸 hazo_auth init-users\n");
|
|
89
|
+
console.log("Initializing users, roles, and permissions from configuration...\n");
|
|
90
|
+
// Get hazo_connect instance
|
|
91
|
+
const hazoConnect = get_hazo_connect_instance();
|
|
92
|
+
const permissions_service = createCrudService(hazoConnect, "hazo_permissions");
|
|
93
|
+
const roles_service = createCrudService(hazoConnect, "hazo_roles");
|
|
94
|
+
const role_permissions_service = createCrudService(hazoConnect, "hazo_role_permissions");
|
|
95
|
+
const users_service = createCrudService(hazoConnect, "hazo_users");
|
|
96
|
+
const user_roles_service = createCrudService(hazoConnect, "hazo_user_roles");
|
|
97
|
+
// 1. Get permissions from config
|
|
98
|
+
const config = get_user_management_config();
|
|
99
|
+
const permission_names = config.application_permission_list_defaults || [];
|
|
100
|
+
if (permission_names.length === 0) {
|
|
101
|
+
console.log("⚠ No permissions found in configuration.");
|
|
102
|
+
console.log(" Add permissions to [hazo_auth__user_management] application_permission_list_defaults\n");
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
console.log(`Found ${permission_names.length} permission(s) in configuration:`);
|
|
106
|
+
permission_names.forEach((name) => console.log(` - ${name}`));
|
|
107
|
+
console.log();
|
|
108
|
+
// 2. Add permissions to hazo_permissions table
|
|
109
|
+
const permission_id_map = {};
|
|
110
|
+
const now = new Date().toISOString();
|
|
111
|
+
for (const permission_name of permission_names) {
|
|
112
|
+
const trimmed_name = permission_name.trim();
|
|
113
|
+
if (!trimmed_name)
|
|
114
|
+
continue;
|
|
115
|
+
// Check if permission already exists
|
|
116
|
+
const existing_permissions = await permissions_service.findBy({
|
|
117
|
+
permission_name: trimmed_name,
|
|
118
|
+
});
|
|
119
|
+
if (Array.isArray(existing_permissions) && existing_permissions.length > 0) {
|
|
120
|
+
const existing_permission = existing_permissions[0];
|
|
121
|
+
const perm_id = existing_permission.id;
|
|
122
|
+
permission_id_map[trimmed_name] = perm_id;
|
|
123
|
+
summary.permissions.existing.push(trimmed_name);
|
|
124
|
+
console.log(`✓ Permission already exists: ${trimmed_name} (ID: ${perm_id})`);
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
// Insert new permission
|
|
128
|
+
const new_permission = await permissions_service.insert({
|
|
129
|
+
permission_name: trimmed_name,
|
|
130
|
+
description: `Permission for ${trimmed_name}`,
|
|
131
|
+
created_at: now,
|
|
132
|
+
changed_at: now,
|
|
133
|
+
});
|
|
134
|
+
const perm_id = Array.isArray(new_permission)
|
|
135
|
+
? new_permission[0].id
|
|
136
|
+
: new_permission.id;
|
|
137
|
+
permission_id_map[trimmed_name] = perm_id;
|
|
138
|
+
summary.permissions.inserted.push(trimmed_name);
|
|
139
|
+
console.log(`✓ Inserted permission: ${trimmed_name} (ID: ${perm_id})`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
console.log();
|
|
143
|
+
// 3. Create or get default_super_user_role
|
|
144
|
+
const role_name = "default_super_user_role";
|
|
145
|
+
const existing_roles = await roles_service.findBy({
|
|
146
|
+
role_name,
|
|
147
|
+
});
|
|
148
|
+
let role_id;
|
|
149
|
+
if (Array.isArray(existing_roles) && existing_roles.length > 0) {
|
|
150
|
+
role_id = existing_roles[0].id;
|
|
151
|
+
summary.role.existing = true;
|
|
152
|
+
summary.role.role_id = role_id;
|
|
153
|
+
console.log(`✓ Role already exists: ${role_name} (ID: ${role_id})`);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
const new_role = await roles_service.insert({
|
|
157
|
+
role_name,
|
|
158
|
+
created_at: now,
|
|
159
|
+
changed_at: now,
|
|
160
|
+
});
|
|
161
|
+
role_id = Array.isArray(new_role)
|
|
162
|
+
? new_role[0].id
|
|
163
|
+
: new_role.id;
|
|
164
|
+
summary.role.inserted = true;
|
|
165
|
+
summary.role.role_id = role_id;
|
|
166
|
+
console.log(`✓ Created role: ${role_name} (ID: ${role_id})`);
|
|
167
|
+
}
|
|
168
|
+
console.log();
|
|
169
|
+
// 4. Assign all permissions to the role
|
|
170
|
+
const permission_ids = Object.values(permission_id_map);
|
|
171
|
+
for (const permission_id of permission_ids) {
|
|
172
|
+
// Check if role-permission assignment already exists
|
|
173
|
+
const existing_assignments = await role_permissions_service.findBy({
|
|
174
|
+
role_id,
|
|
175
|
+
permission_id,
|
|
176
|
+
});
|
|
177
|
+
if (Array.isArray(existing_assignments) && existing_assignments.length > 0) {
|
|
178
|
+
summary.role_permissions.existing++;
|
|
179
|
+
const perm_name = Object.keys(permission_id_map).find((key) => permission_id_map[key] === permission_id);
|
|
180
|
+
console.log(`✓ Role-permission already exists: ${role_name} -> ${perm_name}`);
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
await role_permissions_service.insert({
|
|
184
|
+
role_id,
|
|
185
|
+
permission_id,
|
|
186
|
+
created_at: now,
|
|
187
|
+
changed_at: now,
|
|
188
|
+
});
|
|
189
|
+
summary.role_permissions.inserted++;
|
|
190
|
+
const perm_name = Object.keys(permission_id_map).find((key) => permission_id_map[key] === permission_id);
|
|
191
|
+
console.log(`✓ Assigned permission to role: ${role_name} -> ${perm_name}`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
console.log();
|
|
195
|
+
// 5. Get super user email from options or config
|
|
196
|
+
const super_user_email = ((_a = options.email) === null || _a === void 0 ? void 0 : _a.trim()) || get_config_value("hazo_auth__initial_setup", "default_super_user_email", "").trim();
|
|
197
|
+
if (!super_user_email) {
|
|
198
|
+
console.log("⚠ No super user email provided.");
|
|
199
|
+
console.log(" Either use --email=user@example.com parameter");
|
|
200
|
+
console.log(" Or add [hazo_auth__initial_setup] default_super_user_email to config\n");
|
|
201
|
+
print_summary(summary);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
if (options.email) {
|
|
205
|
+
console.log(`Using email from --email parameter: ${super_user_email}`);
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
console.log(`Using email from config: ${super_user_email}`);
|
|
209
|
+
}
|
|
210
|
+
console.log(`Looking up user with email: ${super_user_email}`);
|
|
211
|
+
// 6. Find user by email
|
|
212
|
+
const users = await users_service.findBy({
|
|
213
|
+
email_address: super_user_email,
|
|
214
|
+
});
|
|
215
|
+
if (!Array.isArray(users) || users.length === 0) {
|
|
216
|
+
console.log(`✗ User not found with email: ${super_user_email}`);
|
|
217
|
+
console.log(" Please ensure the user exists in the database before running this script.\n");
|
|
218
|
+
print_summary(summary);
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
const user = users[0];
|
|
222
|
+
const user_id = user.id;
|
|
223
|
+
console.log(`✓ Found user: ${super_user_email} (ID: ${user_id})`);
|
|
224
|
+
console.log();
|
|
225
|
+
// 7. Assign role to user
|
|
226
|
+
const existing_user_roles = await user_roles_service.findBy({
|
|
227
|
+
user_id,
|
|
228
|
+
role_id,
|
|
229
|
+
});
|
|
230
|
+
if (Array.isArray(existing_user_roles) && existing_user_roles.length > 0) {
|
|
231
|
+
summary.user_role.existing = true;
|
|
232
|
+
console.log(`✓ User already has role assigned: ${user_id} -> ${role_name}`);
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
await user_roles_service.insert({
|
|
236
|
+
user_id,
|
|
237
|
+
role_id,
|
|
238
|
+
created_at: now,
|
|
239
|
+
changed_at: now,
|
|
240
|
+
});
|
|
241
|
+
summary.user_role.inserted = true;
|
|
242
|
+
console.log(`✓ Assigned role to user: ${user_id} -> ${role_name}`);
|
|
243
|
+
}
|
|
244
|
+
console.log();
|
|
245
|
+
// 8. Print summary
|
|
246
|
+
print_summary(summary);
|
|
247
|
+
logger.info("init_users_completed", {
|
|
248
|
+
filename: "init_users.ts",
|
|
249
|
+
line_number: 0,
|
|
250
|
+
summary,
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
const error_message = error instanceof Error ? error.message : "Unknown error";
|
|
255
|
+
const error_stack = error instanceof Error ? error.stack : undefined;
|
|
256
|
+
console.error("\n✗ Error initializing users:");
|
|
257
|
+
console.error(` ${error_message}`);
|
|
258
|
+
if (error_stack) {
|
|
259
|
+
console.error("\nStack trace:");
|
|
260
|
+
console.error(error_stack);
|
|
261
|
+
}
|
|
262
|
+
logger.error("init_users_failed", {
|
|
263
|
+
filename: "init_users.ts",
|
|
264
|
+
line_number: 0,
|
|
265
|
+
error_message,
|
|
266
|
+
error_stack,
|
|
267
|
+
});
|
|
268
|
+
process.exit(1);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
// section: help
|
|
272
|
+
/**
|
|
273
|
+
* Shows help for the init-users command
|
|
274
|
+
*/
|
|
275
|
+
export function show_init_users_help() {
|
|
276
|
+
console.log(`
|
|
277
|
+
hazo_auth init-users
|
|
278
|
+
|
|
279
|
+
Initialize users, roles, and permissions from configuration.
|
|
280
|
+
|
|
281
|
+
This command reads from hazo_auth_config.ini and:
|
|
282
|
+
1. Creates permissions from [hazo_auth__user_management] application_permission_list_defaults
|
|
283
|
+
2. Creates a 'default_super_user_role' role
|
|
284
|
+
3. Assigns all permissions to the super user role
|
|
285
|
+
4. Finds user by email (from --email parameter or config)
|
|
286
|
+
5. Assigns the super user role to that user
|
|
287
|
+
|
|
288
|
+
Options:
|
|
289
|
+
--email=<email> Email address of the user to assign super user role
|
|
290
|
+
(overrides [hazo_auth__initial_setup] default_super_user_email)
|
|
291
|
+
--help, -h Show this help message
|
|
292
|
+
|
|
293
|
+
Configuration required in hazo_auth_config.ini:
|
|
294
|
+
|
|
295
|
+
[hazo_auth__user_management]
|
|
296
|
+
application_permission_list_defaults = admin_user_management,admin_role_management,admin_permission_management
|
|
297
|
+
|
|
298
|
+
[hazo_auth__initial_setup]
|
|
299
|
+
default_super_user_email = admin@example.com (optional if using --email)
|
|
300
|
+
|
|
301
|
+
Note: The user must already exist in the database (registered) before running this command.
|
|
302
|
+
|
|
303
|
+
Usage:
|
|
304
|
+
npx hazo_auth init-users
|
|
305
|
+
npx hazo_auth init-users --email=admin@example.com
|
|
306
|
+
`);
|
|
307
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export type DevLockLayoutProps = {
|
|
2
|
+
/** Background color (default: #000000 - black) */
|
|
3
|
+
background_color?: string;
|
|
4
|
+
/** Logo image path (default: /logo.png) */
|
|
5
|
+
logo_path?: string;
|
|
6
|
+
/** Logo width in pixels (default: 120) */
|
|
7
|
+
logo_width?: number;
|
|
8
|
+
/** Logo height in pixels (default: 120) */
|
|
9
|
+
logo_height?: number;
|
|
10
|
+
/** Application name displayed below logo */
|
|
11
|
+
application_name?: string;
|
|
12
|
+
/** Limited access text displayed with lock icon (default: "Limited Access") */
|
|
13
|
+
limited_access_text?: string;
|
|
14
|
+
/** Password input placeholder (default: "Enter access password") */
|
|
15
|
+
password_placeholder?: string;
|
|
16
|
+
/** Submit button text (default: "Unlock") */
|
|
17
|
+
submit_button_text?: string;
|
|
18
|
+
/** Error message for incorrect password (default: "Incorrect password") */
|
|
19
|
+
error_message?: string;
|
|
20
|
+
/** Text color for labels (default: #ffffff - white) */
|
|
21
|
+
text_color?: string;
|
|
22
|
+
/** Accent color for button (default: #3b82f6 - blue) */
|
|
23
|
+
accent_color?: string;
|
|
24
|
+
/** Callback when unlock is successful */
|
|
25
|
+
onUnlock?: () => void;
|
|
26
|
+
};
|
|
27
|
+
export default function DevLockLayout({ background_color, logo_path, logo_width, logo_height, application_name, limited_access_text, password_placeholder, submit_button_text, error_message, text_color, accent_color, onUnlock, }: DevLockLayoutProps): import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
export { DevLockLayout };
|
|
29
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/layouts/dev_lock/index.tsx"],"names":[],"mappings":"AAaA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,kDAAkD;IAClD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,+EAA+E;IAC/E,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oEAAoE;IACpE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,6CAA6C;IAC7C,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,2EAA2E;IAC3E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB,CAAC;AAGF,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EACpC,gBAA4B,EAC5B,SAAuB,EACvB,UAAgB,EAChB,WAAiB,EACjB,gBAAqB,EACrB,mBAAsC,EACtC,oBAA8C,EAC9C,kBAA6B,EAC7B,aAAoC,EACpC,UAAsB,EACtB,YAAwB,EACxB,QAAQ,GACT,EAAE,kBAAkB,2CA4IpB;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// file_description: Development lock screen layout component
|
|
2
|
+
// A simple centered layout for entering the dev lock password
|
|
3
|
+
// section: client_directive
|
|
4
|
+
"use client";
|
|
5
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
6
|
+
// section: imports
|
|
7
|
+
import { useState, useCallback } from "react";
|
|
8
|
+
import Image from "next/image";
|
|
9
|
+
import { Input } from "../../ui/input";
|
|
10
|
+
import { Button } from "../../ui/button";
|
|
11
|
+
import { Lock, AlertCircle, Loader2 } from "lucide-react";
|
|
12
|
+
// section: component
|
|
13
|
+
export default function DevLockLayout({ background_color = "#000000", logo_path = "/logo.png", logo_width = 120, logo_height = 120, application_name = "", limited_access_text = "Limited Access", password_placeholder = "Enter access password", submit_button_text = "Unlock", error_message = "Incorrect password", text_color = "#ffffff", accent_color = "#3b82f6", onUnlock, }) {
|
|
14
|
+
const [password, setPassword] = useState("");
|
|
15
|
+
const [error, setError] = useState(null);
|
|
16
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
17
|
+
const handleSubmit = useCallback(async (e) => {
|
|
18
|
+
e.preventDefault();
|
|
19
|
+
setError(null);
|
|
20
|
+
setIsLoading(true);
|
|
21
|
+
try {
|
|
22
|
+
const response = await fetch("/api/hazo_auth/dev_lock", {
|
|
23
|
+
method: "POST",
|
|
24
|
+
headers: { "Content-Type": "application/json" },
|
|
25
|
+
body: JSON.stringify({ password }),
|
|
26
|
+
});
|
|
27
|
+
if (response.ok) {
|
|
28
|
+
// Success - redirect to home or call onUnlock
|
|
29
|
+
if (onUnlock) {
|
|
30
|
+
onUnlock();
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
window.location.href = "/";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
setError(error_message);
|
|
38
|
+
setPassword("");
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch (_a) {
|
|
42
|
+
setError("An error occurred. Please try again.");
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
setIsLoading(false);
|
|
46
|
+
}
|
|
47
|
+
}, [password, error_message, onUnlock]);
|
|
48
|
+
const handlePasswordChange = useCallback((e) => {
|
|
49
|
+
setPassword(e.target.value);
|
|
50
|
+
// Clear error when user starts typing
|
|
51
|
+
if (error) {
|
|
52
|
+
setError(null);
|
|
53
|
+
}
|
|
54
|
+
}, [error]);
|
|
55
|
+
return (_jsx("div", { className: "cls_dev_lock_layout min-h-screen flex flex-col items-center justify-center p-4", style: { backgroundColor: background_color }, children: _jsxs("div", { className: "cls_dev_lock_container flex flex-col items-center gap-6 max-w-sm w-full", children: [_jsx("div", { className: "cls_dev_lock_logo", children: _jsx(Image, { src: logo_path, alt: "Application logo", width: logo_width, height: logo_height, className: "object-contain", priority: true }) }), application_name && (_jsx("h1", { className: "cls_dev_lock_app_name text-2xl font-bold text-center", style: { color: text_color }, children: application_name })), _jsxs("div", { className: "cls_dev_lock_header flex items-center gap-2", children: [_jsx(Lock, { className: "w-5 h-5", style: { color: text_color } }), _jsx("span", { className: "cls_dev_lock_text text-sm font-medium uppercase tracking-wider", style: { color: text_color, opacity: 0.8 }, children: limited_access_text })] }), _jsxs("form", { onSubmit: handleSubmit, className: "cls_dev_lock_form flex flex-col gap-4 w-full", children: [_jsx("div", { className: "cls_dev_lock_input_wrapper relative", children: _jsx(Input, { type: "password", value: password, onChange: handlePasswordChange, placeholder: password_placeholder, className: "cls_dev_lock_input h-12 bg-white/10 border-white/20 text-white placeholder:text-white/50 focus:border-white/40 focus:ring-white/20", disabled: isLoading, autoFocus: true, autoComplete: "current-password" }) }), error && (_jsxs("div", { className: "cls_dev_lock_error flex items-center gap-2 text-sm", style: { color: "#ef4444" }, children: [_jsx(AlertCircle, { className: "w-4 h-4 flex-shrink-0" }), _jsx("span", { children: error })] })), _jsx(Button, { type: "submit", className: "cls_dev_lock_button h-12 font-medium transition-colors", style: {
|
|
56
|
+
backgroundColor: accent_color,
|
|
57
|
+
color: "#ffffff",
|
|
58
|
+
}, disabled: isLoading || !password, children: isLoading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "w-4 h-4 animate-spin mr-2" }), "Verifying..."] })) : (submit_button_text) })] })] }) }));
|
|
59
|
+
}
|
|
60
|
+
export { DevLockLayout };
|
|
@@ -12,5 +12,7 @@ export { default as MySettingsLayout } from "./my_settings/index";
|
|
|
12
12
|
export type { MySettingsLayoutProps } from "./my_settings/index";
|
|
13
13
|
export { UserManagementLayout } from "./user_management/index";
|
|
14
14
|
export type { UserManagementLayoutProps } from "./user_management/index";
|
|
15
|
+
export { default as DevLockLayout } from "./dev_lock/index";
|
|
16
|
+
export type { DevLockLayoutProps } from "./dev_lock/index";
|
|
15
17
|
export * from "./shared/index";
|
|
16
18
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/layouts/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAC;AACvD,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC7D,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE5D,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC1E,YAAY,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAEzE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AACxE,YAAY,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAEvE,OAAO,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAChF,YAAY,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAE/E,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAClE,YAAY,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAEjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,YAAY,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/layouts/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAC;AACvD,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC7D,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE5D,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC1E,YAAY,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAEzE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AACxE,YAAY,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAEvE,OAAO,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAChF,YAAY,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAE/E,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAClE,YAAY,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAEjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,YAAY,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAEzE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC5D,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAG3D,cAAc,gBAAgB,CAAC"}
|
|
@@ -7,5 +7,6 @@ export { default as ResetPasswordLayout } from "./reset_password/index";
|
|
|
7
7
|
export { default as EmailVerificationLayout } from "./email_verification/index";
|
|
8
8
|
export { default as MySettingsLayout } from "./my_settings/index";
|
|
9
9
|
export { UserManagementLayout } from "./user_management/index";
|
|
10
|
+
export { default as DevLockLayout } from "./dev_lock/index";
|
|
10
11
|
// section: shared_exports
|
|
11
12
|
export * from "./shared/index";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type OrgManagementLayoutProps = {
|
|
2
|
+
className?: string;
|
|
3
|
+
/** Title displayed at the top */
|
|
4
|
+
title?: string;
|
|
5
|
+
/** Description displayed below the title */
|
|
6
|
+
description?: string;
|
|
7
|
+
/** Required permission for org management (default: hazo_perm_org_management) */
|
|
8
|
+
requiredPermission?: string;
|
|
9
|
+
/** Permission for global admin access (default: hazo_org_global_admin) */
|
|
10
|
+
globalAdminPermission?: string;
|
|
11
|
+
/** Message shown when authentication is required */
|
|
12
|
+
authRequiredMessage?: string;
|
|
13
|
+
/** Message shown when permission is denied */
|
|
14
|
+
permissionDeniedMessage?: string;
|
|
15
|
+
/** Message shown when multi-tenancy is disabled */
|
|
16
|
+
multiTenancyDisabledMessage?: string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Standalone Organization Management layout component
|
|
20
|
+
* Provides organization hierarchy management with CRUD operations
|
|
21
|
+
* @param props - Component props
|
|
22
|
+
* @returns Organization Management layout component
|
|
23
|
+
*/
|
|
24
|
+
export declare function OrgManagementLayout({ className, title, description, requiredPermission, globalAdminPermission, authRequiredMessage, permissionDeniedMessage, multiTenancyDisabledMessage, }: OrgManagementLayoutProps): import("react/jsx-runtime").JSX.Element;
|
|
25
|
+
export default OrgManagementLayout;
|
|
26
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/layouts/org_management/index.tsx"],"names":[],"mappings":"AAwBA,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,0EAA0E;IAC1E,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,oDAAoD;IACpD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,8CAA8C;IAC9C,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,mDAAmD;IACnD,2BAA2B,CAAC,EAAE,MAAM,CAAC;CACtC,CAAC;AAGF;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,SAAS,EACT,KAAiC,EACjC,WAAiE,EACjE,kBAA+C,EAC/C,qBAA+C,EAC/C,mBAAwE,EACxE,uBAA4F,EAC5F,2BAAkF,GACnF,EAAE,wBAAwB,2CAuH1B;AAED,eAAe,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// file_description: Standalone Organization Management layout component for managing multi-tenancy organizations
|
|
2
|
+
// section: client_directive
|
|
3
|
+
"use client";
|
|
4
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
5
|
+
// section: imports
|
|
6
|
+
import { useState, useEffect } from "react";
|
|
7
|
+
import { OrgHierarchyTab } from "../user_management/components/org_hierarchy_tab";
|
|
8
|
+
import { useHazoAuthConfig } from "../../../contexts/hazo_auth_provider";
|
|
9
|
+
import { use_hazo_auth } from "../shared/hooks/use_hazo_auth";
|
|
10
|
+
import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "../../ui/card";
|
|
11
|
+
import { Loader2, AlertCircle, Shield, Building2, } from "lucide-react";
|
|
12
|
+
// section: component
|
|
13
|
+
/**
|
|
14
|
+
* Standalone Organization Management layout component
|
|
15
|
+
* Provides organization hierarchy management with CRUD operations
|
|
16
|
+
* @param props - Component props
|
|
17
|
+
* @returns Organization Management layout component
|
|
18
|
+
*/
|
|
19
|
+
export function OrgManagementLayout({ className, title = "Organization Management", description = "Manage your organization hierarchy and structure.", requiredPermission = "hazo_perm_org_management", globalAdminPermission = "hazo_org_global_admin", authRequiredMessage = "Please log in to access organization management.", permissionDeniedMessage = "You need organization management permission to access this page.", multiTenancyDisabledMessage = "Multi-tenancy is not enabled in the configuration.", }) {
|
|
20
|
+
const { apiBasePath } = useHazoAuthConfig();
|
|
21
|
+
const authResult = use_hazo_auth();
|
|
22
|
+
const [multiTenancyEnabled, setMultiTenancyEnabled] = useState(null);
|
|
23
|
+
const [checkingMultiTenancy, setCheckingMultiTenancy] = useState(true);
|
|
24
|
+
// Check if multi-tenancy is enabled
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
const checkMultiTenancy = async () => {
|
|
27
|
+
try {
|
|
28
|
+
const response = await fetch(`${apiBasePath}/org_management/orgs?action=list`);
|
|
29
|
+
const data = await response.json();
|
|
30
|
+
if (data.code === "MULTI_TENANCY_DISABLED") {
|
|
31
|
+
setMultiTenancyEnabled(false);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
setMultiTenancyEnabled(true);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
// If we can't check, assume enabled and let the component handle it
|
|
39
|
+
setMultiTenancyEnabled(true);
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
setCheckingMultiTenancy(false);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
if (authResult.authenticated && authResult.permissions.includes(requiredPermission)) {
|
|
46
|
+
void checkMultiTenancy();
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
setCheckingMultiTenancy(false);
|
|
50
|
+
}
|
|
51
|
+
}, [apiBasePath, authResult.authenticated, authResult.permissions, requiredPermission]);
|
|
52
|
+
// Loading state
|
|
53
|
+
if (authResult.loading || checkingMultiTenancy) {
|
|
54
|
+
return (_jsx("div", { className: `cls_org_management_layout flex items-center justify-center p-8 ${className || ""}`, children: _jsx(Loader2, { className: "h-6 w-6 animate-spin text-slate-400" }) }));
|
|
55
|
+
}
|
|
56
|
+
// Not authenticated
|
|
57
|
+
if (!authResult.authenticated) {
|
|
58
|
+
return (_jsxs("div", { className: `cls_org_management_layout flex flex-col items-center justify-center p-8 gap-4 ${className || ""}`, children: [_jsx(AlertCircle, { className: "h-12 w-12 text-red-500" }), _jsx("h1", { className: "text-xl font-semibold", children: "Authentication Required" }), _jsx("p", { className: "text-muted-foreground text-center", children: authRequiredMessage })] }));
|
|
59
|
+
}
|
|
60
|
+
// Check required permission
|
|
61
|
+
const hasOrgManagementPermission = authResult.permissions.includes(requiredPermission);
|
|
62
|
+
if (!hasOrgManagementPermission) {
|
|
63
|
+
return (_jsxs("div", { className: `cls_org_management_layout flex flex-col items-center justify-center p-8 gap-4 ${className || ""}`, children: [_jsx(Shield, { className: "h-12 w-12 text-amber-500" }), _jsx("h1", { className: "text-xl font-semibold", children: "Access Denied" }), _jsx("p", { className: "text-muted-foreground text-center", children: permissionDeniedMessage }), _jsxs("p", { className: "text-xs text-muted-foreground", children: ["Required permission: ", _jsx("code", { className: "bg-muted px-1 py-0.5 rounded", children: requiredPermission })] })] }));
|
|
64
|
+
}
|
|
65
|
+
// Multi-tenancy disabled
|
|
66
|
+
if (multiTenancyEnabled === false) {
|
|
67
|
+
return (_jsxs("div", { className: `cls_org_management_layout flex flex-col items-center justify-center p-8 gap-4 ${className || ""}`, children: [_jsx(Building2, { className: "h-12 w-12 text-amber-500" }), _jsx("h1", { className: "text-xl font-semibold", children: "Multi-Tenancy Disabled" }), _jsx("p", { className: "text-muted-foreground text-center max-w-md", children: multiTenancyDisabledMessage }), _jsxs("p", { className: "text-xs text-muted-foreground text-center", children: ["Enable multi-tenancy by setting", " ", _jsx("code", { className: "bg-muted px-1 py-0.5 rounded", children: "enable_multi_tenancy = true" }), " in the", " ", _jsx("code", { className: "bg-muted px-1 py-0.5 rounded", children: "[hazo_auth__multi_tenancy]" }), " section."] })] }));
|
|
68
|
+
}
|
|
69
|
+
// Check global admin permission
|
|
70
|
+
const isGlobalAdmin = authResult.permissions.includes(globalAdminPermission);
|
|
71
|
+
return (_jsxs("div", { className: `cls_org_management_layout flex flex-col gap-6 p-4 w-full max-w-5xl mx-auto ${className || ""}`, children: [_jsxs("div", { className: "cls_org_management_header", children: [_jsxs("h1", { className: "text-2xl font-bold flex items-center gap-2", children: [_jsx(Building2, { className: "h-6 w-6" }), title] }), _jsx("p", { className: "text-muted-foreground", children: description })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { className: "text-lg", children: "Organization Hierarchy" }), _jsxs(CardDescription, { children: ["View and manage the organization structure.", isGlobalAdmin
|
|
72
|
+
? " As a global admin, you can see and manage all organizations."
|
|
73
|
+
: " You can manage organizations within your access scope."] })] }), _jsx(CardContent, { children: _jsx(OrgHierarchyTab, { isGlobalAdmin: isGlobalAdmin }) })] })] }));
|
|
74
|
+
}
|
|
75
|
+
export default OrgManagementLayout;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { PasswordRequirementOptions } from "../../../../lib/utils/password_validator";
|
|
2
|
+
export type { PasswordRequirementOptions };
|
|
1
3
|
export type LayoutFieldId = string;
|
|
2
4
|
export type LayoutFieldDefinition = {
|
|
3
5
|
id: LayoutFieldId;
|
|
@@ -23,13 +25,6 @@ export type ButtonPaletteDefaults = {
|
|
|
23
25
|
cancelText: string;
|
|
24
26
|
};
|
|
25
27
|
export type ButtonPaletteOverrides = Partial<ButtonPaletteDefaults>;
|
|
26
|
-
export type PasswordRequirementOptions = {
|
|
27
|
-
minimum_length: number;
|
|
28
|
-
require_uppercase: boolean;
|
|
29
|
-
require_lowercase: boolean;
|
|
30
|
-
require_number: boolean;
|
|
31
|
-
require_special: boolean;
|
|
32
|
-
};
|
|
33
28
|
export type PasswordRequirementOverrides = Partial<PasswordRequirementOptions>;
|
|
34
29
|
export declare const resolveFieldDefinitions: (baseDefinitions: LayoutFieldMap, overrides?: LayoutFieldMapOverrides) => LayoutFieldMap;
|
|
35
30
|
export declare const resolveLabels: (defaults: LayoutLabelDefaults, overrides?: LayoutLabelOverrides) => LayoutLabelDefaults;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout_customization.d.ts","sourceRoot":"","sources":["../../../../../src/components/layouts/shared/config/layout_customization.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC;AAEnC,MAAM,MAAM,qBAAqB,GAAG;IAClC,EAAE,EAAE,aAAa,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,aAAa,EAAE,qBAAqB,CAAC,CAAC;AAC1E,MAAM,MAAM,uBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;AAErG,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAEhE,MAAM,MAAM,qBAAqB,GAAG;IAClC,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAEpE,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"layout_customization.d.ts","sourceRoot":"","sources":["../../../../../src/components/layouts/shared/config/layout_customization.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,0CAA0C,CAAC;AAC3F,YAAY,EAAE,0BAA0B,EAAE,CAAC;AAG3C,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC;AAEnC,MAAM,MAAM,qBAAqB,GAAG;IAClC,EAAE,EAAE,aAAa,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,aAAa,EAAE,qBAAqB,CAAC,CAAC;AAC1E,MAAM,MAAM,uBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;AAErG,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAEhE,MAAM,MAAM,qBAAqB,GAAG;IAClC,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAEpE,MAAM,MAAM,4BAA4B,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAAC;AAG/E,eAAO,MAAM,uBAAuB,GAClC,iBAAiB,cAAc,EAC/B,YAAY,uBAAuB,KAClC,cAqBF,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,UAAU,mBAAmB,EAC7B,YAAY,oBAAoB,KAC/B,mBAGD,CAAC;AAEH,eAAO,MAAM,oBAAoB,GAC/B,UAAU,qBAAqB,EAC/B,YAAY,sBAAsB,KACjC,qBAGD,CAAC;AAEH,eAAO,MAAM,2BAA2B,GACtC,UAAU,0BAA0B,EACpC,YAAY,4BAA4B,KACvC,0BAGD,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type OrgHierarchyTabProps = {
|
|
2
|
+
className?: string;
|
|
3
|
+
/** Whether the user has global admin permission (can see all orgs) */
|
|
4
|
+
isGlobalAdmin?: boolean;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Organization Hierarchy tab component for managing multi-tenancy organizations
|
|
8
|
+
* Displays organizations in a tree view for intuitive hierarchy configuration
|
|
9
|
+
* @param props - Component props
|
|
10
|
+
* @returns Organization Hierarchy tab component
|
|
11
|
+
*/
|
|
12
|
+
export declare function OrgHierarchyTab({ className, isGlobalAdmin, }: OrgHierarchyTabProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=org_hierarchy_tab.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"org_hierarchy_tab.d.ts","sourceRoot":"","sources":["../../../../../src/components/layouts/user_management/components/org_hierarchy_tab.tsx"],"names":[],"mappings":"AA6CA,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AA6GF;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAC9B,SAAS,EACT,aAAqB,GACtB,EAAE,oBAAoB,2CA0ftB"}
|