hazo_auth 4.3.0 → 4.4.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/cli-src/lib/already_logged_in_config.server.ts +1 -1
- package/cli-src/lib/app_logger.ts +8 -18
- package/cli-src/lib/auth/auth_types.ts +7 -0
- package/cli-src/lib/auth/auth_utils.server.ts +2 -2
- package/cli-src/lib/auth/dev_lock_validator.edge.ts +171 -0
- package/cli-src/lib/auth/hazo_get_auth.server.ts +84 -13
- package/cli-src/lib/auth/index.ts +5 -5
- package/cli-src/lib/auth/nextauth_config.ts +4 -4
- package/cli-src/lib/auth/org_cache.ts +148 -0
- package/cli-src/lib/auth/server_auth.ts +2 -2
- package/cli-src/lib/auth/session_token_validator.edge.ts +4 -0
- package/cli-src/lib/auth_utility_config.server.ts +1 -1
- package/cli-src/lib/config/config_loader.server.ts +1 -1
- package/cli-src/lib/config/default_config.ts +44 -0
- package/cli-src/lib/dev_lock_config.server.ts +148 -0
- package/cli-src/lib/email_verification_config.server.ts +3 -3
- package/cli-src/lib/file_types_config.server.ts +1 -1
- package/cli-src/lib/forgot_password_config.server.ts +3 -3
- package/cli-src/lib/hazo_connect_instance.server.ts +2 -2
- package/cli-src/lib/hazo_connect_setup.server.ts +2 -2
- package/cli-src/lib/index.ts +24 -24
- package/cli-src/lib/login_config.server.ts +4 -4
- package/cli-src/lib/messages_config.server.ts +1 -1
- package/cli-src/lib/multi_tenancy_config.server.ts +94 -0
- package/cli-src/lib/my_settings_config.server.ts +7 -7
- package/cli-src/lib/oauth_config.server.ts +2 -2
- package/cli-src/lib/password_requirements_config.server.ts +2 -2
- package/cli-src/lib/profile_pic_menu_config.server.ts +1 -1
- package/cli-src/lib/profile_picture_config.server.ts +2 -2
- package/cli-src/lib/register_config.server.ts +5 -5
- package/cli-src/lib/reset_password_config.server.ts +4 -4
- package/cli-src/lib/scope_hierarchy_config.server.ts +2 -2
- package/cli-src/lib/services/email_service.ts +2 -2
- package/cli-src/lib/services/email_verification_service.ts +3 -3
- package/cli-src/lib/services/login_service.ts +3 -3
- package/cli-src/lib/services/oauth_service.ts +4 -4
- package/cli-src/lib/services/org_service.ts +965 -0
- package/cli-src/lib/services/password_change_service.ts +3 -3
- package/cli-src/lib/services/password_reset_service.ts +3 -3
- package/cli-src/lib/services/profile_picture_remove_service.ts +3 -3
- package/cli-src/lib/services/profile_picture_service.ts +5 -5
- package/cli-src/lib/services/registration_service.ts +8 -8
- package/cli-src/lib/services/scope_labels_service.ts +3 -3
- package/cli-src/lib/services/scope_service.ts +2 -2
- package/cli-src/lib/services/session_token_service.ts +6 -2
- package/cli-src/lib/services/token_service.ts +2 -2
- package/cli-src/lib/services/user_profiles_service.ts +4 -4
- package/cli-src/lib/services/user_scope_service.ts +3 -3
- package/cli-src/lib/services/user_update_service.ts +4 -4
- package/cli-src/lib/ui_shell_config.server.ts +1 -1
- package/cli-src/lib/ui_sizes_config.server.ts +1 -1
- package/cli-src/lib/user_fields_config.server.ts +1 -1
- package/cli-src/lib/user_management_config.server.ts +1 -1
- package/cli-src/lib/user_profiles_config.server.ts +1 -1
- package/cli-src/lib/utils/error_sanitizer.ts +1 -1
- package/cli-src/server/types/app_types.ts +72 -0
- package/cli-src/server/types/express.d.ts +16 -0
- package/dist/components/layouts/dev_lock/index.d.ts +29 -0
- package/dist/components/layouts/dev_lock/index.d.ts.map +1 -0
- package/dist/components/layouts/dev_lock/index.js +60 -0
- package/dist/components/layouts/index.d.ts +2 -0
- package/dist/components/layouts/index.d.ts.map +1 -1
- package/dist/components/layouts/index.js +1 -0
- package/dist/components/layouts/login/hooks/use_login_form.js +2 -2
- package/dist/components/layouts/org_management/index.d.ts +26 -0
- package/dist/components/layouts/org_management/index.d.ts.map +1 -0
- package/dist/components/layouts/org_management/index.js +75 -0
- package/dist/components/layouts/user_management/components/org_hierarchy_tab.d.ts +13 -0
- package/dist/components/layouts/user_management/components/org_hierarchy_tab.d.ts.map +1 -0
- package/dist/components/layouts/user_management/components/org_hierarchy_tab.js +276 -0
- package/dist/components/layouts/user_management/index.d.ts +3 -1
- package/dist/components/layouts/user_management/index.d.ts.map +1 -1
- package/dist/components/layouts/user_management/index.js +10 -4
- package/dist/components/ui/button.d.ts +1 -1
- package/dist/lib/app_logger.d.ts +3 -9
- package/dist/lib/app_logger.d.ts.map +1 -1
- package/dist/lib/app_logger.js +7 -10
- package/dist/lib/auth/auth_types.d.ts +6 -0
- package/dist/lib/auth/auth_types.d.ts.map +1 -1
- package/dist/lib/auth/dev_lock_validator.edge.d.ts +38 -0
- package/dist/lib/auth/dev_lock_validator.edge.d.ts.map +1 -0
- package/dist/lib/auth/dev_lock_validator.edge.js +122 -0
- package/dist/lib/auth/hazo_get_auth.server.d.ts.map +1 -1
- package/dist/lib/auth/hazo_get_auth.server.js +61 -1
- package/dist/lib/auth/org_cache.d.ts +65 -0
- package/dist/lib/auth/org_cache.d.ts.map +1 -0
- package/dist/lib/auth/org_cache.js +103 -0
- package/dist/lib/config/default_config.d.ts +76 -0
- package/dist/lib/config/default_config.d.ts.map +1 -1
- package/dist/lib/config/default_config.js +42 -0
- package/dist/lib/dev_lock_config.server.d.ts +41 -0
- package/dist/lib/dev_lock_config.server.d.ts.map +1 -0
- package/dist/lib/dev_lock_config.server.js +50 -0
- package/dist/lib/multi_tenancy_config.server.d.ts +30 -0
- package/dist/lib/multi_tenancy_config.server.d.ts.map +1 -0
- package/dist/lib/multi_tenancy_config.server.js +41 -0
- package/dist/lib/services/org_service.d.ts +191 -0
- package/dist/lib/services/org_service.d.ts.map +1 -0
- package/dist/lib/services/org_service.js +746 -0
- package/dist/page_components/dev_lock.d.ts +11 -0
- package/dist/page_components/dev_lock.d.ts.map +1 -0
- package/dist/page_components/dev_lock.js +17 -0
- package/dist/page_components/index.d.ts +1 -0
- package/dist/page_components/index.d.ts.map +1 -1
- package/dist/page_components/index.js +1 -0
- package/dist/page_components/login.d.ts.map +1 -1
- package/dist/page_components/login.js +3 -7
- package/dist/page_components/org_management.d.ts +27 -0
- package/dist/page_components/org_management.d.ts.map +1 -0
- package/dist/page_components/org_management.js +18 -0
- package/dist/server/config/config_loader.js +2 -2
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +2 -3
- package/dist/server/types/app_types.d.ts +3 -7
- package/dist/server/types/app_types.d.ts.map +1 -1
- package/dist/server_pages/login_client_wrapper.d.ts.map +1 -1
- package/dist/server_pages/login_client_wrapper.js +1 -3
- package/hazo_auth_config.example.ini +30 -0
- package/package.json +29 -2
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
import type { HazoConnectAdapter } from "hazo_connect";
|
|
4
4
|
import { createCrudService } from "hazo_connect/server";
|
|
5
5
|
import argon2 from "argon2";
|
|
6
|
-
import { get_password_requirements_config } from "../password_requirements_config.server";
|
|
7
|
-
import { send_template_email } from "./email_service";
|
|
8
|
-
import { create_app_logger } from "../app_logger";
|
|
6
|
+
import { get_password_requirements_config } from "../password_requirements_config.server.js";
|
|
7
|
+
import { send_template_email } from "./email_service.js";
|
|
8
|
+
import { create_app_logger } from "../app_logger.js";
|
|
9
9
|
|
|
10
10
|
// section: types
|
|
11
11
|
export type PasswordChangeData = {
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
// section: imports
|
|
3
3
|
import type { HazoConnectAdapter } from "hazo_connect";
|
|
4
4
|
import { createCrudService } from "hazo_connect/server";
|
|
5
|
-
import { create_token } from "./token_service";
|
|
5
|
+
import { create_token } from "./token_service.js";
|
|
6
6
|
import argon2 from "argon2";
|
|
7
|
-
import { create_app_logger } from "../app_logger";
|
|
8
|
-
import { send_template_email } from "./email_service";
|
|
7
|
+
import { create_app_logger } from "../app_logger.js";
|
|
8
|
+
import { send_template_email } from "./email_service.js";
|
|
9
9
|
|
|
10
10
|
// section: types
|
|
11
11
|
export type PasswordResetRequestData = {
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
// section: imports
|
|
3
3
|
import type { HazoConnectAdapter } from "hazo_connect";
|
|
4
4
|
import { createCrudService } from "hazo_connect/server";
|
|
5
|
-
import { map_db_source_to_ui } from "./profile_picture_source_mapper";
|
|
6
|
-
import { get_profile_picture_config } from "../profile_picture_config.server";
|
|
7
|
-
import { create_app_logger } from "../app_logger";
|
|
5
|
+
import { map_db_source_to_ui } from "./profile_picture_source_mapper.js";
|
|
6
|
+
import { get_profile_picture_config } from "../profile_picture_config.server.js";
|
|
7
|
+
import { create_app_logger } from "../app_logger.js";
|
|
8
8
|
import fs from "fs";
|
|
9
9
|
import path from "path";
|
|
10
10
|
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
import type { HazoConnectAdapter } from "hazo_connect";
|
|
4
4
|
import { createCrudService } from "hazo_connect/server";
|
|
5
5
|
import gravatarUrl from "gravatar-url";
|
|
6
|
-
import { get_profile_picture_config } from "../profile_picture_config.server";
|
|
7
|
-
import { get_ui_sizes_config } from "../ui_sizes_config.server";
|
|
8
|
-
import { get_file_types_config } from "../file_types_config.server";
|
|
9
|
-
import { create_app_logger } from "../app_logger";
|
|
6
|
+
import { get_profile_picture_config } from "../profile_picture_config.server.js";
|
|
7
|
+
import { get_ui_sizes_config } from "../ui_sizes_config.server.js";
|
|
8
|
+
import { get_file_types_config } from "../file_types_config.server.js";
|
|
9
|
+
import { create_app_logger } from "../app_logger.js";
|
|
10
10
|
import path from "path";
|
|
11
11
|
import fs from "fs";
|
|
12
|
-
import { map_ui_source_to_db, type ProfilePictureSourceUI } from "./profile_picture_source_mapper";
|
|
12
|
+
import { map_ui_source_to_db, type ProfilePictureSourceUI } from "./profile_picture_source_mapper.js";
|
|
13
13
|
|
|
14
14
|
// section: types
|
|
15
15
|
export type ProfilePictureSource = ProfilePictureSourceUI;
|
|
@@ -4,14 +4,14 @@ import type { HazoConnectAdapter } from "hazo_connect";
|
|
|
4
4
|
import { createCrudService } from "hazo_connect/server";
|
|
5
5
|
import argon2 from "argon2";
|
|
6
6
|
import { randomUUID } from "crypto";
|
|
7
|
-
import { create_token } from "./token_service";
|
|
8
|
-
import { get_default_profile_picture } from "./profile_picture_service";
|
|
9
|
-
import { get_profile_picture_config } from "../profile_picture_config.server";
|
|
10
|
-
import { map_ui_source_to_db } from "./profile_picture_source_mapper";
|
|
11
|
-
import { create_app_logger } from "../app_logger";
|
|
12
|
-
import { send_template_email } from "./email_service";
|
|
13
|
-
import { sanitize_error_for_user } from "../utils/error_sanitizer";
|
|
14
|
-
import { get_filename, get_line_number } from "../utils/api_route_helpers";
|
|
7
|
+
import { create_token } from "./token_service.js";
|
|
8
|
+
import { get_default_profile_picture } from "./profile_picture_service.js";
|
|
9
|
+
import { get_profile_picture_config } from "../profile_picture_config.server.js";
|
|
10
|
+
import { map_ui_source_to_db } from "./profile_picture_source_mapper.js";
|
|
11
|
+
import { create_app_logger } from "../app_logger.js";
|
|
12
|
+
import { send_template_email } from "./email_service.js";
|
|
13
|
+
import { sanitize_error_for_user } from "../utils/error_sanitizer.js";
|
|
14
|
+
import { get_filename, get_line_number } from "../utils/api_route_helpers.js";
|
|
15
15
|
|
|
16
16
|
// section: types
|
|
17
17
|
export type RegistrationData = {
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
import type { HazoConnectAdapter } from "hazo_connect";
|
|
4
4
|
import { createCrudService } from "hazo_connect/server";
|
|
5
5
|
import { randomUUID } from "crypto";
|
|
6
|
-
import { create_app_logger } from "../app_logger";
|
|
7
|
-
import { sanitize_error_for_user } from "../utils/error_sanitizer";
|
|
6
|
+
import { create_app_logger } from "../app_logger.js";
|
|
7
|
+
import { sanitize_error_for_user } from "../utils/error_sanitizer.js";
|
|
8
8
|
import type { ScopeLevel } from "./scope_service";
|
|
9
|
-
import { SCOPE_LEVELS } from "./scope_service";
|
|
9
|
+
import { SCOPE_LEVELS } from "./scope_service.js";
|
|
10
10
|
|
|
11
11
|
// section: types
|
|
12
12
|
export type ScopeLabel = {
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// section: imports
|
|
3
3
|
import type { HazoConnectAdapter } from "hazo_connect";
|
|
4
4
|
import { createCrudService } from "hazo_connect/server";
|
|
5
|
-
import { create_app_logger } from "../app_logger";
|
|
6
|
-
import { sanitize_error_for_user } from "../utils/error_sanitizer";
|
|
5
|
+
import { create_app_logger } from "../app_logger.js";
|
|
6
|
+
import { sanitize_error_for_user } from "../utils/error_sanitizer.js";
|
|
7
7
|
|
|
8
8
|
// section: types
|
|
9
9
|
export type ScopeLevel =
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// Uses jose library for Edge-compatible JWT operations
|
|
3
3
|
// section: imports
|
|
4
4
|
import { SignJWT, jwtVerify } from "jose";
|
|
5
|
-
import { create_app_logger } from "../app_logger";
|
|
6
|
-
import { get_filename, get_line_number } from "../utils/api_route_helpers";
|
|
5
|
+
import { create_app_logger } from "../app_logger.js";
|
|
6
|
+
import { get_filename, get_line_number } from "../utils/api_route_helpers.js";
|
|
7
7
|
|
|
8
8
|
// section: types
|
|
9
9
|
export type SessionTokenPayload = {
|
|
@@ -175,3 +175,7 @@ export async function validate_session_token(
|
|
|
175
175
|
|
|
176
176
|
|
|
177
177
|
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
|
|
@@ -4,8 +4,8 @@ import type { HazoConnectAdapter } from "hazo_connect";
|
|
|
4
4
|
import { createCrudService } from "hazo_connect/server";
|
|
5
5
|
import { randomBytes, randomUUID } from "crypto";
|
|
6
6
|
import argon2 from "argon2";
|
|
7
|
-
import { read_config_section } from "../config/config_loader.server";
|
|
8
|
-
import { create_app_logger } from "../app_logger";
|
|
7
|
+
import { read_config_section } from "../config/config_loader.server.js";
|
|
8
|
+
import { create_app_logger } from "../app_logger.js";
|
|
9
9
|
|
|
10
10
|
// section: types
|
|
11
11
|
export type TokenType = "refresh" | "password_reset" | "email_verification";
|
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
import type { HazoConnectAdapter } from "hazo_connect";
|
|
5
5
|
import { createCrudService } from "hazo_connect/server";
|
|
6
6
|
import { differenceInDays } from "date-fns";
|
|
7
|
-
import { create_app_logger } from "../app_logger";
|
|
8
|
-
import { sanitize_error_for_user } from "../utils/error_sanitizer";
|
|
9
|
-
import { get_user_profiles_cache } from "./user_profiles_cache";
|
|
10
|
-
import { get_user_profiles_cache_config } from "../user_profiles_config.server";
|
|
7
|
+
import { create_app_logger } from "../app_logger.js";
|
|
8
|
+
import { sanitize_error_for_user } from "../utils/error_sanitizer.js";
|
|
9
|
+
import { get_user_profiles_cache } from "./user_profiles_cache.js";
|
|
10
|
+
import { get_user_profiles_cache_config } from "../user_profiles_config.server.js";
|
|
11
11
|
|
|
12
12
|
// section: types
|
|
13
13
|
/**
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// section: imports
|
|
3
3
|
import type { HazoConnectAdapter } from "hazo_connect";
|
|
4
4
|
import { createCrudService } from "hazo_connect/server";
|
|
5
|
-
import { create_app_logger } from "../app_logger";
|
|
6
|
-
import { sanitize_error_for_user } from "../utils/error_sanitizer";
|
|
5
|
+
import { create_app_logger } from "../app_logger.js";
|
|
6
|
+
import { sanitize_error_for_user } from "../utils/error_sanitizer.js";
|
|
7
7
|
import {
|
|
8
8
|
type ScopeLevel,
|
|
9
9
|
SCOPE_LEVELS,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
get_scope_by_seq,
|
|
13
13
|
get_scope_ancestors,
|
|
14
14
|
is_valid_scope_level,
|
|
15
|
-
} from "./scope_service";
|
|
15
|
+
} from "./scope_service.js";
|
|
16
16
|
|
|
17
17
|
// section: types
|
|
18
18
|
export type UserScope = {
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
// section: imports
|
|
3
3
|
import type { HazoConnectAdapter } from "hazo_connect";
|
|
4
4
|
import { createCrudService } from "hazo_connect/server";
|
|
5
|
-
import { map_ui_source_to_db, type ProfilePictureSourceUI } from "./profile_picture_source_mapper";
|
|
6
|
-
import { create_app_logger } from "../app_logger";
|
|
7
|
-
import { sanitize_error_for_user } from "../utils/error_sanitizer";
|
|
8
|
-
import { get_filename, get_line_number } from "../utils/api_route_helpers";
|
|
5
|
+
import { map_ui_source_to_db, type ProfilePictureSourceUI } from "./profile_picture_source_mapper.js";
|
|
6
|
+
import { create_app_logger } from "../app_logger.js";
|
|
7
|
+
import { sanitize_error_for_user } from "../utils/error_sanitizer.js";
|
|
8
|
+
import { get_filename, get_line_number } from "../utils/api_route_helpers.js";
|
|
9
9
|
|
|
10
10
|
// section: types
|
|
11
11
|
export type UserUpdateData = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// file_description: load ui shell layout settings from hazo_auth_config.ini
|
|
2
2
|
// section: imports
|
|
3
|
-
import { get_config_value } from "./config/config_loader.server";
|
|
3
|
+
import { get_config_value } from "./config/config_loader.server.js";
|
|
4
4
|
|
|
5
5
|
// section: types
|
|
6
6
|
export type UiShellLayoutMode = "test_sidebar" | "standalone";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// file_description: server-only helper to read UI size configuration from hazo_auth_config.ini
|
|
2
2
|
// section: imports
|
|
3
|
-
import { get_config_number } from "./config/config_loader.server";
|
|
3
|
+
import { get_config_number } from "./config/config_loader.server.js";
|
|
4
4
|
|
|
5
5
|
// section: types
|
|
6
6
|
export type UISizesConfig = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// file_description: server-only helper to read shared user fields configuration from hazo_auth_config.ini
|
|
2
2
|
// section: imports
|
|
3
|
-
import { get_config_boolean } from "./config/config_loader.server";
|
|
3
|
+
import { get_config_boolean } from "./config/config_loader.server.js";
|
|
4
4
|
|
|
5
5
|
// section: types
|
|
6
6
|
export type UserFieldsConfig = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// file_description: server-only helper to read user management configuration from hazo_auth_config.ini
|
|
2
2
|
// section: imports
|
|
3
|
-
import { get_config_value, get_config_array, read_config_section } from "./config/config_loader.server";
|
|
3
|
+
import { get_config_value, get_config_array, read_config_section } from "./config/config_loader.server.js";
|
|
4
4
|
|
|
5
5
|
// section: types
|
|
6
6
|
export type UserManagementConfig = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// file_description: utility functions for sanitizing error messages for user display
|
|
2
2
|
// section: imports
|
|
3
|
-
import { create_app_logger } from "../app_logger";
|
|
3
|
+
import { create_app_logger } from "../app_logger.js";
|
|
4
4
|
|
|
5
5
|
// section: constants
|
|
6
6
|
const USER_FRIENDLY_ERROR_MESSAGE = "We are facing some issues in our system, please try again later.";
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// file_description: define shared application level types for the hazo_auth server
|
|
2
|
+
// section: request_context_types
|
|
3
|
+
import type { Request } from "express";
|
|
4
|
+
import type { Logger, LogData } from "hazo_logs";
|
|
5
|
+
|
|
6
|
+
// section: logger_interface_definition
|
|
7
|
+
// Re-export hazo_logs types for backward compatibility
|
|
8
|
+
export type logger_method = (
|
|
9
|
+
message: string,
|
|
10
|
+
data?: LogData
|
|
11
|
+
) => void;
|
|
12
|
+
|
|
13
|
+
// Use hazo_logs Logger type as logger_service for backward compatibility
|
|
14
|
+
export type logger_service = Logger;
|
|
15
|
+
|
|
16
|
+
// section: configuration_types
|
|
17
|
+
export type emailer_client = {
|
|
18
|
+
send_message: (
|
|
19
|
+
payload: Record<string, unknown>
|
|
20
|
+
) => Promise<{ success: boolean }>;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type handlebars_templates = Record<string, string>;
|
|
24
|
+
|
|
25
|
+
export type password_policy = {
|
|
26
|
+
min_length: number;
|
|
27
|
+
requires_uppercase: boolean;
|
|
28
|
+
requires_lowercase: boolean;
|
|
29
|
+
requires_number: boolean;
|
|
30
|
+
requires_symbol: boolean;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type token_settings = {
|
|
34
|
+
access_token_ttl_seconds: number;
|
|
35
|
+
refresh_token_ttl_seconds: number;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export type rate_limit_settings = {
|
|
39
|
+
max_attempts: number;
|
|
40
|
+
window_minutes: number;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export type captcha_settings =
|
|
44
|
+
| {
|
|
45
|
+
provider: "recaptcha_v2" | "recaptcha_v3" | "hcaptcha";
|
|
46
|
+
secret_key: string;
|
|
47
|
+
}
|
|
48
|
+
| undefined;
|
|
49
|
+
|
|
50
|
+
export type runtime_configuration = {
|
|
51
|
+
permission_names: string[];
|
|
52
|
+
logger: logger_service;
|
|
53
|
+
emailer: emailer_client;
|
|
54
|
+
templates: handlebars_templates;
|
|
55
|
+
labels: Record<string, string>;
|
|
56
|
+
styles: Record<string, string>;
|
|
57
|
+
password_policy: password_policy;
|
|
58
|
+
token_settings: token_settings;
|
|
59
|
+
rate_limit: rate_limit_settings;
|
|
60
|
+
captcha: captcha_settings;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export type app_context = {
|
|
64
|
+
config: runtime_configuration;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// section: typed_request_wrapper
|
|
68
|
+
export type context_request<T = unknown> = Request & {
|
|
69
|
+
body: T;
|
|
70
|
+
context: app_context;
|
|
71
|
+
};
|
|
72
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export type DevLockLayoutProps = {
|
|
2
|
+
/** Background color (default: #000000 - black) */
|
|
3
|
+
background_color?: string;
|
|
4
|
+
/** Logo image path (default: /logo.png) */
|
|
5
|
+
logo_path?: string;
|
|
6
|
+
/** Logo width in pixels (default: 120) */
|
|
7
|
+
logo_width?: number;
|
|
8
|
+
/** Logo height in pixels (default: 120) */
|
|
9
|
+
logo_height?: number;
|
|
10
|
+
/** Application name displayed below logo */
|
|
11
|
+
application_name?: string;
|
|
12
|
+
/** Limited access text displayed with lock icon (default: "Limited Access") */
|
|
13
|
+
limited_access_text?: string;
|
|
14
|
+
/** Password input placeholder (default: "Enter access password") */
|
|
15
|
+
password_placeholder?: string;
|
|
16
|
+
/** Submit button text (default: "Unlock") */
|
|
17
|
+
submit_button_text?: string;
|
|
18
|
+
/** Error message for incorrect password (default: "Incorrect password") */
|
|
19
|
+
error_message?: string;
|
|
20
|
+
/** Text color for labels (default: #ffffff - white) */
|
|
21
|
+
text_color?: string;
|
|
22
|
+
/** Accent color for button (default: #3b82f6 - blue) */
|
|
23
|
+
accent_color?: string;
|
|
24
|
+
/** Callback when unlock is successful */
|
|
25
|
+
onUnlock?: () => void;
|
|
26
|
+
};
|
|
27
|
+
export default function DevLockLayout({ background_color, logo_path, logo_width, logo_height, application_name, limited_access_text, password_placeholder, submit_button_text, error_message, text_color, accent_color, onUnlock, }: DevLockLayoutProps): import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
export { DevLockLayout };
|
|
29
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/layouts/dev_lock/index.tsx"],"names":[],"mappings":"AAaA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,kDAAkD;IAClD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,+EAA+E;IAC/E,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oEAAoE;IACpE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,6CAA6C;IAC7C,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,2EAA2E;IAC3E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB,CAAC;AAGF,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EACpC,gBAA4B,EAC5B,SAAuB,EACvB,UAAgB,EAChB,WAAiB,EACjB,gBAAqB,EACrB,mBAAsC,EACtC,oBAA8C,EAC9C,kBAA6B,EAC7B,aAAoC,EACpC,UAAsB,EACtB,YAAwB,EACxB,QAAQ,GACT,EAAE,kBAAkB,2CA4IpB;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// file_description: Development lock screen layout component
|
|
2
|
+
// A simple centered layout for entering the dev lock password
|
|
3
|
+
// section: client_directive
|
|
4
|
+
"use client";
|
|
5
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
6
|
+
// section: imports
|
|
7
|
+
import { useState, useCallback } from "react";
|
|
8
|
+
import Image from "next/image";
|
|
9
|
+
import { Input } from "../../ui/input";
|
|
10
|
+
import { Button } from "../../ui/button";
|
|
11
|
+
import { Lock, AlertCircle, Loader2 } from "lucide-react";
|
|
12
|
+
// section: component
|
|
13
|
+
export default function DevLockLayout({ background_color = "#000000", logo_path = "/logo.png", logo_width = 120, logo_height = 120, application_name = "", limited_access_text = "Limited Access", password_placeholder = "Enter access password", submit_button_text = "Unlock", error_message = "Incorrect password", text_color = "#ffffff", accent_color = "#3b82f6", onUnlock, }) {
|
|
14
|
+
const [password, setPassword] = useState("");
|
|
15
|
+
const [error, setError] = useState(null);
|
|
16
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
17
|
+
const handleSubmit = useCallback(async (e) => {
|
|
18
|
+
e.preventDefault();
|
|
19
|
+
setError(null);
|
|
20
|
+
setIsLoading(true);
|
|
21
|
+
try {
|
|
22
|
+
const response = await fetch("/api/hazo_auth/dev_lock", {
|
|
23
|
+
method: "POST",
|
|
24
|
+
headers: { "Content-Type": "application/json" },
|
|
25
|
+
body: JSON.stringify({ password }),
|
|
26
|
+
});
|
|
27
|
+
if (response.ok) {
|
|
28
|
+
// Success - redirect to home or call onUnlock
|
|
29
|
+
if (onUnlock) {
|
|
30
|
+
onUnlock();
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
window.location.href = "/";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
setError(error_message);
|
|
38
|
+
setPassword("");
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch (_a) {
|
|
42
|
+
setError("An error occurred. Please try again.");
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
setIsLoading(false);
|
|
46
|
+
}
|
|
47
|
+
}, [password, error_message, onUnlock]);
|
|
48
|
+
const handlePasswordChange = useCallback((e) => {
|
|
49
|
+
setPassword(e.target.value);
|
|
50
|
+
// Clear error when user starts typing
|
|
51
|
+
if (error) {
|
|
52
|
+
setError(null);
|
|
53
|
+
}
|
|
54
|
+
}, [error]);
|
|
55
|
+
return (_jsx("div", { className: "cls_dev_lock_layout min-h-screen flex flex-col items-center justify-center p-4", style: { backgroundColor: background_color }, children: _jsxs("div", { className: "cls_dev_lock_container flex flex-col items-center gap-6 max-w-sm w-full", children: [_jsx("div", { className: "cls_dev_lock_logo", children: _jsx(Image, { src: logo_path, alt: "Application logo", width: logo_width, height: logo_height, className: "object-contain", priority: true }) }), application_name && (_jsx("h1", { className: "cls_dev_lock_app_name text-2xl font-bold text-center", style: { color: text_color }, children: application_name })), _jsxs("div", { className: "cls_dev_lock_header flex items-center gap-2", children: [_jsx(Lock, { className: "w-5 h-5", style: { color: text_color } }), _jsx("span", { className: "cls_dev_lock_text text-sm font-medium uppercase tracking-wider", style: { color: text_color, opacity: 0.8 }, children: limited_access_text })] }), _jsxs("form", { onSubmit: handleSubmit, className: "cls_dev_lock_form flex flex-col gap-4 w-full", children: [_jsx("div", { className: "cls_dev_lock_input_wrapper relative", children: _jsx(Input, { type: "password", value: password, onChange: handlePasswordChange, placeholder: password_placeholder, className: "cls_dev_lock_input h-12 bg-white/10 border-white/20 text-white placeholder:text-white/50 focus:border-white/40 focus:ring-white/20", disabled: isLoading, autoFocus: true, autoComplete: "current-password" }) }), error && (_jsxs("div", { className: "cls_dev_lock_error flex items-center gap-2 text-sm", style: { color: "#ef4444" }, children: [_jsx(AlertCircle, { className: "w-4 h-4 flex-shrink-0" }), _jsx("span", { children: error })] })), _jsx(Button, { type: "submit", className: "cls_dev_lock_button h-12 font-medium transition-colors", style: {
|
|
56
|
+
backgroundColor: accent_color,
|
|
57
|
+
color: "#ffffff",
|
|
58
|
+
}, disabled: isLoading || !password, children: isLoading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "w-4 h-4 animate-spin mr-2" }), "Verifying..."] })) : (submit_button_text) })] })] }) }));
|
|
59
|
+
}
|
|
60
|
+
export { DevLockLayout };
|
|
@@ -12,5 +12,7 @@ export { default as MySettingsLayout } from "./my_settings/index";
|
|
|
12
12
|
export type { MySettingsLayoutProps } from "./my_settings/index";
|
|
13
13
|
export { UserManagementLayout } from "./user_management/index";
|
|
14
14
|
export type { UserManagementLayoutProps } from "./user_management/index";
|
|
15
|
+
export { default as DevLockLayout } from "./dev_lock/index";
|
|
16
|
+
export type { DevLockLayoutProps } from "./dev_lock/index";
|
|
15
17
|
export * from "./shared/index";
|
|
16
18
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/layouts/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAC;AACvD,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC7D,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE5D,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC1E,YAAY,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAEzE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AACxE,YAAY,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAEvE,OAAO,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAChF,YAAY,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAE/E,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAClE,YAAY,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAEjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,YAAY,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/layouts/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAC;AACvD,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC7D,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE5D,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC1E,YAAY,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAEzE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AACxE,YAAY,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAEvE,OAAO,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAChF,YAAY,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAE/E,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAClE,YAAY,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAEjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,YAAY,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAEzE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC5D,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAG3D,cAAc,gBAAgB,CAAC"}
|
|
@@ -7,5 +7,6 @@ export { default as ResetPasswordLayout } from "./reset_password/index";
|
|
|
7
7
|
export { default as EmailVerificationLayout } from "./email_verification/index";
|
|
8
8
|
export { default as MySettingsLayout } from "./my_settings/index";
|
|
9
9
|
export { UserManagementLayout } from "./user_management/index";
|
|
10
|
+
export { default as DevLockLayout } from "./dev_lock/index";
|
|
10
11
|
// section: shared_exports
|
|
11
12
|
export * from "./shared/index";
|
|
@@ -97,10 +97,10 @@ export const use_login_form = ({ dataClient, logger, redirectRoute, successMessa
|
|
|
97
97
|
const logData = Object.assign({ filename: get_filename(), line_number: get_line_number(), email: values[LOGIN_FIELD_IDS.EMAIL], ip_address: clientIp, timestamp,
|
|
98
98
|
success }, (errorMessage ? { error_message: errorMessage } : {}));
|
|
99
99
|
if (success) {
|
|
100
|
-
logger.info("login_attempt_successful", logData);
|
|
100
|
+
logger === null || logger === void 0 ? void 0 : logger.info("login_attempt_successful", logData);
|
|
101
101
|
}
|
|
102
102
|
else {
|
|
103
|
-
logger.error("login_attempt_failed", logData);
|
|
103
|
+
logger === null || logger === void 0 ? void 0 : logger.error("login_attempt_failed", logData);
|
|
104
104
|
}
|
|
105
105
|
}, [logger, values, clientIp]);
|
|
106
106
|
const handleSubmit = useCallback(async (event) => {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type OrgManagementLayoutProps = {
|
|
2
|
+
className?: string;
|
|
3
|
+
/** Title displayed at the top */
|
|
4
|
+
title?: string;
|
|
5
|
+
/** Description displayed below the title */
|
|
6
|
+
description?: string;
|
|
7
|
+
/** Required permission for org management (default: hazo_perm_org_management) */
|
|
8
|
+
requiredPermission?: string;
|
|
9
|
+
/** Permission for global admin access (default: hazo_org_global_admin) */
|
|
10
|
+
globalAdminPermission?: string;
|
|
11
|
+
/** Message shown when authentication is required */
|
|
12
|
+
authRequiredMessage?: string;
|
|
13
|
+
/** Message shown when permission is denied */
|
|
14
|
+
permissionDeniedMessage?: string;
|
|
15
|
+
/** Message shown when multi-tenancy is disabled */
|
|
16
|
+
multiTenancyDisabledMessage?: string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Standalone Organization Management layout component
|
|
20
|
+
* Provides organization hierarchy management with CRUD operations
|
|
21
|
+
* @param props - Component props
|
|
22
|
+
* @returns Organization Management layout component
|
|
23
|
+
*/
|
|
24
|
+
export declare function OrgManagementLayout({ className, title, description, requiredPermission, globalAdminPermission, authRequiredMessage, permissionDeniedMessage, multiTenancyDisabledMessage, }: OrgManagementLayoutProps): import("react/jsx-runtime").JSX.Element;
|
|
25
|
+
export default OrgManagementLayout;
|
|
26
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/layouts/org_management/index.tsx"],"names":[],"mappings":"AAwBA,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,0EAA0E;IAC1E,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,oDAAoD;IACpD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,8CAA8C;IAC9C,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,mDAAmD;IACnD,2BAA2B,CAAC,EAAE,MAAM,CAAC;CACtC,CAAC;AAGF;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,SAAS,EACT,KAAiC,EACjC,WAAiE,EACjE,kBAA+C,EAC/C,qBAA+C,EAC/C,mBAAwE,EACxE,uBAA4F,EAC5F,2BAAkF,GACnF,EAAE,wBAAwB,2CAuH1B;AAED,eAAe,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// file_description: Standalone Organization Management layout component for managing multi-tenancy organizations
|
|
2
|
+
// section: client_directive
|
|
3
|
+
"use client";
|
|
4
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
5
|
+
// section: imports
|
|
6
|
+
import { useState, useEffect } from "react";
|
|
7
|
+
import { OrgHierarchyTab } from "../user_management/components/org_hierarchy_tab";
|
|
8
|
+
import { useHazoAuthConfig } from "../../../contexts/hazo_auth_provider";
|
|
9
|
+
import { use_hazo_auth } from "../shared/hooks/use_hazo_auth";
|
|
10
|
+
import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "../../ui/card";
|
|
11
|
+
import { Loader2, AlertCircle, Shield, Building2, } from "lucide-react";
|
|
12
|
+
// section: component
|
|
13
|
+
/**
|
|
14
|
+
* Standalone Organization Management layout component
|
|
15
|
+
* Provides organization hierarchy management with CRUD operations
|
|
16
|
+
* @param props - Component props
|
|
17
|
+
* @returns Organization Management layout component
|
|
18
|
+
*/
|
|
19
|
+
export function OrgManagementLayout({ className, title = "Organization Management", description = "Manage your organization hierarchy and structure.", requiredPermission = "hazo_perm_org_management", globalAdminPermission = "hazo_org_global_admin", authRequiredMessage = "Please log in to access organization management.", permissionDeniedMessage = "You need organization management permission to access this page.", multiTenancyDisabledMessage = "Multi-tenancy is not enabled in the configuration.", }) {
|
|
20
|
+
const { apiBasePath } = useHazoAuthConfig();
|
|
21
|
+
const authResult = use_hazo_auth();
|
|
22
|
+
const [multiTenancyEnabled, setMultiTenancyEnabled] = useState(null);
|
|
23
|
+
const [checkingMultiTenancy, setCheckingMultiTenancy] = useState(true);
|
|
24
|
+
// Check if multi-tenancy is enabled
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
const checkMultiTenancy = async () => {
|
|
27
|
+
try {
|
|
28
|
+
const response = await fetch(`${apiBasePath}/org_management/orgs?action=list`);
|
|
29
|
+
const data = await response.json();
|
|
30
|
+
if (data.code === "MULTI_TENANCY_DISABLED") {
|
|
31
|
+
setMultiTenancyEnabled(false);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
setMultiTenancyEnabled(true);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
// If we can't check, assume enabled and let the component handle it
|
|
39
|
+
setMultiTenancyEnabled(true);
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
setCheckingMultiTenancy(false);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
if (authResult.authenticated && authResult.permissions.includes(requiredPermission)) {
|
|
46
|
+
void checkMultiTenancy();
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
setCheckingMultiTenancy(false);
|
|
50
|
+
}
|
|
51
|
+
}, [apiBasePath, authResult.authenticated, authResult.permissions, requiredPermission]);
|
|
52
|
+
// Loading state
|
|
53
|
+
if (authResult.loading || checkingMultiTenancy) {
|
|
54
|
+
return (_jsx("div", { className: `cls_org_management_layout flex items-center justify-center p-8 ${className || ""}`, children: _jsx(Loader2, { className: "h-6 w-6 animate-spin text-slate-400" }) }));
|
|
55
|
+
}
|
|
56
|
+
// Not authenticated
|
|
57
|
+
if (!authResult.authenticated) {
|
|
58
|
+
return (_jsxs("div", { className: `cls_org_management_layout flex flex-col items-center justify-center p-8 gap-4 ${className || ""}`, children: [_jsx(AlertCircle, { className: "h-12 w-12 text-red-500" }), _jsx("h1", { className: "text-xl font-semibold", children: "Authentication Required" }), _jsx("p", { className: "text-muted-foreground text-center", children: authRequiredMessage })] }));
|
|
59
|
+
}
|
|
60
|
+
// Check required permission
|
|
61
|
+
const hasOrgManagementPermission = authResult.permissions.includes(requiredPermission);
|
|
62
|
+
if (!hasOrgManagementPermission) {
|
|
63
|
+
return (_jsxs("div", { className: `cls_org_management_layout flex flex-col items-center justify-center p-8 gap-4 ${className || ""}`, children: [_jsx(Shield, { className: "h-12 w-12 text-amber-500" }), _jsx("h1", { className: "text-xl font-semibold", children: "Access Denied" }), _jsx("p", { className: "text-muted-foreground text-center", children: permissionDeniedMessage }), _jsxs("p", { className: "text-xs text-muted-foreground", children: ["Required permission: ", _jsx("code", { className: "bg-muted px-1 py-0.5 rounded", children: requiredPermission })] })] }));
|
|
64
|
+
}
|
|
65
|
+
// Multi-tenancy disabled
|
|
66
|
+
if (multiTenancyEnabled === false) {
|
|
67
|
+
return (_jsxs("div", { className: `cls_org_management_layout flex flex-col items-center justify-center p-8 gap-4 ${className || ""}`, children: [_jsx(Building2, { className: "h-12 w-12 text-amber-500" }), _jsx("h1", { className: "text-xl font-semibold", children: "Multi-Tenancy Disabled" }), _jsx("p", { className: "text-muted-foreground text-center max-w-md", children: multiTenancyDisabledMessage }), _jsxs("p", { className: "text-xs text-muted-foreground text-center", children: ["Enable multi-tenancy by setting", " ", _jsx("code", { className: "bg-muted px-1 py-0.5 rounded", children: "enable_multi_tenancy = true" }), " in the", " ", _jsx("code", { className: "bg-muted px-1 py-0.5 rounded", children: "[hazo_auth__multi_tenancy]" }), " section."] })] }));
|
|
68
|
+
}
|
|
69
|
+
// Check global admin permission
|
|
70
|
+
const isGlobalAdmin = authResult.permissions.includes(globalAdminPermission);
|
|
71
|
+
return (_jsxs("div", { className: `cls_org_management_layout flex flex-col gap-6 p-4 w-full max-w-5xl mx-auto ${className || ""}`, children: [_jsxs("div", { className: "cls_org_management_header", children: [_jsxs("h1", { className: "text-2xl font-bold flex items-center gap-2", children: [_jsx(Building2, { className: "h-6 w-6" }), title] }), _jsx("p", { className: "text-muted-foreground", children: description })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { className: "text-lg", children: "Organization Hierarchy" }), _jsxs(CardDescription, { children: ["View and manage the organization structure.", isGlobalAdmin
|
|
72
|
+
? " As a global admin, you can see and manage all organizations."
|
|
73
|
+
: " You can manage organizations within your access scope."] })] }), _jsx(CardContent, { children: _jsx(OrgHierarchyTab, { isGlobalAdmin: isGlobalAdmin }) })] })] }));
|
|
74
|
+
}
|
|
75
|
+
export default OrgManagementLayout;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type OrgHierarchyTabProps = {
|
|
2
|
+
className?: string;
|
|
3
|
+
/** Whether the user has global admin permission (can see all orgs) */
|
|
4
|
+
isGlobalAdmin?: boolean;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Organization Hierarchy tab component for managing multi-tenancy organizations
|
|
8
|
+
* Displays organizations in a tree view for intuitive hierarchy configuration
|
|
9
|
+
* @param props - Component props
|
|
10
|
+
* @returns Organization Hierarchy tab component
|
|
11
|
+
*/
|
|
12
|
+
export declare function OrgHierarchyTab({ className, isGlobalAdmin, }: OrgHierarchyTabProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=org_hierarchy_tab.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"org_hierarchy_tab.d.ts","sourceRoot":"","sources":["../../../../../src/components/layouts/user_management/components/org_hierarchy_tab.tsx"],"names":[],"mappings":"AA6CA,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AA6GF;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAC9B,SAAS,EACT,aAAqB,GACtB,EAAE,oBAAoB,2CA0ftB"}
|