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.
Files changed (94) hide show
  1. package/README.md +207 -5
  2. package/SETUP_CHECKLIST.md +1 -1
  3. package/cli-src/lib/auth/auth_types.ts +22 -0
  4. package/cli-src/lib/auth/hazo_get_auth.server.ts +25 -1
  5. package/cli-src/lib/auth/session_token_validator.edge.ts +1 -0
  6. package/cli-src/lib/config/default_config.ts +36 -0
  7. package/cli-src/lib/navbar_config.server.ts +129 -0
  8. package/cli-src/lib/scope_hierarchy_config.server.ts +3 -14
  9. package/cli-src/lib/services/registration_service.ts +12 -0
  10. package/cli-src/lib/services/scope_labels_service.ts +21 -21
  11. package/cli-src/lib/services/scope_service.ts +15 -11
  12. package/cli-src/lib/services/session_token_service.ts +1 -0
  13. package/cli-src/lib/ui_shell_config.server.ts +15 -0
  14. package/cli-src/lib/user_types_config.server.ts +178 -0
  15. package/dist/app/api/hazo_auth/me/route.d.ts.map +1 -1
  16. package/dist/app/api/hazo_auth/me/route.js +17 -0
  17. package/dist/app/api/hazo_auth/org_management/orgs/route.d.ts +26 -0
  18. package/dist/app/api/hazo_auth/org_management/orgs/route.d.ts.map +1 -0
  19. package/dist/app/api/hazo_auth/org_management/orgs/route.js +315 -0
  20. package/dist/app/api/hazo_auth/user_management/users/route.d.ts +11 -1
  21. package/dist/app/api/hazo_auth/user_management/users/route.d.ts.map +1 -1
  22. package/dist/app/api/hazo_auth/user_management/users/route.js +121 -16
  23. package/dist/components/layouts/my_settings/components/profile_picture_library_tab.d.ts.map +1 -1
  24. package/dist/components/layouts/my_settings/components/profile_picture_library_tab.js +8 -14
  25. package/dist/components/layouts/rbac_test/index.d.ts +1 -3
  26. package/dist/components/layouts/rbac_test/index.d.ts.map +1 -1
  27. package/dist/components/layouts/rbac_test/index.js +2 -2
  28. package/dist/components/layouts/shared/components/auth_navbar.d.ts +26 -0
  29. package/dist/components/layouts/shared/components/auth_navbar.d.ts.map +1 -0
  30. package/dist/components/layouts/shared/components/auth_navbar.js +14 -0
  31. package/dist/components/layouts/shared/components/auth_page_shell.d.ts +3 -1
  32. package/dist/components/layouts/shared/components/auth_page_shell.d.ts.map +1 -1
  33. package/dist/components/layouts/shared/components/auth_page_shell.js +17 -2
  34. package/dist/components/layouts/shared/components/standalone_layout_wrapper.d.ts +6 -1
  35. package/dist/components/layouts/shared/components/standalone_layout_wrapper.d.ts.map +1 -1
  36. package/dist/components/layouts/shared/components/standalone_layout_wrapper.js +7 -2
  37. package/dist/components/layouts/shared/index.d.ts +2 -0
  38. package/dist/components/layouts/shared/index.d.ts.map +1 -1
  39. package/dist/components/layouts/shared/index.js +1 -0
  40. package/dist/components/layouts/user_management/components/scope_hierarchy_tab.d.ts +3 -2
  41. package/dist/components/layouts/user_management/components/scope_hierarchy_tab.d.ts.map +1 -1
  42. package/dist/components/layouts/user_management/components/scope_hierarchy_tab.js +45 -18
  43. package/dist/components/layouts/user_management/components/scope_labels_tab.d.ts +3 -2
  44. package/dist/components/layouts/user_management/components/scope_labels_tab.d.ts.map +1 -1
  45. package/dist/components/layouts/user_management/components/scope_labels_tab.js +48 -20
  46. package/dist/components/layouts/user_management/components/user_scopes_tab.d.ts.map +1 -1
  47. package/dist/components/layouts/user_management/components/user_scopes_tab.js +1 -1
  48. package/dist/components/layouts/user_management/index.d.ts +11 -3
  49. package/dist/components/layouts/user_management/index.d.ts.map +1 -1
  50. package/dist/components/layouts/user_management/index.js +52 -5
  51. package/dist/components/ui/user-type-badge.d.ts +23 -0
  52. package/dist/components/ui/user-type-badge.d.ts.map +1 -0
  53. package/dist/components/ui/user-type-badge.js +42 -0
  54. package/dist/lib/auth/auth_types.d.ts +17 -0
  55. package/dist/lib/auth/auth_types.d.ts.map +1 -1
  56. package/dist/lib/auth/auth_types.js +11 -0
  57. package/dist/lib/auth/hazo_get_auth.server.d.ts.map +1 -1
  58. package/dist/lib/auth/hazo_get_auth.server.js +21 -1
  59. package/dist/lib/config/default_config.d.ts +60 -0
  60. package/dist/lib/config/default_config.d.ts.map +1 -1
  61. package/dist/lib/config/default_config.js +34 -0
  62. package/dist/lib/navbar_config.server.d.ts +36 -0
  63. package/dist/lib/navbar_config.server.d.ts.map +1 -0
  64. package/dist/lib/navbar_config.server.js +45 -0
  65. package/dist/lib/scope_hierarchy_config.server.d.ts +3 -7
  66. package/dist/lib/scope_hierarchy_config.server.d.ts.map +1 -1
  67. package/dist/lib/scope_hierarchy_config.server.js +1 -10
  68. package/dist/lib/services/registration_service.d.ts.map +1 -1
  69. package/dist/lib/services/registration_service.js +8 -0
  70. package/dist/lib/services/scope_labels_service.d.ts +7 -7
  71. package/dist/lib/services/scope_labels_service.d.ts.map +1 -1
  72. package/dist/lib/services/scope_labels_service.js +20 -20
  73. package/dist/lib/services/scope_service.d.ts +8 -5
  74. package/dist/lib/services/scope_service.d.ts.map +1 -1
  75. package/dist/lib/services/scope_service.js +9 -8
  76. package/dist/lib/ui_shell_config.server.d.ts +5 -0
  77. package/dist/lib/ui_shell_config.server.d.ts.map +1 -1
  78. package/dist/lib/ui_shell_config.server.js +5 -0
  79. package/dist/lib/user_types_config.server.d.ts +56 -0
  80. package/dist/lib/user_types_config.server.d.ts.map +1 -0
  81. package/dist/lib/user_types_config.server.js +100 -0
  82. package/dist/server/routes/index.d.ts +1 -0
  83. package/dist/server/routes/index.d.ts.map +1 -1
  84. package/dist/server/routes/index.js +2 -0
  85. package/dist/server/routes/org_management_orgs.d.ts +2 -0
  86. package/dist/server/routes/org_management_orgs.d.ts.map +1 -0
  87. package/dist/server/routes/org_management_orgs.js +2 -0
  88. package/hazo_auth_config.example.ini +9 -0
  89. package/package.json +1 -1
  90. package/cli-src/server/logging/logger_service.ts +0 -56
  91. /package/public/profile_pictures/library/Cars/{050 - citroe/314/210n_c3.jpeg" → 050 - citro/303/253n_c3.jpeg"} +0 -0
  92. /package/public/profile_pictures/library/Cars/{064 - lamborghini_huraca/314/201n.jpeg" → 064 - lamborghini_hurac/303/241n.jpeg"} +0 -0
  93. /package/public/profile_pictures/library/Cars/{099 - citroe/314/210n_2cv_(classic).jpeg" → 099 - citro/303/253n_2cv_(classic).jpeg"} +0 -0
  94. /package/public/profile_pictures/library/Cars/{131 - lamborghini_huraca/314/201n_sto.jpeg" → 131 - lamborghini_hurac/303/241n_sto.jpeg"} +0 -0
@@ -260,7 +260,7 @@ export function UserScopesTab({ className }) {
260
260
  }, variant: "outline", size: "sm", children: [_jsx(Plus, { className: "h-4 w-4 mr-2" }), "Assign First Scope"] })] })) : (_jsxs(Table, { className: "w-full", children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: "Level" }), _jsx(TableHead, { children: "Scope Seq" }), _jsx(TableHead, { children: "Scope ID" }), _jsx(TableHead, { children: "Assigned" }), _jsx(TableHead, { className: "text-right w-[80px]", children: "Actions" })] }) }), _jsx(TableBody, { children: userScopes.map((scope) => (_jsxs(TableRow, { children: [_jsx(TableCell, { className: "font-medium", children: getLevelLabel(scope.scope_type) }), _jsx(TableCell, { className: "font-mono text-sm", children: scope.scope_seq }), _jsxs(TableCell, { className: "font-mono text-xs text-muted-foreground", children: [scope.scope_id.substring(0, 8), "..."] }), _jsx(TableCell, { className: "text-sm text-muted-foreground", children: new Date(scope.created_at).toLocaleDateString() }), _jsx(TableCell, { className: "text-right", children: _jsx(Button, { onClick: () => {
261
261
  setScopeToDelete(scope);
262
262
  setDeleteDialogOpen(true);
263
- }, variant: "outline", size: "sm", className: "text-destructive", children: _jsx(Trash2, { className: "h-4 w-4" }) }) })] }, `${scope.scope_type}-${scope.scope_id}`))) })] })) })] }), _jsx(Dialog, { open: addDialogOpen, onOpenChange: setAddDialogOpen, children: _jsxs(DialogContent, { className: "cls_user_scopes_add_dialog sm:max-w-[500px]", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Add Scope Assignment" }), _jsxs(DialogDescription, { children: ["Select a scope from the tree to assign to", " ", (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.name) || (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.email_address), "."] })] }), _jsxs("div", { className: "flex flex-col gap-4 py-4", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: "Select Scope" }), treeLoading ? (_jsx("div", { className: "flex items-center justify-center p-8 border rounded-lg", children: _jsx(Loader2, { className: "h-6 w-6 animate-spin text-slate-400" }) })) : scopeTree.length === 0 ? (_jsxs("div", { className: "flex flex-col items-center justify-center p-6 border rounded-lg border-dashed", children: [_jsx(FolderTree, { className: "h-8 w-8 text-muted-foreground mb-2" }), _jsx("p", { className: "text-sm text-muted-foreground text-center", children: "No scopes available. Create scopes in the Scope Hierarchy tab first." })] })) : (_jsx("div", { className: "border rounded-lg max-h-[300px] overflow-auto", children: _jsx(TreeView, { data: treeData, expandAll: true, defaultNodeIcon: Building2, defaultLeafIcon: Building2, onSelectChange: handleTreeSelectChange, initialSelectedItemId: selectedTreeItem === null || selectedTreeItem === void 0 ? void 0 : selectedTreeItem.id, className: "w-full" }) }))] }), (selectedTreeItem === null || selectedTreeItem === void 0 ? void 0 : selectedTreeItem.scopeData) && (_jsxs("div", { className: "p-3 border rounded-lg bg-muted/50", children: [_jsxs("p", { className: "text-sm", children: [_jsx("span", { className: "font-medium", children: "Selected:" }), " ", selectedTreeItem.scopeData.name] }), _jsxs("p", { className: "text-xs text-muted-foreground", children: [SCOPE_LEVEL_LABELS[selectedTreeItem.scopeData.level], " -", " ", selectedTreeItem.scopeData.seq, " (", selectedTreeItem.scopeData.org, ")"] })] }))] }), _jsxs(DialogFooter, { children: [_jsx(Button, { onClick: handleAddScope, disabled: actionLoading || !(selectedTreeItem === null || selectedTreeItem === void 0 ? void 0 : selectedTreeItem.scopeData), variant: "default", children: actionLoading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin" }), "Assigning..."] })) : (_jsxs(_Fragment, { children: [_jsx(CircleCheck, { className: "h-4 w-4 mr-2" }), "Assign Scope"] })) }), _jsxs(Button, { onClick: () => setAddDialogOpen(false), variant: "outline", children: [_jsx(CircleX, { className: "h-4 w-4 mr-2" }), "Cancel"] })] })] }) }), _jsx(AlertDialog, { open: deleteDialogOpen, onOpenChange: setDeleteDialogOpen, children: _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Remove Scope Assignment" }), _jsxs(AlertDialogDescription, { children: ["Are you sure you want to remove the scope \"", scopeToDelete === null || scopeToDelete === void 0 ? void 0 : scopeToDelete.scope_seq, "\" from", " ", (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.name) || (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.email_address), "? This will also revoke access to any inherited scopes."] })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogAction, { onClick: handleRemoveScope, disabled: actionLoading, children: actionLoading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin" }), "Removing..."] })) : ("Remove") }), _jsx(AlertDialogCancel, { onClick: () => {
263
+ }, variant: "outline", size: "sm", className: "text-destructive", children: _jsx(Trash2, { className: "h-4 w-4" }) }) })] }, `${scope.scope_type}-${scope.scope_id}`))) })] })) })] }), _jsx(Dialog, { open: addDialogOpen, onOpenChange: setAddDialogOpen, children: _jsxs(DialogContent, { className: "cls_user_scopes_add_dialog sm:max-w-[500px]", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Add Scope Assignment" }), _jsxs(DialogDescription, { children: ["Select a scope from the tree to assign to", " ", (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.name) || (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.email_address), "."] })] }), _jsxs("div", { className: "flex flex-col gap-4 py-4", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: "Select Scope" }), treeLoading ? (_jsx("div", { className: "flex items-center justify-center p-8 border rounded-lg", children: _jsx(Loader2, { className: "h-6 w-6 animate-spin text-slate-400" }) })) : scopeTree.length === 0 ? (_jsxs("div", { className: "flex flex-col items-center justify-center p-6 border rounded-lg border-dashed", children: [_jsx(FolderTree, { className: "h-8 w-8 text-muted-foreground mb-2" }), _jsx("p", { className: "text-sm text-muted-foreground text-center", children: "No scopes available. Create scopes in the Scope Hierarchy tab first." })] })) : (_jsx("div", { className: "border rounded-lg max-h-[300px] overflow-auto", children: _jsx(TreeView, { data: treeData, expandAll: true, defaultNodeIcon: Building2, defaultLeafIcon: Building2, onSelectChange: handleTreeSelectChange, initialSelectedItemId: selectedTreeItem === null || selectedTreeItem === void 0 ? void 0 : selectedTreeItem.id, className: "w-full" }) }))] }), (selectedTreeItem === null || selectedTreeItem === void 0 ? void 0 : selectedTreeItem.scopeData) && (_jsxs("div", { className: "p-3 border rounded-lg bg-muted/50", children: [_jsxs("p", { className: "text-sm", children: [_jsx("span", { className: "font-medium", children: "Selected:" }), " ", selectedTreeItem.scopeData.name] }), _jsxs("p", { className: "text-xs text-muted-foreground", children: [SCOPE_LEVEL_LABELS[selectedTreeItem.scopeData.level], " -", " ", selectedTreeItem.scopeData.seq] })] }))] }), _jsxs(DialogFooter, { children: [_jsx(Button, { onClick: handleAddScope, disabled: actionLoading || !(selectedTreeItem === null || selectedTreeItem === void 0 ? void 0 : selectedTreeItem.scopeData), variant: "default", children: actionLoading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin" }), "Assigning..."] })) : (_jsxs(_Fragment, { children: [_jsx(CircleCheck, { className: "h-4 w-4 mr-2" }), "Assign Scope"] })) }), _jsxs(Button, { onClick: () => setAddDialogOpen(false), variant: "outline", children: [_jsx(CircleX, { className: "h-4 w-4 mr-2" }), "Cancel"] })] })] }) }), _jsx(AlertDialog, { open: deleteDialogOpen, onOpenChange: setDeleteDialogOpen, children: _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Remove Scope Assignment" }), _jsxs(AlertDialogDescription, { children: ["Are you sure you want to remove the scope \"", scopeToDelete === null || scopeToDelete === void 0 ? void 0 : scopeToDelete.scope_seq, "\" from", " ", (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.name) || (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.email_address), "? This will also revoke access to any inherited scopes."] })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogAction, { onClick: handleRemoveScope, disabled: actionLoading, children: actionLoading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin" }), "Removing..."] })) : ("Remove") }), _jsx(AlertDialogCancel, { onClick: () => {
264
264
  setDeleteDialogOpen(false);
265
265
  setScopeToDelete(null);
266
266
  }, children: "Cancel" })] })] }) })] }));
@@ -1,11 +1,19 @@
1
+ /** User type definition for the dropdown */
2
+ export type UserTypeOption = {
3
+ key: string;
4
+ label: string;
5
+ badge_color: string;
6
+ };
1
7
  export type UserManagementLayoutProps = {
2
8
  className?: string;
3
9
  /** Whether HRBAC is enabled (passed from server) */
4
10
  hrbacEnabled?: boolean;
5
11
  /** Whether multi-tenancy is enabled (passed from server) */
6
12
  multiTenancyEnabled?: boolean;
7
- /** Default organization for HRBAC scopes */
8
- defaultOrg?: string;
13
+ /** Whether user types feature is enabled (passed from server) */
14
+ userTypesEnabled?: boolean;
15
+ /** Available user types for dropdown (passed from server) */
16
+ availableUserTypes?: UserTypeOption[];
9
17
  };
10
18
  /**
11
19
  * User Management layout component with tabs for managing users, roles, permissions, and HRBAC scopes
@@ -18,5 +26,5 @@ export type UserManagementLayoutProps = {
18
26
  * @param props - Component props
19
27
  * @returns User Management layout component
20
28
  */
21
- export declare function UserManagementLayout({ className, hrbacEnabled, multiTenancyEnabled, defaultOrg }: UserManagementLayoutProps): import("react/jsx-runtime").JSX.Element;
29
+ export declare function UserManagementLayout({ className, hrbacEnabled, multiTenancyEnabled, userTypesEnabled, availableUserTypes }: UserManagementLayoutProps): import("react/jsx-runtime").JSX.Element;
22
30
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/layouts/user_management/index.tsx"],"names":[],"mappings":"AAiDA,MAAM,MAAM,yBAAyB,GAAG;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,4DAA4D;IAC5D,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,4CAA4C;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAsBF;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,SAAS,EAAE,YAAoB,EAAE,mBAA2B,EAAE,UAAe,EAAE,EAAE,yBAAyB,2CAkwChJ"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/layouts/user_management/index.tsx"],"names":[],"mappings":"AA0DA,4CAA4C;AAC5C,MAAM,MAAM,cAAc,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,4DAA4D;IAC5D,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,iEAAiE;IACjE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,6DAA6D;IAC7D,kBAAkB,CAAC,EAAE,cAAc,EAAE,CAAC;CACvC,CAAC;AAuBF;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,SAAS,EAAE,YAAoB,EAAE,mBAA2B,EAAE,gBAAwB,EAAE,kBAAuB,EAAE,EAAE,yBAAyB,2CA81ClL"}
@@ -13,6 +13,8 @@ import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent,
13
13
  import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "../../ui/dialog";
14
14
  import { Input } from "../../ui/input";
15
15
  import { Label } from "../../ui/label";
16
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "../../ui/select";
17
+ import { UserTypeBadge } from "../../ui/user-type-badge";
16
18
  import { RolesMatrix } from "./components/roles_matrix";
17
19
  import { ScopeHierarchyTab } from "./components/scope_hierarchy_tab";
18
20
  import { ScopeLabelsTab } from "./components/scope_labels_tab";
@@ -34,7 +36,7 @@ import { useHazoAuthConfig } from "../../../contexts/hazo_auth_provider";
34
36
  * @param props - Component props
35
37
  * @returns User Management layout component
36
38
  */
37
- export function UserManagementLayout({ className, hrbacEnabled = false, multiTenancyEnabled = false, defaultOrg = "" }) {
39
+ export function UserManagementLayout({ className, hrbacEnabled = false, multiTenancyEnabled = false, userTypesEnabled = false, availableUserTypes = [] }) {
38
40
  const { apiBasePath } = useHazoAuthConfig();
39
41
  // Permission checks
40
42
  const authResult = use_hazo_auth();
@@ -70,6 +72,7 @@ export function UserManagementLayout({ className, hrbacEnabled = false, multiTen
70
72
  const [assignRolesDialogOpen, setAssignRolesDialogOpen] = useState(false);
71
73
  const [selectedUser, setSelectedUser] = useState(null);
72
74
  const [usersActionLoading, setUsersActionLoading] = useState(false);
75
+ const [userTypeUpdateLoading, setUserTypeUpdateLoading] = useState(false);
73
76
  // Tab 3: Permissions state
74
77
  const [permissions, setPermissions] = useState([]);
75
78
  const [permissionsLoading, setPermissionsLoading] = useState(true);
@@ -219,6 +222,47 @@ export function UserManagementLayout({ className, hrbacEnabled = false, multiTen
219
222
  setUsersActionLoading(false);
220
223
  }
221
224
  };
225
+ // Get user type info by key
226
+ const getUserTypeInfo = (typeKey) => {
227
+ if (!typeKey || !userTypesEnabled)
228
+ return null;
229
+ return availableUserTypes.find((t) => t.key === typeKey) || null;
230
+ };
231
+ // Handle user type change
232
+ const handleUserTypeChange = async (newType) => {
233
+ if (!selectedUser)
234
+ return;
235
+ setUserTypeUpdateLoading(true);
236
+ try {
237
+ const response = await fetch(`${apiBasePath}/user_management/users`, {
238
+ method: "PATCH",
239
+ headers: {
240
+ "Content-Type": "application/json",
241
+ },
242
+ body: JSON.stringify({
243
+ user_id: selectedUser.id,
244
+ user_type: newType || null,
245
+ }),
246
+ });
247
+ const data = await response.json();
248
+ if (data.success) {
249
+ toast.success("User type updated successfully");
250
+ // Update local state
251
+ setSelectedUser(Object.assign(Object.assign({}, selectedUser), { user_type: newType || null }));
252
+ // Reload users list
253
+ await loadUsers();
254
+ }
255
+ else {
256
+ toast.error(data.error || "Failed to update user type");
257
+ }
258
+ }
259
+ catch (error) {
260
+ toast.error("Failed to update user type");
261
+ }
262
+ finally {
263
+ setUserTypeUpdateLoading(false);
264
+ }
265
+ };
222
266
  // Handle migrate permissions
223
267
  const handleMigratePermissions = async () => {
224
268
  var _a, _b;
@@ -442,14 +486,17 @@ export function UserManagementLayout({ className, hrbacEnabled = false, multiTen
442
486
  showPermissionsTab ? "permissions" :
443
487
  showScopeLabelsTab ? "scope_labels" :
444
488
  showScopeHierarchyTab ? "scope_hierarchy" :
445
- showUserScopesTab ? "user_scopes" : "users", className: "cls_user_management_tabs w-full", children: [_jsxs(TabsList, { className: "cls_user_management_tabs_list flex w-full flex-wrap", children: [showUsersTab && (_jsx(TabsTrigger, { value: "users", className: "cls_user_management_tabs_trigger flex-1", children: "Manage Users" })), showRolesTab && (_jsx(TabsTrigger, { value: "roles", className: "cls_user_management_tabs_trigger flex-1", children: "Roles" })), showPermissionsTab && (_jsx(TabsTrigger, { value: "permissions", className: "cls_user_management_tabs_trigger flex-1", children: "Permissions" })), showScopeLabelsTab && (_jsx(TabsTrigger, { value: "scope_labels", className: "cls_user_management_tabs_trigger flex-1", children: "Scope Labels" })), showScopeHierarchyTab && (_jsx(TabsTrigger, { value: "scope_hierarchy", className: "cls_user_management_tabs_trigger flex-1", children: "Scope Hierarchy" })), showUserScopesTab && (_jsx(TabsTrigger, { value: "user_scopes", className: "cls_user_management_tabs_trigger flex-1", children: "User Scopes" })), showOrgsTab && (_jsx(TabsTrigger, { value: "organizations", className: "cls_user_management_tabs_trigger flex-1", children: "Organizations" }))] }), showUsersTab && (_jsx(TabsContent, { value: "users", className: "cls_user_management_tab_users w-full", children: usersLoading ? (_jsx("div", { className: "cls_user_management_users_loading flex items-center justify-center p-8", children: _jsx(Loader2, { className: "h-6 w-6 animate-spin text-slate-400" }) })) : (_jsx("div", { className: "cls_user_management_users_table_container border rounded-lg overflow-auto w-full", children: _jsxs(Table, { className: "cls_user_management_users_table w-full", children: [_jsx(TableHeader, { className: "cls_user_management_users_table_header", children: _jsxs(TableRow, { className: "cls_user_management_users_table_header_row", children: [_jsx(TableHead, { className: "cls_user_management_users_table_header_profile_pic w-16", children: "Photo" }), _jsx(TableHead, { className: "cls_user_management_users_table_header_id", children: "ID" }), _jsx(TableHead, { className: "cls_user_management_users_table_header_name", children: "Name" }), _jsx(TableHead, { className: "cls_user_management_users_table_header_email", children: "Email" }), _jsx(TableHead, { className: "cls_user_management_users_table_header_email_verified", children: "Email Verified" }), _jsx(TableHead, { className: "cls_user_management_users_table_header_is_active", children: "Active" }), _jsx(TableHead, { className: "cls_user_management_users_table_header_last_logon", children: "Last Logon" }), _jsx(TableHead, { className: "cls_user_management_users_table_header_created_at", children: "Created At" }), _jsx(TableHead, { className: "cls_user_management_users_table_header_actions text-right", children: "Actions" })] }) }), _jsx(TableBody, { className: "cls_user_management_users_table_body", children: users.length === 0 ? (_jsx(TableRow, { className: "cls_user_management_users_table_row_empty", children: _jsx(TableCell, { colSpan: 9, className: "text-center text-muted-foreground py-8", children: "No users found." }) })) : (users.map((user) => (_jsxs(TableRow, { className: "cls_user_management_users_table_row cursor-pointer hover:bg-muted/50", onClick: () => {
489
+ showUserScopesTab ? "user_scopes" : "users", className: "cls_user_management_tabs w-full", children: [_jsxs(TabsList, { className: "cls_user_management_tabs_list flex w-full flex-wrap", children: [showUsersTab && (_jsx(TabsTrigger, { value: "users", className: "cls_user_management_tabs_trigger flex-1", children: "Manage Users" })), showRolesTab && (_jsx(TabsTrigger, { value: "roles", className: "cls_user_management_tabs_trigger flex-1", children: "Roles" })), showPermissionsTab && (_jsx(TabsTrigger, { value: "permissions", className: "cls_user_management_tabs_trigger flex-1", children: "Permissions" })), showScopeLabelsTab && (_jsx(TabsTrigger, { value: "scope_labels", className: "cls_user_management_tabs_trigger flex-1", children: "Scope Labels" })), showScopeHierarchyTab && (_jsx(TabsTrigger, { value: "scope_hierarchy", className: "cls_user_management_tabs_trigger flex-1", children: "Scope Hierarchy" })), showUserScopesTab && (_jsx(TabsTrigger, { value: "user_scopes", className: "cls_user_management_tabs_trigger flex-1", children: "User Scopes" })), showOrgsTab && (_jsx(TabsTrigger, { value: "organizations", className: "cls_user_management_tabs_trigger flex-1", children: "Organizations" }))] }), showUsersTab && (_jsx(TabsContent, { value: "users", className: "cls_user_management_tab_users w-full", children: usersLoading ? (_jsx("div", { className: "cls_user_management_users_loading flex items-center justify-center p-8", children: _jsx(Loader2, { className: "h-6 w-6 animate-spin text-slate-400" }) })) : (_jsx("div", { className: "cls_user_management_users_table_container border rounded-lg overflow-auto w-full", children: _jsxs(Table, { className: "cls_user_management_users_table w-full", children: [_jsx(TableHeader, { className: "cls_user_management_users_table_header", children: _jsxs(TableRow, { className: "cls_user_management_users_table_header_row", children: [_jsx(TableHead, { className: "cls_user_management_users_table_header_profile_pic w-16", children: "Photo" }), _jsx(TableHead, { className: "cls_user_management_users_table_header_id", children: "ID" }), _jsx(TableHead, { className: "cls_user_management_users_table_header_name", children: "Name" }), _jsx(TableHead, { className: "cls_user_management_users_table_header_email", children: "Email" }), _jsx(TableHead, { className: "cls_user_management_users_table_header_email_verified", children: "Email Verified" }), _jsx(TableHead, { className: "cls_user_management_users_table_header_is_active", children: "Active" }), _jsx(TableHead, { className: "cls_user_management_users_table_header_last_logon", children: "Last Logon" }), _jsx(TableHead, { className: "cls_user_management_users_table_header_created_at", children: "Created At" }), userTypesEnabled && (_jsx(TableHead, { className: "cls_user_management_users_table_header_user_type", children: "User Type" })), _jsx(TableHead, { className: "cls_user_management_users_table_header_actions text-right", children: "Actions" })] }) }), _jsx(TableBody, { className: "cls_user_management_users_table_body", children: users.length === 0 ? (_jsx(TableRow, { className: "cls_user_management_users_table_row_empty", children: _jsx(TableCell, { colSpan: userTypesEnabled ? 10 : 9, className: "text-center text-muted-foreground py-8", children: "No users found." }) })) : (users.map((user) => (_jsxs(TableRow, { className: "cls_user_management_users_table_row cursor-pointer hover:bg-muted/50", onClick: () => {
446
490
  setSelectedUser(user);
447
491
  setUserDetailDialogOpen(true);
448
492
  }, children: [_jsx(TableCell, { className: "cls_user_management_users_table_cell_profile_pic", children: _jsxs(Avatar, { className: "cls_user_management_users_table_avatar h-8 w-8", children: [_jsx(AvatarImage, { src: user.profile_picture_url || undefined, alt: user.name ? `Profile picture of ${user.name}` : "Profile picture", className: "cls_user_management_users_table_avatar_image" }), _jsx(AvatarFallback, { className: "cls_user_management_users_table_avatar_fallback bg-slate-200 text-slate-600 text-xs", children: getUserInitials(user) })] }) }), _jsxs(TableCell, { className: "cls_user_management_users_table_cell_id font-mono text-xs", children: [user.id.substring(0, 8), "..."] }), _jsx(TableCell, { className: "cls_user_management_users_table_cell_name", children: user.name || "-" }), _jsx(TableCell, { className: "cls_user_management_users_table_cell_email", children: user.email_address }), _jsx(TableCell, { className: "cls_user_management_users_table_cell_email_verified", children: user.email_verified ? (_jsx("span", { className: "text-green-600", children: "Yes" })) : (_jsx("span", { className: "text-red-600", children: "No" })) }), _jsx(TableCell, { className: "cls_user_management_users_table_cell_is_active", children: user.is_active ? (_jsx("span", { className: "text-green-600", children: "Active" })) : (_jsx("span", { className: "text-red-600", children: "Inactive" })) }), _jsx(TableCell, { className: "cls_user_management_users_table_cell_last_logon", children: user.last_logon
449
493
  ? new Date(user.last_logon).toLocaleDateString()
450
494
  : "-" }), _jsx(TableCell, { className: "cls_user_management_users_table_cell_created_at", children: user.created_at
451
495
  ? new Date(user.created_at).toLocaleDateString()
452
- : "-" }), _jsx(TableCell, { className: "cls_user_management_users_table_cell_actions text-right", children: _jsx(TooltipProvider, { children: _jsxs("div", { className: "cls_user_management_users_table_actions flex items-center justify-end gap-2", onClick: (e) => e.stopPropagation(), children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { onClick: () => {
496
+ : "-" }), userTypesEnabled && (_jsx(TableCell, { className: "cls_user_management_users_table_cell_user_type", children: (() => {
497
+ const typeInfo = getUserTypeInfo(user.user_type);
498
+ return typeInfo ? (_jsx(UserTypeBadge, { label: typeInfo.label, color: typeInfo.badge_color })) : (_jsx("span", { className: "text-muted-foreground", children: "-" }));
499
+ })() })), _jsx(TableCell, { className: "cls_user_management_users_table_cell_actions text-right", children: _jsx(TooltipProvider, { children: _jsxs("div", { className: "cls_user_management_users_table_actions flex items-center justify-end gap-2", onClick: (e) => e.stopPropagation(), children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { onClick: () => {
453
500
  setSelectedUser(user);
454
501
  setAssignRolesDialogOpen(true);
455
502
  }, variant: "outline", size: "sm", className: "cls_user_management_users_table_action_assign_roles", children: _jsx(UserPlus, { className: "h-4 w-4" }) }) }), _jsx(TooltipContent, { children: _jsx("p", { children: "Assign Roles" }) })] }), user.is_active && (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { onClick: () => {
@@ -467,7 +514,7 @@ export function UserManagementLayout({ className, hrbacEnabled = false, multiTen
467
514
  setEditingPermission(permission);
468
515
  setEditDescription(permission.description);
469
516
  setEditPermissionDialogOpen(true);
470
- }, variant: "outline", size: "sm", className: "cls_user_management_permissions_table_action_edit", children: [_jsx(Edit, { className: "h-4 w-4 mr-1" }), "Edit"] }), _jsxs(Button, { onClick: () => handleDeletePermission(permission), disabled: permissionsActionLoading, variant: "outline", size: "sm", className: "cls_user_management_permissions_table_action_delete text-destructive", children: [_jsx(Trash2, { className: "h-4 w-4 mr-1" }), "Delete"] })] })) }) })] }, `${permission.source}-${permission.id}-${permission.permission_name}`)))) })] }) }))] }) })), showScopeLabelsTab && (_jsx(TabsContent, { value: "scope_labels", className: "cls_user_management_tab_scope_labels w-full", children: _jsx(ScopeLabelsTab, { defaultOrg: defaultOrg }) })), showScopeHierarchyTab && (_jsx(TabsContent, { value: "scope_hierarchy", className: "cls_user_management_tab_scope_hierarchy w-full", children: _jsx(ScopeHierarchyTab, { defaultOrg: defaultOrg }) })), showUserScopesTab && (_jsx(TabsContent, { value: "user_scopes", className: "cls_user_management_tab_user_scopes w-full", children: _jsx(UserScopesTab, {}) })), showOrgsTab && (_jsx(TabsContent, { value: "organizations", className: "cls_user_management_tab_organizations w-full", children: _jsx(OrgHierarchyTab, { isGlobalAdmin: hasOrgGlobalAdminPermission }) }))] })), _jsx(AlertDialog, { open: deactivateDialogOpen, onOpenChange: setDeactivateDialogOpen, children: _jsxs(AlertDialogContent, { className: "cls_user_management_deactivate_dialog", children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Deactivate User" }), _jsxs(AlertDialogDescription, { children: ["Are you sure you want to deactivate ", (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.name) || (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.email_address), "? They will not be able to log in until reactivated."] })] }), _jsxs(AlertDialogFooter, { className: "cls_user_management_deactivate_dialog_footer", children: [_jsx(AlertDialogAction, { onClick: handleDeactivateUser, disabled: usersActionLoading, className: "cls_user_management_deactivate_dialog_confirm", children: usersActionLoading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin" }), "Deactivating..."] })) : ("Deactivate") }), _jsx(AlertDialogCancel, { onClick: () => {
517
+ }, variant: "outline", size: "sm", className: "cls_user_management_permissions_table_action_edit", children: [_jsx(Edit, { className: "h-4 w-4 mr-1" }), "Edit"] }), _jsxs(Button, { onClick: () => handleDeletePermission(permission), disabled: permissionsActionLoading, variant: "outline", size: "sm", className: "cls_user_management_permissions_table_action_delete text-destructive", children: [_jsx(Trash2, { className: "h-4 w-4 mr-1" }), "Delete"] })] })) }) })] }, `${permission.source}-${permission.id}-${permission.permission_name}`)))) })] }) }))] }) })), showScopeLabelsTab && (_jsx(TabsContent, { value: "scope_labels", className: "cls_user_management_tab_scope_labels w-full", children: _jsx(ScopeLabelsTab, {}) })), showScopeHierarchyTab && (_jsx(TabsContent, { value: "scope_hierarchy", className: "cls_user_management_tab_scope_hierarchy w-full", children: _jsx(ScopeHierarchyTab, {}) })), showUserScopesTab && (_jsx(TabsContent, { value: "user_scopes", className: "cls_user_management_tab_user_scopes w-full", children: _jsx(UserScopesTab, {}) })), showOrgsTab && (_jsx(TabsContent, { value: "organizations", className: "cls_user_management_tab_organizations w-full", children: _jsx(OrgHierarchyTab, { isGlobalAdmin: hasOrgGlobalAdminPermission }) }))] })), _jsx(AlertDialog, { open: deactivateDialogOpen, onOpenChange: setDeactivateDialogOpen, children: _jsxs(AlertDialogContent, { className: "cls_user_management_deactivate_dialog", children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Deactivate User" }), _jsxs(AlertDialogDescription, { children: ["Are you sure you want to deactivate ", (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.name) || (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.email_address), "? They will not be able to log in until reactivated."] })] }), _jsxs(AlertDialogFooter, { className: "cls_user_management_deactivate_dialog_footer", children: [_jsx(AlertDialogAction, { onClick: handleDeactivateUser, disabled: usersActionLoading, className: "cls_user_management_deactivate_dialog_confirm", children: usersActionLoading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin" }), "Deactivating..."] })) : ("Deactivate") }), _jsx(AlertDialogCancel, { onClick: () => {
471
518
  setDeactivateDialogOpen(false);
472
519
  setSelectedUser(null);
473
520
  }, className: "cls_user_management_deactivate_dialog_cancel", children: "Cancel" })] })] }) }), _jsx(AlertDialog, { open: resetPasswordDialogOpen, onOpenChange: setResetPasswordDialogOpen, children: _jsxs(AlertDialogContent, { className: "cls_user_management_reset_password_dialog", children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Reset Password" }), _jsxs(AlertDialogDescription, { children: ["Send a password reset email to ", selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.email_address, "? They will receive a link to reset their password."] })] }), _jsxs(AlertDialogFooter, { className: "cls_user_management_reset_password_dialog_footer", children: [_jsx(AlertDialogAction, { onClick: handleResetPassword, disabled: usersActionLoading, className: "cls_user_management_reset_password_dialog_confirm", children: usersActionLoading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin" }), "Sending..."] })) : ("Send Reset Email") }), _jsx(AlertDialogCancel, { onClick: () => {
@@ -505,7 +552,7 @@ export function UserManagementLayout({ className, hrbacEnabled = false, multiTen
505
552
  minute: "2-digit",
506
553
  second: "2-digit",
507
554
  timeZoneName: "short",
508
- }) })) : (_jsx("span", { className: "text-muted-foreground", children: "-" })) })] })] })) }), _jsx(DialogFooter, { className: "cls_user_management_user_detail_dialog_footer", children: _jsx(Button, { onClick: () => setUserDetailDialogOpen(false), variant: "outline", className: "cls_user_management_user_detail_dialog_close", children: "Close" }) })] }) }), _jsx(Dialog, { open: assignRolesDialogOpen, onOpenChange: setAssignRolesDialogOpen, children: _jsxs(DialogContent, { className: "cls_user_management_assign_roles_dialog max-w-4xl max-h-[80vh] overflow-y-auto", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Assign Roles to User" }), _jsxs(DialogDescription, { children: ["Select roles to assign to ", (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.name) || (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.email_address), ". Check the roles you want to assign, then click Save."] })] }), _jsx("div", { className: "cls_user_management_assign_roles_dialog_content py-4", children: _jsx(RolesMatrix, { add_button_enabled: false, role_name_selection_enabled: true, permissions_read_only: true, show_save_cancel: true, user_id: selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.id, onSave: (data) => {
555
+ }) })) : (_jsx("span", { className: "text-muted-foreground", children: "-" })) })] }), userTypesEnabled && (_jsxs("div", { className: "cls_user_management_user_detail_field_user_type flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "User Type" }), _jsxs("div", { className: "cls_user_management_user_detail_user_type_value flex items-center gap-2", children: [_jsxs(Select, { value: selectedUser.user_type || "", onValueChange: (value) => handleUserTypeChange(value), disabled: userTypeUpdateLoading, children: [_jsx(SelectTrigger, { className: "w-48", children: _jsx(SelectValue, { placeholder: "Select user type" }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "", children: "None" }), availableUserTypes.map((type) => (_jsx(SelectItem, { value: type.key, children: type.label }, type.key)))] })] }), userTypeUpdateLoading && (_jsx(Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" }))] })] }))] })) }), _jsx(DialogFooter, { className: "cls_user_management_user_detail_dialog_footer", children: _jsx(Button, { onClick: () => setUserDetailDialogOpen(false), variant: "outline", className: "cls_user_management_user_detail_dialog_close", children: "Close" }) })] }) }), _jsx(Dialog, { open: assignRolesDialogOpen, onOpenChange: setAssignRolesDialogOpen, children: _jsxs(DialogContent, { className: "cls_user_management_assign_roles_dialog max-w-4xl max-h-[80vh] overflow-y-auto", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Assign Roles to User" }), _jsxs(DialogDescription, { children: ["Select roles to assign to ", (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.name) || (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.email_address), ". Check the roles you want to assign, then click Save."] })] }), _jsx("div", { className: "cls_user_management_assign_roles_dialog_content py-4", children: _jsx(RolesMatrix, { add_button_enabled: false, role_name_selection_enabled: true, permissions_read_only: true, show_save_cancel: true, user_id: selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.id, onSave: (data) => {
509
556
  // Data is already saved by RolesMatrix component
510
557
  console.log("User roles saved:", data);
511
558
  // Refresh users list to show updated roles
@@ -0,0 +1,23 @@
1
+ export type UserTypeBadgeProps = {
2
+ /** Display label for the badge */
3
+ label: string;
4
+ /** Color - preset name (blue, green, red, etc.) or hex value (#4CAF50) */
5
+ color: string;
6
+ /** Additional CSS classes */
7
+ className?: string;
8
+ };
9
+ /**
10
+ * UserTypeBadge - Displays a styled badge for user types
11
+ *
12
+ * Supports preset colors (blue, green, red, yellow, purple, gray, orange, pink)
13
+ * and custom hex colors (e.g., #4CAF50).
14
+ *
15
+ * @example
16
+ * // Using preset color
17
+ * <UserTypeBadge label="Administrator" color="red" />
18
+ *
19
+ * // Using custom hex color
20
+ * <UserTypeBadge label="VIP" color="#FFD700" />
21
+ */
22
+ export declare function UserTypeBadge({ label, color, className }: UserTypeBadgeProps): import("react/jsx-runtime").JSX.Element;
23
+ //# sourceMappingURL=user-type-badge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-type-badge.d.ts","sourceRoot":"","sources":["../../../src/components/ui/user-type-badge.tsx"],"names":[],"mappings":"AAiBA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAoBF;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,kBAAkB,2CAmC5E"}
@@ -0,0 +1,42 @@
1
+ // file_description: Badge component for displaying user types with configurable colors
2
+ "use client";
3
+ import { jsx as _jsx } from "react/jsx-runtime";
4
+ import { cn } from "../../lib/utils";
5
+ // section: constants
6
+ const PRESET_COLOR_CLASSES = {
7
+ blue: "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300",
8
+ green: "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300",
9
+ red: "bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-300",
10
+ yellow: "bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-300",
11
+ purple: "bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-300",
12
+ gray: "bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-300",
13
+ orange: "bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-300",
14
+ pink: "bg-pink-100 text-pink-700 dark:bg-pink-900/30 dark:text-pink-300",
15
+ };
16
+ // section: component
17
+ /**
18
+ * UserTypeBadge - Displays a styled badge for user types
19
+ *
20
+ * Supports preset colors (blue, green, red, yellow, purple, gray, orange, pink)
21
+ * and custom hex colors (e.g., #4CAF50).
22
+ *
23
+ * @example
24
+ * // Using preset color
25
+ * <UserTypeBadge label="Administrator" color="red" />
26
+ *
27
+ * // Using custom hex color
28
+ * <UserTypeBadge label="VIP" color="#FFD700" />
29
+ */
30
+ export function UserTypeBadge({ label, color, className }) {
31
+ const isPreset = color in PRESET_COLOR_CLASSES;
32
+ if (isPreset) {
33
+ return (_jsx("span", { className: cn("inline-flex items-center px-2 py-0.5 rounded text-xs font-medium", PRESET_COLOR_CLASSES[color], className), children: label }));
34
+ }
35
+ // Custom hex color - use lighter bg with the color as text
36
+ // Calculate a semi-transparent background from the hex color
37
+ const style = {
38
+ backgroundColor: `${color}20`, // 20 = ~12% opacity in hex
39
+ color: color,
40
+ };
41
+ return (_jsx("span", { className: cn("inline-flex items-center px-2 py-0.5 rounded text-xs font-medium", className), style: style, children: label }));
42
+ }
@@ -26,6 +26,7 @@ export type ScopeAccessInfo = {
26
26
  * Result type for hazo_get_auth function
27
27
  * Returns authenticated state with user data and permissions, or unauthenticated state
28
28
  * Optionally includes scope access information when HRBAC is used
29
+ * Optionally includes org_ok when require_org option is used
29
30
  */
30
31
  export type HazoAuthResult = {
31
32
  authenticated: true;
@@ -35,12 +36,14 @@ export type HazoAuthResult = {
35
36
  missing_permissions?: string[];
36
37
  scope_ok?: boolean;
37
38
  scope_access_via?: ScopeAccessInfo;
39
+ org_ok?: boolean;
38
40
  } | {
39
41
  authenticated: false;
40
42
  user: null;
41
43
  permissions: [];
42
44
  permission_ok: false;
43
45
  scope_ok?: false;
46
+ org_ok?: false;
44
47
  };
45
48
  /**
46
49
  * Options for hazo_get_auth function
@@ -71,6 +74,12 @@ export type HazoAuthOptions = {
71
74
  * Used if scope_id is not provided
72
75
  */
73
76
  scope_seq?: string;
77
+ /**
78
+ * If true, throws OrgRequiredError when user has no org_id assigned
79
+ * Only checked when multi-tenancy is enabled
80
+ * If false or not set (default), org_id is optional and org fields may be null
81
+ */
82
+ require_org?: boolean;
74
83
  };
75
84
  /**
76
85
  * Custom error class for permission denials
@@ -101,4 +110,12 @@ export declare class ScopeAccessError extends Error {
101
110
  scope_seq: string;
102
111
  }>);
103
112
  }
113
+ /**
114
+ * Custom error class for missing organization assignment
115
+ * Thrown when require_org: true is set but user has no org_id assigned
116
+ */
117
+ export declare class OrgRequiredError extends Error {
118
+ user_id: string;
119
+ constructor(user_id: string);
120
+ }
104
121
  //# sourceMappingURL=auth_types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth_types.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/auth_types.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IAEnC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,cAAc,GACtB;IACE,aAAa,EAAE,IAAI,CAAC;IACpB,IAAI,EAAE,YAAY,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,eAAe,CAAC;CACpC,GACD;IACE,aAAa,EAAE,KAAK,CAAC;IACrB,IAAI,EAAE,IAAI,CAAC;IACX,WAAW,EAAE,EAAE,CAAC;IAChB,aAAa,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,EAAE,KAAK,CAAC;CAClB,CAAC;AAEN;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B;;;OAGG;IACH,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,KAAK;IAE/B,mBAAmB,EAAE,MAAM,EAAE;IAC7B,gBAAgB,EAAE,MAAM,EAAE;IAC1B,oBAAoB,EAAE,MAAM,EAAE;IAC9B,qBAAqB,CAAC,EAAE,MAAM;gBAH9B,mBAAmB,EAAE,MAAM,EAAE,EAC7B,gBAAgB,EAAE,MAAM,EAAE,EAC1B,oBAAoB,EAAE,MAAM,EAAE,EAC9B,qBAAqB,CAAC,EAAE,MAAM,YAAA;CAKxC;AAED;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IAEhC,UAAU,EAAE,MAAM;IAClB,gBAAgB,EAAE,MAAM;IACxB,WAAW,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;gBAF/E,UAAU,EAAE,MAAM,EAClB,gBAAgB,EAAE,MAAM,EACxB,WAAW,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CAKzF"}
1
+ {"version":3,"file":"auth_types.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/auth_types.ts"],"names":[],"mappings":"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"}
@@ -27,3 +27,14 @@ export class ScopeAccessError extends Error {
27
27
  this.name = "ScopeAccessError";
28
28
  }
29
29
  }
30
+ /**
31
+ * Custom error class for missing organization assignment
32
+ * Thrown when require_org: true is set but user has no org_id assigned
33
+ */
34
+ export class OrgRequiredError extends Error {
35
+ constructor(user_id) {
36
+ super(`User ${user_id} is not assigned to an organization`);
37
+ this.user_id = user_id;
38
+ this.name = "OrgRequiredError";
39
+ }
40
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"hazo_get_auth.server.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/hazo_get_auth.server.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAK1C,OAAO,KAAK,EAAE,cAAc,EAAgB,eAAe,EAAmB,MAAM,cAAc,CAAC;AAiWnG;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,cAAc,CAAC,CAgNzB"}
1
+ {"version":3,"file":"hazo_get_auth.server.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/hazo_get_auth.server.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAK1C,OAAO,KAAK,EAAE,cAAc,EAAgB,eAAe,EAAmB,MAAM,cAAc,CAAC;AAiWnG;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,cAAc,CAAC,CAwOzB"}
@@ -2,7 +2,7 @@ import { get_hazo_connect_instance } from "../hazo_connect_instance.server";
2
2
  import { createCrudService } from "hazo_connect/server";
3
3
  import { create_app_logger } from "../app_logger";
4
4
  import { get_filename, get_line_number } from "../utils/api_route_helpers";
5
- import { PermissionError, ScopeAccessError } from "./auth_types";
5
+ import { PermissionError, ScopeAccessError, OrgRequiredError } from "./auth_types";
6
6
  import { get_auth_cache } from "./auth_cache";
7
7
  import { get_scope_cache } from "./scope_cache";
8
8
  import { get_rate_limiter } from "./auth_rate_limiter";
@@ -436,6 +436,25 @@ export async function hazo_get_auth(request, options) {
436
436
  throw new ScopeAccessError(options.scope_type, (options === null || options === void 0 ? void 0 : options.scope_id) || (options === null || options === void 0 ? void 0 : options.scope_seq) || "unknown", scope_result.user_scopes);
437
437
  }
438
438
  }
439
+ // Check org requirement if specified (only when multi-tenancy is enabled)
440
+ let org_ok;
441
+ if ((options === null || options === void 0 ? void 0 : options.require_org) && is_multi_tenancy_enabled()) {
442
+ org_ok = !!user.org_id;
443
+ if (!org_ok) {
444
+ // Log org requirement failure if permission logging is enabled
445
+ if (config.log_permission_denials) {
446
+ const client_ip = get_client_ip(request);
447
+ logger.warn("auth_utility_org_required_missing", {
448
+ filename: get_filename(),
449
+ line_number: get_line_number(),
450
+ user_id: user.id,
451
+ ip: client_ip,
452
+ });
453
+ }
454
+ // Always throw error when org is required but missing
455
+ throw new OrgRequiredError(user.id);
456
+ }
457
+ }
439
458
  return {
440
459
  authenticated: true,
441
460
  user,
@@ -444,5 +463,6 @@ export async function hazo_get_auth(request, options) {
444
463
  missing_permissions,
445
464
  scope_ok,
446
465
  scope_access_via,
466
+ org_ok,
447
467
  };
448
468
  }
@@ -133,6 +133,36 @@ export declare const DEFAULT_MULTI_TENANCY: {
133
133
  /** Default user limit per organization (0 = unlimited) */
134
134
  readonly default_user_limit: 0;
135
135
  };
136
+ export declare const DEFAULT_NAVBAR: {
137
+ /** Enable navbar on auth pages */
138
+ readonly enable_navbar: true;
139
+ /** Logo image path (default: /logo.png in public folder) */
140
+ readonly logo_path: "/logo.png";
141
+ /** Logo width in pixels */
142
+ readonly logo_width: 32;
143
+ /** Logo height in pixels */
144
+ readonly logo_height: 32;
145
+ /** Company/application name displayed next to logo */
146
+ readonly company_name: "";
147
+ /** Home link path */
148
+ readonly home_path: "/";
149
+ /** Home link label */
150
+ readonly home_label: "Home";
151
+ /** Show home link */
152
+ readonly show_home_link: true;
153
+ /** Navbar background color (empty = transparent/inherit) */
154
+ readonly background_color: "";
155
+ /** Navbar text color (empty = inherit) */
156
+ readonly text_color: "";
157
+ /** Navbar height in pixels */
158
+ readonly height: 64;
159
+ };
160
+ export declare const DEFAULT_USER_TYPES: {
161
+ /** Enable user types feature (default: false) */
162
+ readonly enable_user_types: false;
163
+ /** Default user type for new users (empty = no default) */
164
+ readonly default_user_type: "";
165
+ };
136
166
  export declare const DEFAULT_DEV_LOCK: {
137
167
  /** Enable the development lock screen (also requires HAZO_AUTH_DEV_LOCK_ENABLED env var) */
138
168
  readonly enable: false;
@@ -329,6 +359,36 @@ export declare const HAZO_AUTH_DEFAULTS: {
329
359
  /** Default user limit per organization (0 = unlimited) */
330
360
  readonly default_user_limit: 0;
331
361
  };
362
+ readonly navbar: {
363
+ /** Enable navbar on auth pages */
364
+ readonly enable_navbar: true;
365
+ /** Logo image path (default: /logo.png in public folder) */
366
+ readonly logo_path: "/logo.png";
367
+ /** Logo width in pixels */
368
+ readonly logo_width: 32;
369
+ /** Logo height in pixels */
370
+ readonly logo_height: 32;
371
+ /** Company/application name displayed next to logo */
372
+ readonly company_name: "";
373
+ /** Home link path */
374
+ readonly home_path: "/";
375
+ /** Home link label */
376
+ readonly home_label: "Home";
377
+ /** Show home link */
378
+ readonly show_home_link: true;
379
+ /** Navbar background color (empty = transparent/inherit) */
380
+ readonly background_color: "";
381
+ /** Navbar text color (empty = inherit) */
382
+ readonly text_color: "";
383
+ /** Navbar height in pixels */
384
+ readonly height: 64;
385
+ };
386
+ readonly userTypes: {
387
+ /** Enable user types feature (default: false) */
388
+ readonly enable_user_types: false;
389
+ /** Default user type for new users (empty = no default) */
390
+ readonly default_user_type: "";
391
+ };
332
392
  };
333
393
  /**
334
394
  * Type representing the complete default configuration structure
@@ -1 +1 @@
1
- {"version":3,"file":"default_config.d.ts","sourceRoot":"","sources":["../../../src/lib/config/default_config.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,6BAA6B;;;;;;CAMhC,CAAC;AAGX,eAAO,MAAM,mBAAmB;;;;CAItB,CAAC;AAGX,eAAO,MAAM,uBAAuB;;;;;;;CAO1B,CAAC;AAGX,eAAO,MAAM,gBAAgB;;;;;;;;;CASnB,CAAC;AAGX,eAAO,MAAM,kBAAkB;;;CAGrB,CAAC;AAGX,eAAO,MAAM,gBAAgB;;;;;CAKnB,CAAC;AAGX,eAAO,MAAM,yBAAyB;;;;;;CAM5B,CAAC;AAGX,eAAO,MAAM,aAAa;4BACI,MAAM,GAAG,SAAS;;;;;;CAMtC,CAAC;AAGX,eAAO,MAAM,gBAAgB;4BACC,MAAM,GAAG,SAAS;;;;;CAKtC,CAAC;AAGX,eAAO,MAAM,uBAAuB;;;;CAI1B,CAAC;AAGX,eAAO,MAAM,sBAAsB;;;;CAIzB,CAAC;AAGX,eAAO,MAAM,0BAA0B;;;;;CAK7B,CAAC;AAGX,eAAO,MAAM,mBAAmB;;;;;CAKtB,CAAC;AAGX,eAAO,MAAM,uBAAuB;;;;CAI1B,CAAC;AAGX,eAAO,MAAM,oBAAoB;;;;CAIvB,CAAC;AAGX,eAAO,MAAM,gBAAgB;0BACE,YAAY,GAAG,cAAc;;;;;CAKlD,CAAC;AAGX,eAAO,MAAM,wBAAwB;;;;;;;;CAQ3B,CAAC;AAGX,eAAO,MAAM,iBAAiB;;CAEpB,CAAC;AAGX,eAAO,MAAM,aAAa;IACxB,kHAAkH;;IAElH,8CAA8C;;IAE9C,iGAAiG;;IAEjG,kDAAkD;;IAElD,0EAA0E;;CAElE,CAAC;AAGX,eAAO,MAAM,qBAAqB;IAChC,oDAAoD;;IAEpD,yDAAyD;;IAEzD,mDAAmD;;IAEnD,0DAA0D;;CAElD,CAAC;AAGX,eAAO,MAAM,gBAAgB;IAC3B,4FAA4F;;IAE5F,+BAA+B;;IAE/B,wCAAwC;;IAExC,4DAA4D;;IAE5D,2BAA2B;;IAE3B,4BAA4B;;IAE5B,4CAA4C;;IAE5C,mDAAmD;;IAEnD,sCAAsC;;IAEtC,yBAAyB;;IAEzB,2CAA2C;;IAE3C,6CAA6C;;IAE7C,8CAA8C;;CAEtC,CAAC;AAGX;;;GAGG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAnJD,MAAM,GAAG,SAAS;;;;;;;;gCAUlB,MAAM,GAAG,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BAqDjB,YAAY,GAAG,cAAc;;;;;;;;;;;;;;;;;;;QAyB1D,kHAAkH;;QAElH,8CAA8C;;QAE9C,iGAAiG;;QAEjG,kDAAkD;;QAElD,0EAA0E;;;;QAkB1E,4FAA4F;;QAE5F,+BAA+B;;QAE/B,wCAAwC;;QAExC,4DAA4D;;QAE5D,2BAA2B;;QAE3B,4BAA4B;;QAE5B,4CAA4C;;QAE5C,mDAAmD;;QAEnD,sCAAsC;;QAEtC,yBAAyB;;QAEzB,2CAA2C;;QAE3C,6CAA6C;;QAE7C,8CAA8C;;;;QApC9C,oDAAoD;;QAEpD,yDAAyD;;QAEzD,mDAAmD;;QAEnD,0DAA0D;;;CA6DlD,CAAC;AAGX;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,kBAAkB,CAAC"}
1
+ {"version":3,"file":"default_config.d.ts","sourceRoot":"","sources":["../../../src/lib/config/default_config.ts"],"names":[],"mappings":"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"}
@@ -156,6 +156,38 @@ export const DEFAULT_MULTI_TENANCY = {
156
156
  /** Default user limit per organization (0 = unlimited) */
157
157
  default_user_limit: 0,
158
158
  };
159
+ // section: navbar
160
+ export const DEFAULT_NAVBAR = {
161
+ /** Enable navbar on auth pages */
162
+ enable_navbar: true,
163
+ /** Logo image path (default: /logo.png in public folder) */
164
+ logo_path: "/logo.png",
165
+ /** Logo width in pixels */
166
+ logo_width: 32,
167
+ /** Logo height in pixels */
168
+ logo_height: 32,
169
+ /** Company/application name displayed next to logo */
170
+ company_name: "",
171
+ /** Home link path */
172
+ home_path: "/",
173
+ /** Home link label */
174
+ home_label: "Home",
175
+ /** Show home link */
176
+ show_home_link: true,
177
+ /** Navbar background color (empty = transparent/inherit) */
178
+ background_color: "",
179
+ /** Navbar text color (empty = inherit) */
180
+ text_color: "",
181
+ /** Navbar height in pixels */
182
+ height: 64,
183
+ };
184
+ // section: user_types
185
+ export const DEFAULT_USER_TYPES = {
186
+ /** Enable user types feature (default: false) */
187
+ enable_user_types: false,
188
+ /** Default user type for new users (empty = no default) */
189
+ default_user_type: "",
190
+ };
159
191
  // section: dev_lock
160
192
  export const DEFAULT_DEV_LOCK = {
161
193
  /** Enable the development lock screen (also requires HAZO_AUTH_DEV_LOCK_ENABLED env var) */
@@ -212,4 +244,6 @@ export const HAZO_AUTH_DEFAULTS = {
212
244
  oauth: DEFAULT_OAUTH,
213
245
  devLock: DEFAULT_DEV_LOCK,
214
246
  multiTenancy: DEFAULT_MULTI_TENANCY,
247
+ navbar: DEFAULT_NAVBAR,
248
+ userTypes: DEFAULT_USER_TYPES,
215
249
  };
@@ -0,0 +1,36 @@
1
+ export type NavbarConfig = {
2
+ /** Enable navbar on auth pages */
3
+ enable_navbar: boolean;
4
+ /** Logo image path */
5
+ logo_path: string;
6
+ /** Logo width in pixels */
7
+ logo_width: number;
8
+ /** Logo height in pixels */
9
+ logo_height: number;
10
+ /** Company/application name displayed next to logo */
11
+ company_name: string;
12
+ /** Home link path */
13
+ home_path: string;
14
+ /** Home link label */
15
+ home_label: string;
16
+ /** Show home link */
17
+ show_home_link: boolean;
18
+ /** Navbar background color (empty = inherit) */
19
+ background_color: string;
20
+ /** Navbar text color (empty = inherit) */
21
+ text_color: string;
22
+ /** Navbar height in pixels */
23
+ height: number;
24
+ };
25
+ /**
26
+ * Reads navbar configuration from hazo_auth_config.ini file
27
+ * Falls back to defaults if hazo_auth_config.ini is not found or section is missing
28
+ * @returns Navbar configuration options
29
+ */
30
+ export declare function get_navbar_config(): NavbarConfig;
31
+ /**
32
+ * Helper to check if navbar is enabled in config
33
+ * @returns true if navbar is enabled
34
+ */
35
+ export declare function is_navbar_enabled(): boolean;
36
+ //# sourceMappingURL=navbar_config.server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navbar_config.server.d.ts","sourceRoot":"","sources":["../../src/lib/navbar_config.server.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,YAAY,GAAG;IACzB,kCAAkC;IAClC,aAAa,EAAE,OAAO,CAAC;IACvB,sBAAsB;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,2BAA2B;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,YAAY,EAAE,MAAM,CAAC;IACrB,qBAAqB;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,sBAAsB;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,qBAAqB;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,gDAAgD;IAChD,gBAAgB,EAAE,MAAM,CAAC;IACzB,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAMF;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,YAAY,CAgFhD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C"}