hazo_auth 3.0.3 → 4.0.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.
Files changed (67) hide show
  1. package/README.md +146 -0
  2. package/SETUP_CHECKLIST.md +369 -0
  3. package/dist/app/api/hazo_auth/library_photo/[category]/[filename]/route.d.ts +2 -2
  4. package/dist/app/api/hazo_auth/library_photo/[category]/[filename]/route.d.ts.map +1 -1
  5. package/dist/app/api/hazo_auth/library_photo/[category]/[filename]/route.js +1 -1
  6. package/dist/app/api/hazo_auth/profile_picture/[filename]/route.d.ts +2 -2
  7. package/dist/app/api/hazo_auth/profile_picture/[filename]/route.d.ts.map +1 -1
  8. package/dist/app/api/hazo_auth/profile_picture/[filename]/route.js +1 -1
  9. package/dist/components/layouts/my_settings/components/profile_picture_library_tab.d.ts.map +1 -1
  10. package/dist/components/layouts/my_settings/components/profile_picture_library_tab.js +2 -2
  11. package/dist/components/layouts/rbac_test/index.d.ts +15 -0
  12. package/dist/components/layouts/rbac_test/index.d.ts.map +1 -0
  13. package/dist/components/layouts/rbac_test/index.js +378 -0
  14. package/dist/components/layouts/shared/components/password_field.js +1 -1
  15. package/dist/components/layouts/shared/components/sidebar_layout_wrapper.d.ts.map +1 -1
  16. package/dist/components/layouts/shared/components/sidebar_layout_wrapper.js +2 -2
  17. package/dist/components/layouts/shared/components/two_column_auth_layout.js +1 -1
  18. package/dist/components/layouts/user_management/components/roles_matrix.d.ts +2 -3
  19. package/dist/components/layouts/user_management/components/roles_matrix.d.ts.map +1 -1
  20. package/dist/components/layouts/user_management/components/roles_matrix.js +133 -8
  21. package/dist/components/layouts/user_management/components/scope_hierarchy_tab.d.ts +12 -0
  22. package/dist/components/layouts/user_management/components/scope_hierarchy_tab.d.ts.map +1 -0
  23. package/dist/components/layouts/user_management/components/scope_hierarchy_tab.js +291 -0
  24. package/dist/components/layouts/user_management/components/scope_labels_tab.d.ts +13 -0
  25. package/dist/components/layouts/user_management/components/scope_labels_tab.d.ts.map +1 -0
  26. package/dist/components/layouts/user_management/components/scope_labels_tab.js +158 -0
  27. package/dist/components/layouts/user_management/components/user_scopes_tab.d.ts +11 -0
  28. package/dist/components/layouts/user_management/components/user_scopes_tab.d.ts.map +1 -0
  29. package/dist/components/layouts/user_management/components/user_scopes_tab.js +267 -0
  30. package/dist/components/layouts/user_management/index.d.ts +9 -2
  31. package/dist/components/layouts/user_management/index.d.ts.map +1 -1
  32. package/dist/components/layouts/user_management/index.js +22 -6
  33. package/dist/components/ui/select.d.ts +14 -0
  34. package/dist/components/ui/select.d.ts.map +1 -0
  35. package/dist/components/ui/select.js +59 -0
  36. package/dist/components/ui/tree-view.d.ts +108 -0
  37. package/dist/components/ui/tree-view.d.ts.map +1 -0
  38. package/dist/components/ui/tree-view.js +194 -0
  39. package/dist/lib/auth/auth_types.d.ts +45 -0
  40. package/dist/lib/auth/auth_types.d.ts.map +1 -1
  41. package/dist/lib/auth/auth_types.js +13 -0
  42. package/dist/lib/auth/hazo_get_auth.server.d.ts +4 -2
  43. package/dist/lib/auth/hazo_get_auth.server.d.ts.map +1 -1
  44. package/dist/lib/auth/hazo_get_auth.server.js +107 -3
  45. package/dist/lib/auth/scope_cache.d.ts +92 -0
  46. package/dist/lib/auth/scope_cache.d.ts.map +1 -0
  47. package/dist/lib/auth/scope_cache.js +171 -0
  48. package/dist/lib/scope_hierarchy_config.server.d.ts +39 -0
  49. package/dist/lib/scope_hierarchy_config.server.d.ts.map +1 -0
  50. package/dist/lib/scope_hierarchy_config.server.js +96 -0
  51. package/dist/lib/services/email_service.d.ts.map +1 -1
  52. package/dist/lib/services/email_service.js +7 -2
  53. package/dist/lib/services/profile_picture_service.d.ts +1 -7
  54. package/dist/lib/services/profile_picture_service.d.ts.map +1 -1
  55. package/dist/lib/services/profile_picture_service.js +77 -32
  56. package/dist/lib/services/registration_service.js +1 -1
  57. package/dist/lib/services/scope_labels_service.d.ts +48 -0
  58. package/dist/lib/services/scope_labels_service.d.ts.map +1 -0
  59. package/dist/lib/services/scope_labels_service.js +277 -0
  60. package/dist/lib/services/scope_service.d.ts +114 -0
  61. package/dist/lib/services/scope_service.d.ts.map +1 -0
  62. package/dist/lib/services/scope_service.js +582 -0
  63. package/dist/lib/services/user_scope_service.d.ts +74 -0
  64. package/dist/lib/services/user_scope_service.d.ts.map +1 -0
  65. package/dist/lib/services/user_scope_service.js +415 -0
  66. package/hazo_auth_config.example.ini +1 -1
  67. package/package.json +5 -3
@@ -0,0 +1,277 @@
1
+ import { createCrudService } from "hazo_connect/server";
2
+ import { randomUUID } from "crypto";
3
+ import { create_app_logger } from "../app_logger";
4
+ import { sanitize_error_for_user } from "../utils/error_sanitizer";
5
+ import { SCOPE_LEVELS } from "./scope_service";
6
+ // section: constants
7
+ export const DEFAULT_SCOPE_LABELS = {
8
+ hazo_scopes_l1: "Level 1",
9
+ hazo_scopes_l2: "Level 2",
10
+ hazo_scopes_l3: "Level 3",
11
+ hazo_scopes_l4: "Level 4",
12
+ hazo_scopes_l5: "Level 5",
13
+ hazo_scopes_l6: "Level 6",
14
+ hazo_scopes_l7: "Level 7",
15
+ };
16
+ // section: helpers
17
+ /**
18
+ * Gets all scope labels for an organization
19
+ */
20
+ export async function get_scope_labels(adapter, org) {
21
+ try {
22
+ const label_service = createCrudService(adapter, "hazo_scope_labels");
23
+ const labels = await label_service.findBy({ org });
24
+ return {
25
+ success: true,
26
+ labels: Array.isArray(labels) ? labels : [],
27
+ };
28
+ }
29
+ catch (error) {
30
+ const logger = create_app_logger();
31
+ const error_message = sanitize_error_for_user(error, {
32
+ logToConsole: true,
33
+ logToLogger: true,
34
+ logger,
35
+ context: {
36
+ filename: "scope_labels_service.ts",
37
+ line_number: 0,
38
+ operation: "get_scope_labels",
39
+ org,
40
+ },
41
+ });
42
+ return {
43
+ success: false,
44
+ error: error_message,
45
+ };
46
+ }
47
+ }
48
+ /**
49
+ * Gets all scope labels for an organization, with defaults filled in for missing levels
50
+ */
51
+ export async function get_scope_labels_with_defaults(adapter, org, custom_defaults) {
52
+ try {
53
+ const result = await get_scope_labels(adapter, org);
54
+ if (!result.success) {
55
+ return result;
56
+ }
57
+ const existing_labels = result.labels || [];
58
+ const labels_map = new Map();
59
+ // Add existing labels to map
60
+ for (const label of existing_labels) {
61
+ labels_map.set(label.scope_type, label);
62
+ }
63
+ // Create synthetic entries for missing levels (with default labels)
64
+ const defaults = custom_defaults || DEFAULT_SCOPE_LABELS;
65
+ const all_labels = [];
66
+ for (const level of SCOPE_LEVELS) {
67
+ if (labels_map.has(level)) {
68
+ all_labels.push(labels_map.get(level));
69
+ }
70
+ else {
71
+ // Create a synthetic label entry (not persisted)
72
+ all_labels.push({
73
+ id: "", // Empty ID indicates this is a default, not from DB
74
+ org,
75
+ scope_type: level,
76
+ label: defaults[level],
77
+ created_at: "",
78
+ changed_at: "",
79
+ });
80
+ }
81
+ }
82
+ return {
83
+ success: true,
84
+ labels: all_labels,
85
+ };
86
+ }
87
+ catch (error) {
88
+ const logger = create_app_logger();
89
+ const error_message = sanitize_error_for_user(error, {
90
+ logToConsole: true,
91
+ logToLogger: true,
92
+ logger,
93
+ context: {
94
+ filename: "scope_labels_service.ts",
95
+ line_number: 0,
96
+ operation: "get_scope_labels_with_defaults",
97
+ org,
98
+ },
99
+ });
100
+ return {
101
+ success: false,
102
+ error: error_message,
103
+ };
104
+ }
105
+ }
106
+ /**
107
+ * Gets the label for a specific scope level
108
+ * Returns the custom label if set, otherwise returns the default
109
+ */
110
+ export async function get_label_for_level(adapter, org, scope_type, custom_default) {
111
+ try {
112
+ const label_service = createCrudService(adapter, "hazo_scope_labels");
113
+ const labels = await label_service.findBy({ org, scope_type });
114
+ if (Array.isArray(labels) && labels.length > 0) {
115
+ return labels[0].label;
116
+ }
117
+ return custom_default || DEFAULT_SCOPE_LABELS[scope_type];
118
+ }
119
+ catch (_a) {
120
+ // Return default on any error
121
+ return custom_default || DEFAULT_SCOPE_LABELS[scope_type];
122
+ }
123
+ }
124
+ /**
125
+ * Creates or updates a scope label for an organization
126
+ * Uses upsert pattern - creates if not exists, updates if exists
127
+ */
128
+ export async function upsert_scope_label(adapter, org, scope_type, label) {
129
+ try {
130
+ const label_service = createCrudService(adapter, "hazo_scope_labels");
131
+ const now = new Date().toISOString();
132
+ // Check if label already exists for this org + scope_type
133
+ const existing = await label_service.findBy({ org, scope_type });
134
+ if (Array.isArray(existing) && existing.length > 0) {
135
+ // Update existing
136
+ const existing_label = existing[0];
137
+ const updated = await label_service.updateById(existing_label.id, {
138
+ label,
139
+ changed_at: now,
140
+ });
141
+ if (!Array.isArray(updated) || updated.length === 0) {
142
+ return {
143
+ success: false,
144
+ error: "Failed to update scope label",
145
+ };
146
+ }
147
+ return {
148
+ success: true,
149
+ label: updated[0],
150
+ };
151
+ }
152
+ else {
153
+ // Create new
154
+ const inserted = await label_service.insert({
155
+ id: randomUUID(),
156
+ org,
157
+ scope_type,
158
+ label,
159
+ created_at: now,
160
+ changed_at: now,
161
+ });
162
+ if (!Array.isArray(inserted) || inserted.length === 0) {
163
+ return {
164
+ success: false,
165
+ error: "Failed to create scope label",
166
+ };
167
+ }
168
+ return {
169
+ success: true,
170
+ label: inserted[0],
171
+ };
172
+ }
173
+ }
174
+ catch (error) {
175
+ const logger = create_app_logger();
176
+ const error_message = sanitize_error_for_user(error, {
177
+ logToConsole: true,
178
+ logToLogger: true,
179
+ logger,
180
+ context: {
181
+ filename: "scope_labels_service.ts",
182
+ line_number: 0,
183
+ operation: "upsert_scope_label",
184
+ org,
185
+ scope_type,
186
+ label,
187
+ },
188
+ });
189
+ return {
190
+ success: false,
191
+ error: error_message,
192
+ };
193
+ }
194
+ }
195
+ /**
196
+ * Batch upsert scope labels for an organization
197
+ * Useful for saving all labels at once from the UI
198
+ */
199
+ export async function batch_upsert_scope_labels(adapter, org, labels) {
200
+ try {
201
+ const results = [];
202
+ for (const { scope_type, label } of labels) {
203
+ const result = await upsert_scope_label(adapter, org, scope_type, label);
204
+ if (!result.success) {
205
+ return {
206
+ success: false,
207
+ error: `Failed to save label for ${scope_type}: ${result.error}`,
208
+ };
209
+ }
210
+ if (result.label) {
211
+ results.push(result.label);
212
+ }
213
+ }
214
+ return {
215
+ success: true,
216
+ labels: results,
217
+ };
218
+ }
219
+ catch (error) {
220
+ const logger = create_app_logger();
221
+ const error_message = sanitize_error_for_user(error, {
222
+ logToConsole: true,
223
+ logToLogger: true,
224
+ logger,
225
+ context: {
226
+ filename: "scope_labels_service.ts",
227
+ line_number: 0,
228
+ operation: "batch_upsert_scope_labels",
229
+ org,
230
+ },
231
+ });
232
+ return {
233
+ success: false,
234
+ error: error_message,
235
+ };
236
+ }
237
+ }
238
+ /**
239
+ * Deletes a scope label, reverting to default
240
+ */
241
+ export async function delete_scope_label(adapter, org, scope_type) {
242
+ try {
243
+ const label_service = createCrudService(adapter, "hazo_scope_labels");
244
+ // Find the label
245
+ const existing = await label_service.findBy({ org, scope_type });
246
+ if (!Array.isArray(existing) || existing.length === 0) {
247
+ return {
248
+ success: true, // Already doesn't exist
249
+ };
250
+ }
251
+ const existing_label = existing[0];
252
+ await label_service.deleteById(existing_label.id);
253
+ return {
254
+ success: true,
255
+ label: existing_label,
256
+ };
257
+ }
258
+ catch (error) {
259
+ const logger = create_app_logger();
260
+ const error_message = sanitize_error_for_user(error, {
261
+ logToConsole: true,
262
+ logToLogger: true,
263
+ logger,
264
+ context: {
265
+ filename: "scope_labels_service.ts",
266
+ line_number: 0,
267
+ operation: "delete_scope_label",
268
+ org,
269
+ scope_type,
270
+ },
271
+ });
272
+ return {
273
+ success: false,
274
+ error: error_message,
275
+ };
276
+ }
277
+ }
@@ -0,0 +1,114 @@
1
+ import type { HazoConnectAdapter } from "hazo_connect";
2
+ export type ScopeLevel = "hazo_scopes_l1" | "hazo_scopes_l2" | "hazo_scopes_l3" | "hazo_scopes_l4" | "hazo_scopes_l5" | "hazo_scopes_l6" | "hazo_scopes_l7";
3
+ export type ScopeRecord = {
4
+ id: string;
5
+ seq: string;
6
+ org: string;
7
+ name: string;
8
+ parent_scope_id?: string | null;
9
+ created_at: string;
10
+ changed_at: string;
11
+ };
12
+ export type ScopeServiceResult = {
13
+ success: boolean;
14
+ scope?: ScopeRecord;
15
+ scopes?: ScopeRecord[];
16
+ error?: string;
17
+ };
18
+ export type CreateScopeData = {
19
+ org: string;
20
+ name: string;
21
+ parent_scope_id?: string;
22
+ };
23
+ export type UpdateScopeData = {
24
+ name?: string;
25
+ parent_scope_id?: string | null;
26
+ };
27
+ export declare const SCOPE_LEVELS: ScopeLevel[];
28
+ export declare const SCOPE_LEVEL_NUMBERS: Record<ScopeLevel, number>;
29
+ /**
30
+ * Validates that the provided string is a valid scope level
31
+ */
32
+ export declare function is_valid_scope_level(level: string): level is ScopeLevel;
33
+ /**
34
+ * Gets the parent level for a given scope level
35
+ * Returns undefined for L1 (root level)
36
+ */
37
+ export declare function get_parent_level(level: ScopeLevel): ScopeLevel | undefined;
38
+ /**
39
+ * Gets the child level for a given scope level
40
+ * Returns undefined for L7 (leaf level)
41
+ */
42
+ export declare function get_child_level(level: ScopeLevel): ScopeLevel | undefined;
43
+ /**
44
+ * Gets all scopes for a given level, optionally filtered by organization
45
+ */
46
+ export declare function get_scopes_by_level(adapter: HazoConnectAdapter, level: ScopeLevel, org?: string): Promise<ScopeServiceResult>;
47
+ /**
48
+ * Gets a single scope by ID
49
+ */
50
+ export declare function get_scope_by_id(adapter: HazoConnectAdapter, level: ScopeLevel, scope_id: string): Promise<ScopeServiceResult>;
51
+ /**
52
+ * Gets a single scope by seq (friendly ID)
53
+ */
54
+ export declare function get_scope_by_seq(adapter: HazoConnectAdapter, level: ScopeLevel, seq: string): Promise<ScopeServiceResult>;
55
+ /**
56
+ * Creates a new scope
57
+ * Note: The seq field is auto-generated by the database via hazo_scope_id_generator function
58
+ */
59
+ export declare function create_scope(adapter: HazoConnectAdapter, level: ScopeLevel, data: CreateScopeData): Promise<ScopeServiceResult>;
60
+ /**
61
+ * Updates an existing scope
62
+ */
63
+ export declare function update_scope(adapter: HazoConnectAdapter, level: ScopeLevel, scope_id: string, data: UpdateScopeData): Promise<ScopeServiceResult>;
64
+ /**
65
+ * Deletes a scope (cascades to children via database FK constraints)
66
+ */
67
+ export declare function delete_scope(adapter: HazoConnectAdapter, level: ScopeLevel, scope_id: string): Promise<ScopeServiceResult>;
68
+ /**
69
+ * Gets immediate children of a scope
70
+ */
71
+ export declare function get_scope_children(adapter: HazoConnectAdapter, level: ScopeLevel, scope_id: string): Promise<ScopeServiceResult>;
72
+ /**
73
+ * Gets all ancestors of a scope up to L1 (root)
74
+ * Returns array ordered from immediate parent to root (L1)
75
+ */
76
+ export declare function get_scope_ancestors(adapter: HazoConnectAdapter, level: ScopeLevel, scope_id: string): Promise<ScopeServiceResult>;
77
+ /**
78
+ * Gets all descendants of a scope down to L7 (leaves)
79
+ * Returns flat array of all descendant scopes
80
+ */
81
+ export declare function get_scope_descendants(adapter: HazoConnectAdapter, level: ScopeLevel, scope_id: string): Promise<ScopeServiceResult>;
82
+ /**
83
+ * Gets scope hierarchy tree for a given organization
84
+ * Returns nested structure starting from L1
85
+ */
86
+ export type ScopeTreeNode = ScopeRecord & {
87
+ children?: ScopeTreeNode[];
88
+ level: ScopeLevel;
89
+ };
90
+ /**
91
+ * Organization tree node that groups scopes by organization
92
+ */
93
+ export type OrgScopeTreeNode = {
94
+ id: string;
95
+ name: string;
96
+ org: string;
97
+ isOrgNode: true;
98
+ children: ScopeTreeNode[];
99
+ };
100
+ export declare function get_scope_tree(adapter: HazoConnectAdapter, org: string): Promise<{
101
+ success: boolean;
102
+ tree?: ScopeTreeNode[];
103
+ error?: string;
104
+ }>;
105
+ /**
106
+ * Gets all scope trees across all organizations
107
+ * Returns trees for all L1 scopes (top level)
108
+ */
109
+ export declare function get_all_scope_trees(adapter: HazoConnectAdapter): Promise<{
110
+ success: boolean;
111
+ trees?: ScopeTreeNode[];
112
+ error?: string;
113
+ }>;
114
+ //# sourceMappingURL=scope_service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope_service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/scope_service.ts"],"names":[],"mappings":"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"}