hazo_auth 4.4.1 → 4.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +207 -5
- package/SETUP_CHECKLIST.md +1 -1
- package/cli-src/lib/auth/auth_types.ts +22 -0
- package/cli-src/lib/auth/hazo_get_auth.server.ts +25 -1
- package/cli-src/lib/auth/session_token_validator.edge.ts +1 -0
- package/cli-src/lib/config/default_config.ts +36 -0
- package/cli-src/lib/navbar_config.server.ts +129 -0
- package/cli-src/lib/scope_hierarchy_config.server.ts +3 -14
- package/cli-src/lib/services/registration_service.ts +12 -0
- package/cli-src/lib/services/scope_labels_service.ts +21 -21
- package/cli-src/lib/services/scope_service.ts +15 -11
- package/cli-src/lib/services/session_token_service.ts +1 -0
- package/cli-src/lib/ui_shell_config.server.ts +15 -0
- package/cli-src/lib/user_types_config.server.ts +178 -0
- package/dist/app/api/hazo_auth/me/route.d.ts.map +1 -1
- package/dist/app/api/hazo_auth/me/route.js +17 -0
- package/dist/app/api/hazo_auth/org_management/orgs/route.d.ts +26 -0
- package/dist/app/api/hazo_auth/org_management/orgs/route.d.ts.map +1 -0
- package/dist/app/api/hazo_auth/org_management/orgs/route.js +315 -0
- package/dist/app/api/hazo_auth/user_management/users/route.d.ts +11 -1
- package/dist/app/api/hazo_auth/user_management/users/route.d.ts.map +1 -1
- package/dist/app/api/hazo_auth/user_management/users/route.js +121 -16
- package/dist/components/layouts/my_settings/components/profile_picture_library_tab.d.ts.map +1 -1
- package/dist/components/layouts/my_settings/components/profile_picture_library_tab.js +8 -14
- package/dist/components/layouts/rbac_test/index.d.ts +1 -3
- package/dist/components/layouts/rbac_test/index.d.ts.map +1 -1
- package/dist/components/layouts/rbac_test/index.js +2 -2
- package/dist/components/layouts/shared/components/auth_navbar.d.ts +26 -0
- package/dist/components/layouts/shared/components/auth_navbar.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/auth_navbar.js +14 -0
- package/dist/components/layouts/shared/components/auth_page_shell.d.ts +3 -1
- package/dist/components/layouts/shared/components/auth_page_shell.d.ts.map +1 -1
- package/dist/components/layouts/shared/components/auth_page_shell.js +17 -2
- package/dist/components/layouts/shared/components/standalone_layout_wrapper.d.ts +6 -1
- package/dist/components/layouts/shared/components/standalone_layout_wrapper.d.ts.map +1 -1
- package/dist/components/layouts/shared/components/standalone_layout_wrapper.js +7 -2
- package/dist/components/layouts/shared/index.d.ts +2 -0
- package/dist/components/layouts/shared/index.d.ts.map +1 -1
- package/dist/components/layouts/shared/index.js +1 -0
- package/dist/components/layouts/user_management/components/scope_hierarchy_tab.d.ts +3 -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 +45 -18
- package/dist/components/layouts/user_management/components/scope_labels_tab.d.ts +3 -2
- package/dist/components/layouts/user_management/components/scope_labels_tab.d.ts.map +1 -1
- package/dist/components/layouts/user_management/components/scope_labels_tab.js +48 -20
- 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 +1 -1
- package/dist/components/layouts/user_management/index.d.ts +11 -3
- package/dist/components/layouts/user_management/index.d.ts.map +1 -1
- package/dist/components/layouts/user_management/index.js +52 -5
- package/dist/components/ui/user-type-badge.d.ts +23 -0
- package/dist/components/ui/user-type-badge.d.ts.map +1 -0
- package/dist/components/ui/user-type-badge.js +42 -0
- package/dist/lib/auth/auth_types.d.ts +17 -0
- package/dist/lib/auth/auth_types.d.ts.map +1 -1
- package/dist/lib/auth/auth_types.js +11 -0
- package/dist/lib/auth/hazo_get_auth.server.d.ts.map +1 -1
- package/dist/lib/auth/hazo_get_auth.server.js +21 -1
- package/dist/lib/config/default_config.d.ts +60 -0
- package/dist/lib/config/default_config.d.ts.map +1 -1
- package/dist/lib/config/default_config.js +34 -0
- package/dist/lib/navbar_config.server.d.ts +36 -0
- package/dist/lib/navbar_config.server.d.ts.map +1 -0
- package/dist/lib/navbar_config.server.js +45 -0
- package/dist/lib/scope_hierarchy_config.server.d.ts +3 -7
- package/dist/lib/scope_hierarchy_config.server.d.ts.map +1 -1
- package/dist/lib/scope_hierarchy_config.server.js +1 -10
- package/dist/lib/services/registration_service.d.ts.map +1 -1
- package/dist/lib/services/registration_service.js +8 -0
- package/dist/lib/services/scope_labels_service.d.ts +7 -7
- package/dist/lib/services/scope_labels_service.d.ts.map +1 -1
- package/dist/lib/services/scope_labels_service.js +20 -20
- package/dist/lib/services/scope_service.d.ts +8 -5
- package/dist/lib/services/scope_service.d.ts.map +1 -1
- package/dist/lib/services/scope_service.js +9 -8
- package/dist/lib/ui_shell_config.server.d.ts +5 -0
- package/dist/lib/ui_shell_config.server.d.ts.map +1 -1
- package/dist/lib/ui_shell_config.server.js +5 -0
- package/dist/lib/user_types_config.server.d.ts +56 -0
- package/dist/lib/user_types_config.server.d.ts.map +1 -0
- package/dist/lib/user_types_config.server.js +100 -0
- package/dist/server/routes/index.d.ts +1 -0
- package/dist/server/routes/index.d.ts.map +1 -1
- package/dist/server/routes/index.js +2 -0
- package/dist/server/routes/org_management_orgs.d.ts +2 -0
- package/dist/server/routes/org_management_orgs.d.ts.map +1 -0
- package/dist/server/routes/org_management_orgs.js +2 -0
- package/hazo_auth_config.example.ini +9 -0
- package/package.json +1 -1
- package/cli-src/server/logging/logger_service.ts +0 -56
- /package/public/profile_pictures/library/Cars/{050 - citroe/314/210n_c3.jpeg" → 050 - citro/303/253n_c3.jpeg"} +0 -0
- /package/public/profile_pictures/library/Cars/{064 - lamborghini_huraca/314/201n.jpeg" → 064 - lamborghini_hurac/303/241n.jpeg"} +0 -0
- /package/public/profile_pictures/library/Cars/{099 - citroe/314/210n_2cv_(classic).jpeg" → 099 - citro/303/253n_2cv_(classic).jpeg"} +0 -0
- /package/public/profile_pictures/library/Cars/{131 - lamborghini_huraca/314/201n_sto.jpeg" → 131 - lamborghini_hurac/303/241n_sto.jpeg"} +0 -0
|
@@ -11,7 +11,7 @@ import { SCOPE_LEVELS } from "./scope_service.js";
|
|
|
11
11
|
// section: types
|
|
12
12
|
export type ScopeLabel = {
|
|
13
13
|
id: string;
|
|
14
|
-
|
|
14
|
+
org_id: string;
|
|
15
15
|
scope_type: ScopeLevel;
|
|
16
16
|
label: string;
|
|
17
17
|
created_at: string;
|
|
@@ -43,11 +43,11 @@ export const DEFAULT_SCOPE_LABELS: Record<ScopeLevel, string> = {
|
|
|
43
43
|
*/
|
|
44
44
|
export async function get_scope_labels(
|
|
45
45
|
adapter: HazoConnectAdapter,
|
|
46
|
-
|
|
46
|
+
org_id: string,
|
|
47
47
|
): Promise<ScopeLabelResult> {
|
|
48
48
|
try {
|
|
49
49
|
const label_service = createCrudService(adapter, "hazo_scope_labels");
|
|
50
|
-
const labels = await label_service.findBy({
|
|
50
|
+
const labels = await label_service.findBy({ org_id });
|
|
51
51
|
|
|
52
52
|
return {
|
|
53
53
|
success: true,
|
|
@@ -63,7 +63,7 @@ export async function get_scope_labels(
|
|
|
63
63
|
filename: "scope_labels_service.ts",
|
|
64
64
|
line_number: 0,
|
|
65
65
|
operation: "get_scope_labels",
|
|
66
|
-
|
|
66
|
+
org_id,
|
|
67
67
|
},
|
|
68
68
|
});
|
|
69
69
|
|
|
@@ -79,11 +79,11 @@ export async function get_scope_labels(
|
|
|
79
79
|
*/
|
|
80
80
|
export async function get_scope_labels_with_defaults(
|
|
81
81
|
adapter: HazoConnectAdapter,
|
|
82
|
-
|
|
82
|
+
org_id: string,
|
|
83
83
|
custom_defaults?: Record<ScopeLevel, string>,
|
|
84
84
|
): Promise<ScopeLabelResult> {
|
|
85
85
|
try {
|
|
86
|
-
const result = await get_scope_labels(adapter,
|
|
86
|
+
const result = await get_scope_labels(adapter, org_id);
|
|
87
87
|
if (!result.success) {
|
|
88
88
|
return result;
|
|
89
89
|
}
|
|
@@ -107,7 +107,7 @@ export async function get_scope_labels_with_defaults(
|
|
|
107
107
|
// Create a synthetic label entry (not persisted)
|
|
108
108
|
all_labels.push({
|
|
109
109
|
id: "", // Empty ID indicates this is a default, not from DB
|
|
110
|
-
|
|
110
|
+
org_id,
|
|
111
111
|
scope_type: level,
|
|
112
112
|
label: defaults[level],
|
|
113
113
|
created_at: "",
|
|
@@ -130,7 +130,7 @@ export async function get_scope_labels_with_defaults(
|
|
|
130
130
|
filename: "scope_labels_service.ts",
|
|
131
131
|
line_number: 0,
|
|
132
132
|
operation: "get_scope_labels_with_defaults",
|
|
133
|
-
|
|
133
|
+
org_id,
|
|
134
134
|
},
|
|
135
135
|
});
|
|
136
136
|
|
|
@@ -147,13 +147,13 @@ export async function get_scope_labels_with_defaults(
|
|
|
147
147
|
*/
|
|
148
148
|
export async function get_label_for_level(
|
|
149
149
|
adapter: HazoConnectAdapter,
|
|
150
|
-
|
|
150
|
+
org_id: string,
|
|
151
151
|
scope_type: ScopeLevel,
|
|
152
152
|
custom_default?: string,
|
|
153
153
|
): Promise<string> {
|
|
154
154
|
try {
|
|
155
155
|
const label_service = createCrudService(adapter, "hazo_scope_labels");
|
|
156
|
-
const labels = await label_service.findBy({
|
|
156
|
+
const labels = await label_service.findBy({ org_id, scope_type });
|
|
157
157
|
|
|
158
158
|
if (Array.isArray(labels) && labels.length > 0) {
|
|
159
159
|
return (labels[0] as ScopeLabel).label;
|
|
@@ -172,7 +172,7 @@ export async function get_label_for_level(
|
|
|
172
172
|
*/
|
|
173
173
|
export async function upsert_scope_label(
|
|
174
174
|
adapter: HazoConnectAdapter,
|
|
175
|
-
|
|
175
|
+
org_id: string,
|
|
176
176
|
scope_type: ScopeLevel,
|
|
177
177
|
label: string,
|
|
178
178
|
): Promise<ScopeLabelResult> {
|
|
@@ -180,8 +180,8 @@ export async function upsert_scope_label(
|
|
|
180
180
|
const label_service = createCrudService(adapter, "hazo_scope_labels");
|
|
181
181
|
const now = new Date().toISOString();
|
|
182
182
|
|
|
183
|
-
// Check if label already exists for this
|
|
184
|
-
const existing = await label_service.findBy({
|
|
183
|
+
// Check if label already exists for this org_id + scope_type
|
|
184
|
+
const existing = await label_service.findBy({ org_id, scope_type });
|
|
185
185
|
|
|
186
186
|
if (Array.isArray(existing) && existing.length > 0) {
|
|
187
187
|
// Update existing
|
|
@@ -206,7 +206,7 @@ export async function upsert_scope_label(
|
|
|
206
206
|
// Create new
|
|
207
207
|
const inserted = await label_service.insert({
|
|
208
208
|
id: randomUUID(),
|
|
209
|
-
|
|
209
|
+
org_id,
|
|
210
210
|
scope_type,
|
|
211
211
|
label,
|
|
212
212
|
created_at: now,
|
|
@@ -235,7 +235,7 @@ export async function upsert_scope_label(
|
|
|
235
235
|
filename: "scope_labels_service.ts",
|
|
236
236
|
line_number: 0,
|
|
237
237
|
operation: "upsert_scope_label",
|
|
238
|
-
|
|
238
|
+
org_id,
|
|
239
239
|
scope_type,
|
|
240
240
|
label,
|
|
241
241
|
},
|
|
@@ -254,14 +254,14 @@ export async function upsert_scope_label(
|
|
|
254
254
|
*/
|
|
255
255
|
export async function batch_upsert_scope_labels(
|
|
256
256
|
adapter: HazoConnectAdapter,
|
|
257
|
-
|
|
257
|
+
org_id: string,
|
|
258
258
|
labels: Array<{ scope_type: ScopeLevel; label: string }>,
|
|
259
259
|
): Promise<ScopeLabelResult> {
|
|
260
260
|
try {
|
|
261
261
|
const results: ScopeLabel[] = [];
|
|
262
262
|
|
|
263
263
|
for (const { scope_type, label } of labels) {
|
|
264
|
-
const result = await upsert_scope_label(adapter,
|
|
264
|
+
const result = await upsert_scope_label(adapter, org_id, scope_type, label);
|
|
265
265
|
if (!result.success) {
|
|
266
266
|
return {
|
|
267
267
|
success: false,
|
|
@@ -287,7 +287,7 @@ export async function batch_upsert_scope_labels(
|
|
|
287
287
|
filename: "scope_labels_service.ts",
|
|
288
288
|
line_number: 0,
|
|
289
289
|
operation: "batch_upsert_scope_labels",
|
|
290
|
-
|
|
290
|
+
org_id,
|
|
291
291
|
},
|
|
292
292
|
});
|
|
293
293
|
|
|
@@ -303,14 +303,14 @@ export async function batch_upsert_scope_labels(
|
|
|
303
303
|
*/
|
|
304
304
|
export async function delete_scope_label(
|
|
305
305
|
adapter: HazoConnectAdapter,
|
|
306
|
-
|
|
306
|
+
org_id: string,
|
|
307
307
|
scope_type: ScopeLevel,
|
|
308
308
|
): Promise<ScopeLabelResult> {
|
|
309
309
|
try {
|
|
310
310
|
const label_service = createCrudService(adapter, "hazo_scope_labels");
|
|
311
311
|
|
|
312
312
|
// Find the label
|
|
313
|
-
const existing = await label_service.findBy({
|
|
313
|
+
const existing = await label_service.findBy({ org_id, scope_type });
|
|
314
314
|
|
|
315
315
|
if (!Array.isArray(existing) || existing.length === 0) {
|
|
316
316
|
return {
|
|
@@ -335,7 +335,7 @@ export async function delete_scope_label(
|
|
|
335
335
|
filename: "scope_labels_service.ts",
|
|
336
336
|
line_number: 0,
|
|
337
337
|
operation: "delete_scope_label",
|
|
338
|
-
|
|
338
|
+
org_id,
|
|
339
339
|
scope_type,
|
|
340
340
|
},
|
|
341
341
|
});
|
|
@@ -18,7 +18,8 @@ export type ScopeLevel =
|
|
|
18
18
|
export type ScopeRecord = {
|
|
19
19
|
id: string;
|
|
20
20
|
seq: string;
|
|
21
|
-
|
|
21
|
+
org_id: string;
|
|
22
|
+
root_org_id: string;
|
|
22
23
|
name: string;
|
|
23
24
|
parent_scope_id?: string | null;
|
|
24
25
|
created_at: string;
|
|
@@ -33,7 +34,8 @@ export type ScopeServiceResult = {
|
|
|
33
34
|
};
|
|
34
35
|
|
|
35
36
|
export type CreateScopeData = {
|
|
36
|
-
|
|
37
|
+
org_id: string;
|
|
38
|
+
root_org_id: string;
|
|
37
39
|
name: string;
|
|
38
40
|
parent_scope_id?: string;
|
|
39
41
|
};
|
|
@@ -99,14 +101,14 @@ export function get_child_level(level: ScopeLevel): ScopeLevel | undefined {
|
|
|
99
101
|
export async function get_scopes_by_level(
|
|
100
102
|
adapter: HazoConnectAdapter,
|
|
101
103
|
level: ScopeLevel,
|
|
102
|
-
|
|
104
|
+
org_id?: string,
|
|
103
105
|
): Promise<ScopeServiceResult> {
|
|
104
106
|
try {
|
|
105
107
|
const scope_service = createCrudService(adapter, level);
|
|
106
108
|
|
|
107
109
|
let scopes: unknown[];
|
|
108
|
-
if (
|
|
109
|
-
scopes = await scope_service.findBy({
|
|
110
|
+
if (org_id) {
|
|
111
|
+
scopes = await scope_service.findBy({ org_id });
|
|
110
112
|
} else {
|
|
111
113
|
scopes = await scope_service.findBy({});
|
|
112
114
|
}
|
|
@@ -133,7 +135,7 @@ export async function get_scopes_by_level(
|
|
|
133
135
|
line_number: 0,
|
|
134
136
|
operation: "get_scopes_by_level",
|
|
135
137
|
level,
|
|
136
|
-
|
|
138
|
+
org_id,
|
|
137
139
|
},
|
|
138
140
|
});
|
|
139
141
|
|
|
@@ -272,7 +274,8 @@ export async function create_scope(
|
|
|
272
274
|
}
|
|
273
275
|
|
|
274
276
|
const insert_data: Record<string, unknown> = {
|
|
275
|
-
|
|
277
|
+
org_id: data.org_id,
|
|
278
|
+
root_org_id: data.root_org_id,
|
|
276
279
|
name: data.name,
|
|
277
280
|
created_at: now,
|
|
278
281
|
changed_at: now,
|
|
@@ -635,18 +638,19 @@ export type ScopeTreeNode = ScopeRecord & {
|
|
|
635
638
|
export type OrgScopeTreeNode = {
|
|
636
639
|
id: string;
|
|
637
640
|
name: string;
|
|
638
|
-
|
|
641
|
+
org_id: string;
|
|
642
|
+
root_org_id: string;
|
|
639
643
|
isOrgNode: true;
|
|
640
644
|
children: ScopeTreeNode[];
|
|
641
645
|
};
|
|
642
646
|
|
|
643
647
|
export async function get_scope_tree(
|
|
644
648
|
adapter: HazoConnectAdapter,
|
|
645
|
-
|
|
649
|
+
org_id: string,
|
|
646
650
|
): Promise<{ success: boolean; tree?: ScopeTreeNode[]; error?: string }> {
|
|
647
651
|
try {
|
|
648
652
|
// Get all L1 scopes for this org
|
|
649
|
-
const l1_result = await get_scopes_by_level(adapter, "hazo_scopes_l1",
|
|
653
|
+
const l1_result = await get_scopes_by_level(adapter, "hazo_scopes_l1", org_id);
|
|
650
654
|
if (!l1_result.success || !l1_result.scopes) {
|
|
651
655
|
return l1_result;
|
|
652
656
|
}
|
|
@@ -696,7 +700,7 @@ export async function get_scope_tree(
|
|
|
696
700
|
filename: "scope_service.ts",
|
|
697
701
|
line_number: 0,
|
|
698
702
|
operation: "get_scope_tree",
|
|
699
|
-
|
|
703
|
+
org_id,
|
|
700
704
|
},
|
|
701
705
|
});
|
|
702
706
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// file_description: load ui shell layout settings from hazo_auth_config.ini
|
|
2
2
|
// section: imports
|
|
3
3
|
import { get_config_value } from "./config/config_loader.server.js";
|
|
4
|
+
import { get_navbar_config, type NavbarConfig } from "./navbar_config.server.js";
|
|
4
5
|
|
|
5
6
|
// section: types
|
|
6
7
|
export type UiShellLayoutMode = "test_sidebar" | "standalone";
|
|
@@ -13,6 +14,10 @@ export type UiShellConfig = {
|
|
|
13
14
|
standalone_content_class: string;
|
|
14
15
|
standalone_show_heading: boolean;
|
|
15
16
|
standalone_show_description: boolean;
|
|
17
|
+
/** Navbar configuration for standalone mode */
|
|
18
|
+
navbar: NavbarConfig;
|
|
19
|
+
/** Enable vertical centering in standalone mode */
|
|
20
|
+
vertical_center: boolean;
|
|
16
21
|
};
|
|
17
22
|
|
|
18
23
|
// section: helpers
|
|
@@ -58,6 +63,14 @@ export function get_ui_shell_config(): UiShellConfig {
|
|
|
58
63
|
"true"
|
|
59
64
|
).toLowerCase() === "true";
|
|
60
65
|
|
|
66
|
+
const vertical_center = get_config_value(
|
|
67
|
+
section,
|
|
68
|
+
"vertical_center",
|
|
69
|
+
"true"
|
|
70
|
+
).toLowerCase() === "true";
|
|
71
|
+
|
|
72
|
+
const navbar = get_navbar_config();
|
|
73
|
+
|
|
61
74
|
return {
|
|
62
75
|
layout_mode,
|
|
63
76
|
standalone_heading,
|
|
@@ -66,6 +79,8 @@ export function get_ui_shell_config(): UiShellConfig {
|
|
|
66
79
|
standalone_content_class,
|
|
67
80
|
standalone_show_heading,
|
|
68
81
|
standalone_show_description,
|
|
82
|
+
navbar,
|
|
83
|
+
vertical_center,
|
|
69
84
|
};
|
|
70
85
|
}
|
|
71
86
|
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
// file_description: server-only helper to read user types configuration from hazo_auth_config.ini
|
|
2
|
+
// section: imports
|
|
3
|
+
import {
|
|
4
|
+
get_config_value,
|
|
5
|
+
get_config_boolean,
|
|
6
|
+
read_config_section,
|
|
7
|
+
} from "./config/config_loader.server.js";
|
|
8
|
+
import { DEFAULT_USER_TYPES } from "./config/default_config.js";
|
|
9
|
+
|
|
10
|
+
// section: types
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Badge color preset names supported by the UserTypeBadge component
|
|
14
|
+
*/
|
|
15
|
+
export type BadgeColorPreset =
|
|
16
|
+
| "blue"
|
|
17
|
+
| "green"
|
|
18
|
+
| "red"
|
|
19
|
+
| "yellow"
|
|
20
|
+
| "purple"
|
|
21
|
+
| "gray"
|
|
22
|
+
| "orange"
|
|
23
|
+
| "pink";
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Individual user type definition parsed from config
|
|
27
|
+
*/
|
|
28
|
+
export type UserTypeDefinition = {
|
|
29
|
+
/** Unique key stored in database (e.g., "admin", "standard") */
|
|
30
|
+
key: string;
|
|
31
|
+
/** Display label (e.g., "Administrator", "Standard User") */
|
|
32
|
+
label: string;
|
|
33
|
+
/** Badge color - preset name or hex value */
|
|
34
|
+
badge_color: string;
|
|
35
|
+
/** Whether this is a preset color or custom hex */
|
|
36
|
+
is_preset_color: boolean;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* User types configuration options
|
|
41
|
+
*/
|
|
42
|
+
export type UserTypesConfig = {
|
|
43
|
+
/** Whether user types feature is enabled (default: false) */
|
|
44
|
+
enable_user_types: boolean;
|
|
45
|
+
/** Default user type for new users (empty = no default) */
|
|
46
|
+
default_user_type: string;
|
|
47
|
+
/** Map of user type definitions by key */
|
|
48
|
+
user_types: Map<string, UserTypeDefinition>;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// section: constants
|
|
52
|
+
|
|
53
|
+
const SECTION_NAME = "hazo_auth__user_types";
|
|
54
|
+
|
|
55
|
+
const PRESET_COLORS = new Set<BadgeColorPreset>([
|
|
56
|
+
"blue",
|
|
57
|
+
"green",
|
|
58
|
+
"red",
|
|
59
|
+
"yellow",
|
|
60
|
+
"purple",
|
|
61
|
+
"gray",
|
|
62
|
+
"orange",
|
|
63
|
+
"pink",
|
|
64
|
+
]);
|
|
65
|
+
|
|
66
|
+
// section: helpers
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Parses a user type definition string
|
|
70
|
+
* Format: key:label:color (e.g., "admin:Administrator:red" or "custom:Custom Type:#4CAF50")
|
|
71
|
+
* @param value - The config value string
|
|
72
|
+
* @returns UserTypeDefinition or null if invalid
|
|
73
|
+
*/
|
|
74
|
+
function parse_user_type_definition(value: string): UserTypeDefinition | null {
|
|
75
|
+
const parts = value.split(":").map((s) => s.trim());
|
|
76
|
+
if (parts.length < 2) return null;
|
|
77
|
+
|
|
78
|
+
const key = parts[0];
|
|
79
|
+
const label = parts[1];
|
|
80
|
+
const badge_color = parts[2] || "gray";
|
|
81
|
+
|
|
82
|
+
if (!key || !label) return null;
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
key,
|
|
86
|
+
label,
|
|
87
|
+
badge_color,
|
|
88
|
+
is_preset_color: PRESET_COLORS.has(badge_color as BadgeColorPreset),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Reads user types configuration from hazo_auth_config.ini file
|
|
94
|
+
* Falls back to defaults if config file is not found or section is missing
|
|
95
|
+
* @returns User types configuration options
|
|
96
|
+
*/
|
|
97
|
+
export function get_user_types_config(): UserTypesConfig {
|
|
98
|
+
const enable_user_types = get_config_boolean(
|
|
99
|
+
SECTION_NAME,
|
|
100
|
+
"enable_user_types",
|
|
101
|
+
DEFAULT_USER_TYPES.enable_user_types
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
const default_user_type = get_config_value(
|
|
105
|
+
SECTION_NAME,
|
|
106
|
+
"default_user_type",
|
|
107
|
+
DEFAULT_USER_TYPES.default_user_type
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
// Parse user type definitions from config
|
|
111
|
+
const user_types = new Map<string, UserTypeDefinition>();
|
|
112
|
+
const section = read_config_section(SECTION_NAME);
|
|
113
|
+
|
|
114
|
+
if (section) {
|
|
115
|
+
// Look for user_type_1, user_type_2, etc. (up to 50 types supported)
|
|
116
|
+
for (let i = 1; i <= 50; i++) {
|
|
117
|
+
const key = `user_type_${i}`;
|
|
118
|
+
const value = section[key];
|
|
119
|
+
if (!value) continue;
|
|
120
|
+
|
|
121
|
+
const type_def = parse_user_type_definition(value);
|
|
122
|
+
if (type_def) {
|
|
123
|
+
user_types.set(type_def.key, type_def);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return {
|
|
129
|
+
enable_user_types,
|
|
130
|
+
default_user_type,
|
|
131
|
+
user_types,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Checks if user types feature is enabled in the configuration
|
|
137
|
+
* Convenience function for quick checks
|
|
138
|
+
*/
|
|
139
|
+
export function is_user_types_enabled(): boolean {
|
|
140
|
+
return get_config_boolean(
|
|
141
|
+
SECTION_NAME,
|
|
142
|
+
"enable_user_types",
|
|
143
|
+
DEFAULT_USER_TYPES.enable_user_types
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Gets the default user type from config
|
|
149
|
+
* Returns empty string if not configured
|
|
150
|
+
*/
|
|
151
|
+
export function get_default_user_type(): string {
|
|
152
|
+
return get_config_value(
|
|
153
|
+
SECTION_NAME,
|
|
154
|
+
"default_user_type",
|
|
155
|
+
DEFAULT_USER_TYPES.default_user_type
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Gets user type definition by key
|
|
161
|
+
* @param type_key - The user type key
|
|
162
|
+
* @returns UserTypeDefinition or undefined if not found
|
|
163
|
+
*/
|
|
164
|
+
export function get_user_type_by_key(
|
|
165
|
+
type_key: string
|
|
166
|
+
): UserTypeDefinition | undefined {
|
|
167
|
+
const config = get_user_types_config();
|
|
168
|
+
return config.user_types.get(type_key);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Gets all user type definitions as array (for UI dropdowns)
|
|
173
|
+
* @returns Array of UserTypeDefinition objects
|
|
174
|
+
*/
|
|
175
|
+
export function get_all_user_types(): UserTypeDefinition[] {
|
|
176
|
+
const config = get_user_types_config();
|
|
177
|
+
return Array.from(config.user_types.values());
|
|
178
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../src/app/api/hazo_auth/me/route.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../src/app/api/hazo_auth/me/route.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAaxD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAsB,GAAG,CAAC,OAAO,EAAE,WAAW;;IA4G7C"}
|
|
@@ -8,6 +8,7 @@ import { createCrudService } from "hazo_connect/server";
|
|
|
8
8
|
import { map_db_source_to_ui } from "../../../../lib/services/profile_picture_source_mapper";
|
|
9
9
|
import { create_app_logger } from "../../../../lib/app_logger";
|
|
10
10
|
import { get_filename, get_line_number } from "../../../../lib/utils/api_route_helpers";
|
|
11
|
+
import { is_user_types_enabled, get_user_type_by_key, } from "../../../../lib/user_types_config.server";
|
|
11
12
|
// section: api_handler
|
|
12
13
|
/**
|
|
13
14
|
* GET /api/hazo_auth/me
|
|
@@ -71,6 +72,19 @@ export async function GET(request) {
|
|
|
71
72
|
// Check if user has a password set
|
|
72
73
|
const password_hash = user_db.password_hash;
|
|
73
74
|
const has_password = password_hash !== null && password_hash !== undefined && password_hash !== "";
|
|
75
|
+
// Get user type info if feature is enabled
|
|
76
|
+
const user_type = user_db.user_type || null;
|
|
77
|
+
let user_type_info = null;
|
|
78
|
+
if (is_user_types_enabled() && user_type) {
|
|
79
|
+
const type_def = get_user_type_by_key(user_type);
|
|
80
|
+
if (type_def) {
|
|
81
|
+
user_type_info = {
|
|
82
|
+
key: type_def.key,
|
|
83
|
+
label: type_def.label,
|
|
84
|
+
badge_color: type_def.badge_color,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
74
88
|
// Return unified format with all fields
|
|
75
89
|
const profile_pic = auth_result.user.profile_picture_url;
|
|
76
90
|
return NextResponse.json({
|
|
@@ -91,6 +105,9 @@ export async function GET(request) {
|
|
|
91
105
|
auth_providers,
|
|
92
106
|
has_password,
|
|
93
107
|
google_connected: auth_providers.includes("google"),
|
|
108
|
+
// User type fields (when feature is enabled)
|
|
109
|
+
user_type,
|
|
110
|
+
user_type_info,
|
|
94
111
|
// Permissions and user object (always included)
|
|
95
112
|
user: auth_result.user,
|
|
96
113
|
permissions: auth_result.permissions,
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { NextRequest, NextResponse } from "next/server";
|
|
2
|
+
export declare const dynamic = "force-dynamic";
|
|
3
|
+
/**
|
|
4
|
+
* GET - Fetch organizations
|
|
5
|
+
* Query params:
|
|
6
|
+
* - action: 'list' | 'tree' (default: 'list')
|
|
7
|
+
* - include_inactive: boolean (default: false)
|
|
8
|
+
* - root_org_id: string (optional, filter by root org - required unless global admin)
|
|
9
|
+
*/
|
|
10
|
+
export declare function GET(request: NextRequest): Promise<NextResponse<unknown>>;
|
|
11
|
+
/**
|
|
12
|
+
* POST - Create a new organization
|
|
13
|
+
* Body: { name: string, user_limit?: number, parent_org_id?: string }
|
|
14
|
+
*/
|
|
15
|
+
export declare function POST(request: NextRequest): Promise<NextResponse<unknown>>;
|
|
16
|
+
/**
|
|
17
|
+
* PATCH - Update an existing organization
|
|
18
|
+
* Body: { org_id: string, name?: string, user_limit?: number }
|
|
19
|
+
*/
|
|
20
|
+
export declare function PATCH(request: NextRequest): Promise<NextResponse<unknown>>;
|
|
21
|
+
/**
|
|
22
|
+
* DELETE - Soft delete an organization (sets active = false)
|
|
23
|
+
* Query params: org_id
|
|
24
|
+
*/
|
|
25
|
+
export declare function DELETE(request: NextRequest): Promise<NextResponse<unknown>>;
|
|
26
|
+
//# sourceMappingURL=route.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/app/api/hazo_auth/org_management/orgs/route.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAiBxD,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAqDvC;;;;;;GAMG;AACH,wBAAsB,GAAG,CAAC,OAAO,EAAE,WAAW,kCAmF7C;AAED;;;GAGG;AACH,wBAAsB,IAAI,CAAC,OAAO,EAAE,WAAW,kCA6F9C;AAED;;;GAGG;AACH,wBAAsB,KAAK,CAAC,OAAO,EAAE,WAAW,kCA2G/C;AAED;;;GAGG;AACH,wBAAsB,MAAM,CAAC,OAAO,EAAE,WAAW,kCA4EhD"}
|