hazo_auth 4.2.0 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/hazo_auth.mjs +35 -0
- package/cli-src/assets/images/forgot_password_default.jpg +0 -0
- package/cli-src/assets/images/login_default.jpg +0 -0
- package/cli-src/assets/images/register_default.jpg +0 -0
- package/cli-src/assets/images/reset_password_default.jpg +0 -0
- package/cli-src/assets/images/verify_email_default.jpg +0 -0
- package/cli-src/cli/generate.ts +276 -0
- package/cli-src/cli/index.ts +207 -0
- package/cli-src/cli/init.ts +254 -0
- package/cli-src/cli/init_users.ts +376 -0
- package/cli-src/cli/validate.ts +581 -0
- package/cli-src/lib/already_logged_in_config.server.ts +46 -0
- package/cli-src/lib/app_logger.ts +24 -0
- package/cli-src/lib/auth/auth_cache.ts +220 -0
- package/cli-src/lib/auth/auth_rate_limiter.ts +121 -0
- package/cli-src/lib/auth/auth_types.ts +117 -0
- package/cli-src/lib/auth/auth_utils.server.ts +196 -0
- package/cli-src/lib/auth/dev_lock_validator.edge.ts +171 -0
- package/cli-src/lib/auth/hazo_get_auth.server.ts +583 -0
- package/cli-src/lib/auth/index.ts +23 -0
- package/cli-src/lib/auth/nextauth_config.ts +227 -0
- package/cli-src/lib/auth/org_cache.ts +148 -0
- package/cli-src/lib/auth/scope_cache.ts +233 -0
- package/cli-src/lib/auth/server_auth.ts +88 -0
- package/cli-src/lib/auth/session_token_validator.edge.ts +92 -0
- package/cli-src/lib/auth_utility_config.server.ts +136 -0
- package/cli-src/lib/config/config_loader.server.ts +164 -0
- package/cli-src/lib/config/default_config.ts +243 -0
- package/cli-src/lib/dev_lock_config.server.ts +148 -0
- package/cli-src/lib/email_verification_config.server.ts +63 -0
- package/cli-src/lib/file_types_config.server.ts +25 -0
- package/cli-src/lib/forgot_password_config.server.ts +63 -0
- package/cli-src/lib/hazo_connect_instance.server.ts +101 -0
- package/cli-src/lib/hazo_connect_setup.server.ts +194 -0
- package/cli-src/lib/hazo_connect_setup.ts +54 -0
- package/cli-src/lib/index.ts +46 -0
- package/cli-src/lib/login_config.server.ts +106 -0
- package/cli-src/lib/messages_config.server.ts +45 -0
- package/cli-src/lib/migrations/apply_migration.ts +105 -0
- package/cli-src/lib/multi_tenancy_config.server.ts +94 -0
- package/cli-src/lib/my_settings_config.server.ts +135 -0
- package/cli-src/lib/oauth_config.server.ts +87 -0
- package/cli-src/lib/password_requirements_config.server.ts +40 -0
- package/cli-src/lib/profile_pic_menu_config.server.ts +138 -0
- package/cli-src/lib/profile_picture_config.server.ts +56 -0
- package/cli-src/lib/register_config.server.ts +101 -0
- package/cli-src/lib/reset_password_config.server.ts +103 -0
- package/cli-src/lib/scope_hierarchy_config.server.ts +151 -0
- package/cli-src/lib/services/email_service.ts +587 -0
- package/cli-src/lib/services/email_verification_service.ts +270 -0
- package/cli-src/lib/services/index.ts +16 -0
- package/cli-src/lib/services/login_service.ts +150 -0
- package/cli-src/lib/services/oauth_service.ts +494 -0
- package/cli-src/lib/services/org_service.ts +965 -0
- package/cli-src/lib/services/password_change_service.ts +154 -0
- package/cli-src/lib/services/password_reset_service.ts +418 -0
- package/cli-src/lib/services/profile_picture_remove_service.ts +120 -0
- package/cli-src/lib/services/profile_picture_service.ts +451 -0
- package/cli-src/lib/services/profile_picture_source_mapper.ts +62 -0
- package/cli-src/lib/services/registration_service.ts +185 -0
- package/cli-src/lib/services/scope_labels_service.ts +348 -0
- package/cli-src/lib/services/scope_service.ts +778 -0
- package/cli-src/lib/services/session_token_service.ts +178 -0
- package/cli-src/lib/services/token_service.ts +240 -0
- package/cli-src/lib/services/user_profiles_cache.ts +189 -0
- package/cli-src/lib/services/user_profiles_service.ts +264 -0
- package/cli-src/lib/services/user_scope_service.ts +554 -0
- package/cli-src/lib/services/user_update_service.ts +141 -0
- package/cli-src/lib/ui_shell_config.server.ts +73 -0
- package/cli-src/lib/ui_sizes_config.server.ts +37 -0
- package/cli-src/lib/user_fields_config.server.ts +31 -0
- package/cli-src/lib/user_management_config.server.ts +39 -0
- package/cli-src/lib/user_profiles_config.server.ts +55 -0
- package/cli-src/lib/utils/api_route_helpers.ts +60 -0
- package/cli-src/lib/utils/error_sanitizer.ts +75 -0
- package/cli-src/lib/utils/password_validator.ts +65 -0
- package/cli-src/lib/utils.ts +11 -0
- package/cli-src/server/logging/logger_service.ts +56 -0
- package/cli-src/server/types/app_types.ts +74 -0
- package/cli-src/server/types/express.d.ts +16 -0
- package/dist/cli/index.js +18 -0
- package/dist/cli/init_users.d.ts +17 -0
- package/dist/cli/init_users.d.ts.map +1 -0
- package/dist/cli/init_users.js +307 -0
- package/dist/components/layouts/dev_lock/index.d.ts +29 -0
- package/dist/components/layouts/dev_lock/index.d.ts.map +1 -0
- package/dist/components/layouts/dev_lock/index.js +60 -0
- package/dist/components/layouts/index.d.ts +2 -0
- package/dist/components/layouts/index.d.ts.map +1 -1
- package/dist/components/layouts/index.js +1 -0
- package/dist/components/layouts/org_management/index.d.ts +26 -0
- package/dist/components/layouts/org_management/index.d.ts.map +1 -0
- package/dist/components/layouts/org_management/index.js +75 -0
- package/dist/components/layouts/shared/config/layout_customization.d.ts +2 -7
- package/dist/components/layouts/shared/config/layout_customization.d.ts.map +1 -1
- package/dist/components/layouts/user_management/components/org_hierarchy_tab.d.ts +13 -0
- package/dist/components/layouts/user_management/components/org_hierarchy_tab.d.ts.map +1 -0
- package/dist/components/layouts/user_management/components/org_hierarchy_tab.js +276 -0
- package/dist/components/layouts/user_management/index.d.ts +3 -1
- package/dist/components/layouts/user_management/index.d.ts.map +1 -1
- package/dist/components/layouts/user_management/index.js +10 -4
- package/dist/lib/auth/auth_types.d.ts +6 -0
- package/dist/lib/auth/auth_types.d.ts.map +1 -1
- package/dist/lib/auth/dev_lock_validator.edge.d.ts +38 -0
- package/dist/lib/auth/dev_lock_validator.edge.d.ts.map +1 -0
- package/dist/lib/auth/dev_lock_validator.edge.js +122 -0
- package/dist/lib/auth/hazo_get_auth.server.d.ts.map +1 -1
- package/dist/lib/auth/hazo_get_auth.server.js +61 -1
- package/dist/lib/auth/org_cache.d.ts +65 -0
- package/dist/lib/auth/org_cache.d.ts.map +1 -0
- package/dist/lib/auth/org_cache.js +103 -0
- package/dist/lib/config/default_config.d.ts +76 -0
- package/dist/lib/config/default_config.d.ts.map +1 -1
- package/dist/lib/config/default_config.js +42 -0
- package/dist/lib/dev_lock_config.server.d.ts +41 -0
- package/dist/lib/dev_lock_config.server.d.ts.map +1 -0
- package/dist/lib/dev_lock_config.server.js +50 -0
- package/dist/lib/multi_tenancy_config.server.d.ts +30 -0
- package/dist/lib/multi_tenancy_config.server.d.ts.map +1 -0
- package/dist/lib/multi_tenancy_config.server.js +41 -0
- package/dist/lib/services/org_service.d.ts +191 -0
- package/dist/lib/services/org_service.d.ts.map +1 -0
- package/dist/lib/services/org_service.js +746 -0
- package/dist/lib/utils/password_validator.d.ts +7 -1
- package/dist/lib/utils/password_validator.d.ts.map +1 -1
- package/dist/page_components/dev_lock.d.ts +11 -0
- package/dist/page_components/dev_lock.d.ts.map +1 -0
- package/dist/page_components/dev_lock.js +17 -0
- package/dist/page_components/index.d.ts +1 -0
- package/dist/page_components/index.d.ts.map +1 -1
- package/dist/page_components/index.js +1 -0
- package/dist/page_components/org_management.d.ts +27 -0
- package/dist/page_components/org_management.d.ts.map +1 -0
- package/dist/page_components/org_management.js +18 -0
- package/hazo_auth_config.example.ini +30 -0
- package/package.json +27 -3
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// file_description: barrel export for lib utilities
|
|
2
|
+
// section: auth_exports
|
|
3
|
+
export * from "./auth/index";
|
|
4
|
+
|
|
5
|
+
// section: service_exports
|
|
6
|
+
export * from "./services/index";
|
|
7
|
+
|
|
8
|
+
// section: utility_exports
|
|
9
|
+
export { cn, merge_class_names } from "./utils.js";
|
|
10
|
+
|
|
11
|
+
// section: config_exports
|
|
12
|
+
export { get_config_value, get_config_number, get_config_boolean, get_config_array, read_config_section } from "./config/config_loader.server.js";
|
|
13
|
+
|
|
14
|
+
// section: hazo_connect_exports
|
|
15
|
+
export { create_sqlite_hazo_connect } from "./hazo_connect_setup.js";
|
|
16
|
+
export { get_hazo_connect_instance } from "./hazo_connect_instance.server.js";
|
|
17
|
+
|
|
18
|
+
// section: logger_exports
|
|
19
|
+
export { create_app_logger } from "./app_logger.js";
|
|
20
|
+
|
|
21
|
+
// section: config_server_exports
|
|
22
|
+
export { get_login_config } from "./login_config.server.js";
|
|
23
|
+
export { get_register_config } from "./register_config.server.js";
|
|
24
|
+
export { get_forgot_password_config } from "./forgot_password_config.server.js";
|
|
25
|
+
export { get_reset_password_config } from "./reset_password_config.server.js";
|
|
26
|
+
export { get_email_verification_config } from "./email_verification_config.server.js";
|
|
27
|
+
export { get_my_settings_config } from "./my_settings_config.server.js";
|
|
28
|
+
export { get_user_management_config } from "./user_management_config.server.js";
|
|
29
|
+
export { get_profile_picture_config } from "./profile_picture_config.server.js";
|
|
30
|
+
export { get_profile_pic_menu_config } from "./profile_pic_menu_config.server.js";
|
|
31
|
+
export { get_already_logged_in_config } from "./already_logged_in_config.server.js";
|
|
32
|
+
export { get_ui_shell_config } from "./ui_shell_config.server.js";
|
|
33
|
+
export { get_ui_sizes_config } from "./ui_sizes_config.server.js";
|
|
34
|
+
export { get_auth_utility_config } from "./auth_utility_config.server.js";
|
|
35
|
+
export { get_password_requirements_config } from "./password_requirements_config.server.js";
|
|
36
|
+
export { get_messages_config } from "./messages_config.server.js";
|
|
37
|
+
export { get_user_fields_config } from "./user_fields_config.server.js";
|
|
38
|
+
export { get_file_types_config } from "./file_types_config.server.js";
|
|
39
|
+
export { get_oauth_config, is_google_oauth_enabled, is_email_password_enabled } from "./oauth_config.server.js";
|
|
40
|
+
export type { OAuthConfig } from "./oauth_config.server";
|
|
41
|
+
|
|
42
|
+
// section: util_exports
|
|
43
|
+
export { sanitize_error_for_user } from "./utils/error_sanitizer.js";
|
|
44
|
+
export type { ErrorSanitizationOptions } from "./utils/error_sanitizer";
|
|
45
|
+
export * from "./utils/api_route_helpers";
|
|
46
|
+
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// file_description: server-only helper to read login layout configuration from hazo_auth_config.ini
|
|
2
|
+
// section: imports
|
|
3
|
+
import { get_config_value } from "./config/config_loader.server.js";
|
|
4
|
+
import { get_already_logged_in_config } from "./already_logged_in_config.server.js";
|
|
5
|
+
import { get_oauth_config, type OAuthConfig } from "./oauth_config.server.js";
|
|
6
|
+
import loginDefaultImage from "../assets/images/login_default.jpg.js";
|
|
7
|
+
|
|
8
|
+
// section: types
|
|
9
|
+
import type { StaticImageData } from "next/image";
|
|
10
|
+
|
|
11
|
+
export type LoginConfig = {
|
|
12
|
+
redirectRoute?: string;
|
|
13
|
+
successMessage: string;
|
|
14
|
+
alreadyLoggedInMessage: string;
|
|
15
|
+
showLogoutButton: boolean;
|
|
16
|
+
showReturnHomeButton: boolean;
|
|
17
|
+
returnHomeButtonLabel: string;
|
|
18
|
+
returnHomePath: string;
|
|
19
|
+
forgotPasswordPath: string;
|
|
20
|
+
forgotPasswordLabel: string;
|
|
21
|
+
createAccountPath: string;
|
|
22
|
+
createAccountLabel: string;
|
|
23
|
+
imageSrc: string | StaticImageData;
|
|
24
|
+
imageAlt: string;
|
|
25
|
+
imageBackgroundColor: string;
|
|
26
|
+
/** OAuth configuration */
|
|
27
|
+
oauth: OAuthConfig;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// section: helpers
|
|
31
|
+
/**
|
|
32
|
+
* Reads login layout configuration from hazo_auth_config.ini file
|
|
33
|
+
* Falls back to defaults if hazo_auth_config.ini is not found or section is missing
|
|
34
|
+
* @returns Login configuration options
|
|
35
|
+
*/
|
|
36
|
+
export function get_login_config(): LoginConfig {
|
|
37
|
+
const section = "hazo_auth__login_layout";
|
|
38
|
+
|
|
39
|
+
// Read redirect route (optional)
|
|
40
|
+
const redirectRouteValue = get_config_value(section, "redirect_route_on_successful_login", "");
|
|
41
|
+
const redirectRoute = redirectRouteValue || undefined;
|
|
42
|
+
|
|
43
|
+
// Read success message (defaults to "Successfully logged in")
|
|
44
|
+
const successMessage = get_config_value(section, "success_message", "Successfully logged in");
|
|
45
|
+
|
|
46
|
+
const forgotPasswordPath = get_config_value(
|
|
47
|
+
section,
|
|
48
|
+
"forgot_password_path",
|
|
49
|
+
"/hazo_auth/forgot_password"
|
|
50
|
+
);
|
|
51
|
+
const forgotPasswordLabel = get_config_value(
|
|
52
|
+
section,
|
|
53
|
+
"forgot_password_label",
|
|
54
|
+
"Forgot password?"
|
|
55
|
+
);
|
|
56
|
+
const createAccountPath = get_config_value(section, "create_account_path", "/hazo_auth/register");
|
|
57
|
+
const createAccountLabel = get_config_value(
|
|
58
|
+
section,
|
|
59
|
+
"create_account_label",
|
|
60
|
+
"Create account"
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
// Get shared already logged in config
|
|
64
|
+
const alreadyLoggedInConfig = get_already_logged_in_config();
|
|
65
|
+
|
|
66
|
+
// Read image configuration
|
|
67
|
+
// If not set in config, falls back to default image from assets
|
|
68
|
+
const imageSrc = get_config_value(
|
|
69
|
+
section,
|
|
70
|
+
"image_src",
|
|
71
|
+
"" // Empty string means not set in config
|
|
72
|
+
) || loginDefaultImage;
|
|
73
|
+
|
|
74
|
+
const imageAlt = get_config_value(
|
|
75
|
+
section,
|
|
76
|
+
"image_alt",
|
|
77
|
+
"Secure login illustration"
|
|
78
|
+
);
|
|
79
|
+
const imageBackgroundColor = get_config_value(
|
|
80
|
+
section,
|
|
81
|
+
"image_background_color",
|
|
82
|
+
"#f1f5f9"
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
// Get OAuth configuration
|
|
86
|
+
const oauth = get_oauth_config();
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
redirectRoute,
|
|
90
|
+
successMessage,
|
|
91
|
+
alreadyLoggedInMessage: alreadyLoggedInConfig.message,
|
|
92
|
+
showLogoutButton: alreadyLoggedInConfig.showLogoutButton,
|
|
93
|
+
showReturnHomeButton: alreadyLoggedInConfig.showReturnHomeButton,
|
|
94
|
+
returnHomeButtonLabel: alreadyLoggedInConfig.returnHomeButtonLabel,
|
|
95
|
+
returnHomePath: alreadyLoggedInConfig.returnHomePath,
|
|
96
|
+
forgotPasswordPath,
|
|
97
|
+
forgotPasswordLabel,
|
|
98
|
+
createAccountPath,
|
|
99
|
+
createAccountLabel,
|
|
100
|
+
imageSrc,
|
|
101
|
+
imageAlt,
|
|
102
|
+
imageBackgroundColor,
|
|
103
|
+
oauth,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// file_description: server-only helper to read user-facing messages from hazo_auth_config.ini
|
|
2
|
+
// section: imports
|
|
3
|
+
import { get_config_value } from "./config/config_loader.server.js";
|
|
4
|
+
|
|
5
|
+
// section: types
|
|
6
|
+
export type MessagesConfig = {
|
|
7
|
+
photo_upload_disabled_message: string;
|
|
8
|
+
gravatar_setup_message: string;
|
|
9
|
+
gravatar_no_account_message: string;
|
|
10
|
+
library_tooltip_message: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
// section: helpers
|
|
14
|
+
/**
|
|
15
|
+
* Reads user-facing messages from hazo_auth_config.ini file
|
|
16
|
+
* Falls back to defaults if hazo_auth_config.ini is not found or section is missing
|
|
17
|
+
* @returns Messages configuration options
|
|
18
|
+
*/
|
|
19
|
+
export function get_messages_config(): MessagesConfig {
|
|
20
|
+
const section = "hazo_auth__messages";
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
photo_upload_disabled_message: get_config_value(
|
|
24
|
+
section,
|
|
25
|
+
"photo_upload_disabled_message",
|
|
26
|
+
"Photo upload is not enabled. Please contact your administrator."
|
|
27
|
+
),
|
|
28
|
+
gravatar_setup_message: get_config_value(
|
|
29
|
+
section,
|
|
30
|
+
"gravatar_setup_message",
|
|
31
|
+
"To set up your Gravatar:"
|
|
32
|
+
),
|
|
33
|
+
gravatar_no_account_message: get_config_value(
|
|
34
|
+
section,
|
|
35
|
+
"gravatar_no_account_message",
|
|
36
|
+
"You don't have a Gravatar account set up for this email address."
|
|
37
|
+
),
|
|
38
|
+
library_tooltip_message: get_config_value(
|
|
39
|
+
section,
|
|
40
|
+
"library_tooltip_message",
|
|
41
|
+
"Select another tab image style to remove this image"
|
|
42
|
+
),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// file_description: helper to apply database migrations using hazo_connect
|
|
2
|
+
// section: imports
|
|
3
|
+
import type { HazoConnectAdapter } from "hazo_connect";
|
|
4
|
+
import { createCrudService } from "hazo_connect/server";
|
|
5
|
+
import fs from "fs";
|
|
6
|
+
import path from "path";
|
|
7
|
+
|
|
8
|
+
// section: helpers
|
|
9
|
+
/**
|
|
10
|
+
* Applies a SQL migration file to the database
|
|
11
|
+
* For SQLite, we need to execute raw SQL statements
|
|
12
|
+
* @param adapter - The hazo_connect adapter instance
|
|
13
|
+
* @param migration_file_path - Path to the SQL migration file
|
|
14
|
+
* @returns Success status and error message if any
|
|
15
|
+
*/
|
|
16
|
+
export async function apply_migration(
|
|
17
|
+
adapter: HazoConnectAdapter,
|
|
18
|
+
migration_file_path: string,
|
|
19
|
+
): Promise<{ success: boolean; error?: string }> {
|
|
20
|
+
try {
|
|
21
|
+
// Read the migration file
|
|
22
|
+
const migration_sql = fs.readFileSync(migration_file_path, "utf-8");
|
|
23
|
+
|
|
24
|
+
// Split SQL statements by semicolon and execute each one
|
|
25
|
+
// Remove comments and empty statements
|
|
26
|
+
const statements = migration_sql
|
|
27
|
+
.split(";")
|
|
28
|
+
.map((stmt) => stmt.trim())
|
|
29
|
+
.filter((stmt) => stmt.length > 0 && !stmt.startsWith("--"));
|
|
30
|
+
|
|
31
|
+
// Execute each statement
|
|
32
|
+
// For SQLite via hazo_connect, we may need to use a raw query method
|
|
33
|
+
// Since hazo_connect doesn't expose raw SQL execution directly,
|
|
34
|
+
// we'll try to use the adapter's internal methods or skip migration
|
|
35
|
+
// and rely on the fallback in token_service
|
|
36
|
+
|
|
37
|
+
// For now, we'll log that migration should be applied manually
|
|
38
|
+
// The token_service has fallback logic to work without token_type column
|
|
39
|
+
if (process.env.NODE_ENV === "development") {
|
|
40
|
+
console.log(
|
|
41
|
+
`[migrations] Migration file found: ${migration_file_path}`,
|
|
42
|
+
"\n[migrations] Note: Raw SQL execution not available via hazo_connect adapter.",
|
|
43
|
+
"\n[migrations] Please apply migration manually or ensure token_type column exists."
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Try to check if token_type column already exists by querying the schema
|
|
48
|
+
// If it doesn't exist, we'll rely on the fallback in token_service
|
|
49
|
+
return { success: true };
|
|
50
|
+
} catch (error) {
|
|
51
|
+
const error_message =
|
|
52
|
+
error instanceof Error ? error.message : "Unknown error";
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
success: false,
|
|
56
|
+
error: error_message,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Applies all migrations in the migrations directory
|
|
63
|
+
* @param adapter - The hazo_connect adapter instance
|
|
64
|
+
* @returns Success status and error message if any
|
|
65
|
+
*/
|
|
66
|
+
export async function apply_all_migrations(
|
|
67
|
+
adapter: HazoConnectAdapter,
|
|
68
|
+
): Promise<{ success: boolean; error?: string }> {
|
|
69
|
+
try {
|
|
70
|
+
const migrations_dir = path.resolve(process.cwd(), "migrations");
|
|
71
|
+
|
|
72
|
+
if (!fs.existsSync(migrations_dir)) {
|
|
73
|
+
return { success: true }; // No migrations directory, nothing to apply
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Get all SQL files in migrations directory, sorted by name
|
|
77
|
+
const migration_files = fs
|
|
78
|
+
.readdirSync(migrations_dir)
|
|
79
|
+
.filter((file) => file.endsWith(".sql"))
|
|
80
|
+
.sort();
|
|
81
|
+
|
|
82
|
+
for (const migration_file of migration_files) {
|
|
83
|
+
const migration_path = path.join(migrations_dir, migration_file);
|
|
84
|
+
const result = await apply_migration(adapter, migration_path);
|
|
85
|
+
|
|
86
|
+
if (!result.success) {
|
|
87
|
+
return {
|
|
88
|
+
success: false,
|
|
89
|
+
error: `Failed to apply migration ${migration_file}: ${result.error}`,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return { success: true };
|
|
95
|
+
} catch (error) {
|
|
96
|
+
const error_message =
|
|
97
|
+
error instanceof Error ? error.message : "Unknown error";
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
success: false,
|
|
101
|
+
error: error_message,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// file_description: server-only helper to read multi-tenancy configuration from hazo_auth_config.ini
|
|
2
|
+
// section: imports
|
|
3
|
+
import {
|
|
4
|
+
get_config_value,
|
|
5
|
+
get_config_number,
|
|
6
|
+
get_config_boolean,
|
|
7
|
+
} from "./config/config_loader.server.js";
|
|
8
|
+
import { DEFAULT_MULTI_TENANCY } from "./config/default_config.js";
|
|
9
|
+
|
|
10
|
+
// section: types
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Multi-tenancy configuration options
|
|
14
|
+
*/
|
|
15
|
+
export type MultiTenancyConfig = {
|
|
16
|
+
/** Whether multi-tenancy is enabled (default: false) */
|
|
17
|
+
enable_multi_tenancy: boolean;
|
|
18
|
+
/** Cache TTL in minutes for org lookups (default: 15) */
|
|
19
|
+
org_cache_ttl_minutes: number;
|
|
20
|
+
/** Maximum entries in org cache (default: 1000) */
|
|
21
|
+
org_cache_max_entries: number;
|
|
22
|
+
/** Default user limit per organization (0 = unlimited) */
|
|
23
|
+
default_user_limit: number;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// section: constants
|
|
27
|
+
|
|
28
|
+
const SECTION_NAME = "hazo_auth__multi_tenancy";
|
|
29
|
+
|
|
30
|
+
// section: helpers
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Reads multi-tenancy configuration from hazo_auth_config.ini file
|
|
34
|
+
* Falls back to defaults if config file is not found or section is missing
|
|
35
|
+
* @returns Multi-tenancy configuration options
|
|
36
|
+
*/
|
|
37
|
+
export function get_multi_tenancy_config(): MultiTenancyConfig {
|
|
38
|
+
// Core multi-tenancy enablement
|
|
39
|
+
const enable_multi_tenancy = get_config_boolean(
|
|
40
|
+
SECTION_NAME,
|
|
41
|
+
"enable_multi_tenancy",
|
|
42
|
+
DEFAULT_MULTI_TENANCY.enable_multi_tenancy,
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
// Cache settings
|
|
46
|
+
const org_cache_ttl_minutes = get_config_number(
|
|
47
|
+
SECTION_NAME,
|
|
48
|
+
"org_cache_ttl_minutes",
|
|
49
|
+
DEFAULT_MULTI_TENANCY.org_cache_ttl_minutes,
|
|
50
|
+
);
|
|
51
|
+
const org_cache_max_entries = get_config_number(
|
|
52
|
+
SECTION_NAME,
|
|
53
|
+
"org_cache_max_entries",
|
|
54
|
+
DEFAULT_MULTI_TENANCY.org_cache_max_entries,
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
// Default user limit
|
|
58
|
+
const default_user_limit = get_config_number(
|
|
59
|
+
SECTION_NAME,
|
|
60
|
+
"default_user_limit",
|
|
61
|
+
DEFAULT_MULTI_TENANCY.default_user_limit,
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
enable_multi_tenancy,
|
|
66
|
+
org_cache_ttl_minutes,
|
|
67
|
+
org_cache_max_entries,
|
|
68
|
+
default_user_limit,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Checks if multi-tenancy is enabled in the configuration
|
|
74
|
+
* Convenience function for quick checks
|
|
75
|
+
*/
|
|
76
|
+
export function is_multi_tenancy_enabled(): boolean {
|
|
77
|
+
return get_config_boolean(
|
|
78
|
+
SECTION_NAME,
|
|
79
|
+
"enable_multi_tenancy",
|
|
80
|
+
DEFAULT_MULTI_TENANCY.enable_multi_tenancy,
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Gets the default user limit from config
|
|
86
|
+
* Returns 0 if not configured (unlimited)
|
|
87
|
+
*/
|
|
88
|
+
export function get_default_user_limit(): number {
|
|
89
|
+
return get_config_number(
|
|
90
|
+
SECTION_NAME,
|
|
91
|
+
"default_user_limit",
|
|
92
|
+
DEFAULT_MULTI_TENANCY.default_user_limit,
|
|
93
|
+
);
|
|
94
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// file_description: server-only helper to read my settings layout configuration from hazo_auth_config.ini
|
|
2
|
+
// section: imports
|
|
3
|
+
import { get_config_value } from "./config/config_loader.server.js";
|
|
4
|
+
import { get_user_fields_config } from "./user_fields_config.server.js";
|
|
5
|
+
import { get_password_requirements_config } from "./password_requirements_config.server.js";
|
|
6
|
+
import { get_profile_picture_config } from "./profile_picture_config.server.js";
|
|
7
|
+
import { get_messages_config } from "./messages_config.server.js";
|
|
8
|
+
import { get_ui_sizes_config } from "./ui_sizes_config.server.js";
|
|
9
|
+
import { get_file_types_config } from "./file_types_config.server.js";
|
|
10
|
+
|
|
11
|
+
// section: types
|
|
12
|
+
export type MySettingsConfig = {
|
|
13
|
+
userFields: {
|
|
14
|
+
show_name_field: boolean;
|
|
15
|
+
show_email_field: boolean;
|
|
16
|
+
show_password_field: boolean;
|
|
17
|
+
};
|
|
18
|
+
passwordRequirements: {
|
|
19
|
+
minimum_length: number;
|
|
20
|
+
require_uppercase: boolean;
|
|
21
|
+
require_lowercase: boolean;
|
|
22
|
+
require_number: boolean;
|
|
23
|
+
require_special: boolean;
|
|
24
|
+
};
|
|
25
|
+
profilePicture: {
|
|
26
|
+
allow_photo_upload: boolean;
|
|
27
|
+
upload_photo_path?: string;
|
|
28
|
+
max_photo_size: number;
|
|
29
|
+
user_photo_default: boolean;
|
|
30
|
+
user_photo_default_priority1: "gravatar" | "library";
|
|
31
|
+
user_photo_default_priority2?: "library" | "gravatar";
|
|
32
|
+
library_photo_path: string;
|
|
33
|
+
};
|
|
34
|
+
heading?: string;
|
|
35
|
+
subHeading?: string;
|
|
36
|
+
profilePhotoLabel?: string;
|
|
37
|
+
profilePhotoRecommendation?: string;
|
|
38
|
+
uploadPhotoButtonLabel?: string;
|
|
39
|
+
removePhotoButtonLabel?: string;
|
|
40
|
+
profileInformationLabel?: string;
|
|
41
|
+
passwordLabel?: string;
|
|
42
|
+
currentPasswordLabel?: string;
|
|
43
|
+
newPasswordLabel?: string;
|
|
44
|
+
confirmPasswordLabel?: string;
|
|
45
|
+
savePasswordButtonLabel?: string;
|
|
46
|
+
unauthorizedMessage?: string;
|
|
47
|
+
loginButtonLabel?: string;
|
|
48
|
+
loginPath?: string;
|
|
49
|
+
messages: {
|
|
50
|
+
photo_upload_disabled_message: string;
|
|
51
|
+
gravatar_setup_message: string;
|
|
52
|
+
gravatar_no_account_message: string;
|
|
53
|
+
library_tooltip_message: string;
|
|
54
|
+
};
|
|
55
|
+
uiSizes: {
|
|
56
|
+
gravatar_size: number;
|
|
57
|
+
profile_picture_size: number;
|
|
58
|
+
tooltip_icon_size_default: number;
|
|
59
|
+
tooltip_icon_size_small: number;
|
|
60
|
+
library_photo_grid_columns: number;
|
|
61
|
+
library_photo_preview_size: number;
|
|
62
|
+
image_compression_max_dimension: number;
|
|
63
|
+
upload_file_hard_limit_bytes: number;
|
|
64
|
+
};
|
|
65
|
+
fileTypes: {
|
|
66
|
+
allowed_image_extensions: string[];
|
|
67
|
+
allowed_image_mime_types: string[];
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// section: helpers
|
|
72
|
+
/**
|
|
73
|
+
* Reads my settings layout configuration from hazo_auth_config.ini file
|
|
74
|
+
* Falls back to defaults if hazo_auth_config.ini is not found or section is missing
|
|
75
|
+
* @returns My settings configuration options
|
|
76
|
+
*/
|
|
77
|
+
export function get_my_settings_config(): MySettingsConfig {
|
|
78
|
+
const section = "hazo_auth__my_settings_layout";
|
|
79
|
+
|
|
80
|
+
// Get shared user fields config
|
|
81
|
+
const userFields = get_user_fields_config();
|
|
82
|
+
|
|
83
|
+
// Get shared password requirements
|
|
84
|
+
const passwordRequirements = get_password_requirements_config();
|
|
85
|
+
|
|
86
|
+
// Get profile picture configuration
|
|
87
|
+
const profilePicture = get_profile_picture_config();
|
|
88
|
+
|
|
89
|
+
// Get messages, UI sizes, and file types configuration
|
|
90
|
+
const messages = get_messages_config();
|
|
91
|
+
const uiSizes = get_ui_sizes_config();
|
|
92
|
+
const fileTypes = get_file_types_config();
|
|
93
|
+
|
|
94
|
+
// Read optional labels with defaults
|
|
95
|
+
const heading = get_config_value(section, "heading", "Account Settings");
|
|
96
|
+
const subHeading = get_config_value(section, "sub_heading", "Manage your profile, password, and email preferences.");
|
|
97
|
+
const profilePhotoLabel = get_config_value(section, "profile_photo_label", "Profile Photo");
|
|
98
|
+
const profilePhotoRecommendation = get_config_value(section, "profile_photo_recommendation", "Recommended size: 200x200px. JPG, PNG.");
|
|
99
|
+
const uploadPhotoButtonLabel = get_config_value(section, "upload_photo_button_label", "Upload New Photo");
|
|
100
|
+
const removePhotoButtonLabel = get_config_value(section, "remove_photo_button_label", "Remove");
|
|
101
|
+
const profileInformationLabel = get_config_value(section, "profile_information_label", "Profile Information");
|
|
102
|
+
const passwordLabel = get_config_value(section, "password_label", "Password");
|
|
103
|
+
const currentPasswordLabel = get_config_value(section, "current_password_label", "Current Password");
|
|
104
|
+
const newPasswordLabel = get_config_value(section, "new_password_label", "New Password");
|
|
105
|
+
const confirmPasswordLabel = get_config_value(section, "confirm_password_label", "Confirm Password");
|
|
106
|
+
const savePasswordButtonLabel = get_config_value(section, "save_password_button_label", "Save Password");
|
|
107
|
+
const unauthorizedMessage = get_config_value(section, "unauthorized_message", "You must be logged in to access this page.");
|
|
108
|
+
const loginButtonLabel = get_config_value(section, "login_button_label", "Go to login");
|
|
109
|
+
const loginPath = get_config_value(section, "login_path", "/hazo_auth/login");
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
userFields,
|
|
113
|
+
passwordRequirements,
|
|
114
|
+
profilePicture,
|
|
115
|
+
heading,
|
|
116
|
+
subHeading,
|
|
117
|
+
profilePhotoLabel,
|
|
118
|
+
profilePhotoRecommendation,
|
|
119
|
+
uploadPhotoButtonLabel,
|
|
120
|
+
removePhotoButtonLabel,
|
|
121
|
+
profileInformationLabel,
|
|
122
|
+
passwordLabel,
|
|
123
|
+
currentPasswordLabel,
|
|
124
|
+
newPasswordLabel,
|
|
125
|
+
confirmPasswordLabel,
|
|
126
|
+
savePasswordButtonLabel,
|
|
127
|
+
unauthorizedMessage,
|
|
128
|
+
loginButtonLabel,
|
|
129
|
+
loginPath,
|
|
130
|
+
messages,
|
|
131
|
+
uiSizes,
|
|
132
|
+
fileTypes,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// file_description: server-only helper to read OAuth configuration from hazo_auth_config.ini
|
|
2
|
+
// section: imports
|
|
3
|
+
import { get_config_value, get_config_boolean } from "./config/config_loader.server.js";
|
|
4
|
+
import { DEFAULT_OAUTH } from "./config/default_config.js";
|
|
5
|
+
|
|
6
|
+
// section: types
|
|
7
|
+
export type OAuthConfig = {
|
|
8
|
+
/** Enable Google OAuth login */
|
|
9
|
+
enable_google: boolean;
|
|
10
|
+
/** Enable traditional email/password login */
|
|
11
|
+
enable_email_password: boolean;
|
|
12
|
+
/** Auto-link Google login to existing unverified email/password accounts */
|
|
13
|
+
auto_link_unverified_accounts: boolean;
|
|
14
|
+
/** Text displayed on the Google sign-in button */
|
|
15
|
+
google_button_text: string;
|
|
16
|
+
/** Text displayed on the divider between OAuth and email/password form */
|
|
17
|
+
oauth_divider_text: string;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// section: constants
|
|
21
|
+
const SECTION_NAME = "hazo_auth__oauth";
|
|
22
|
+
|
|
23
|
+
// section: helpers
|
|
24
|
+
/**
|
|
25
|
+
* Reads OAuth configuration from hazo_auth_config.ini file
|
|
26
|
+
* Falls back to defaults if hazo_auth_config.ini is not found or section is missing
|
|
27
|
+
* @returns OAuth configuration options
|
|
28
|
+
*/
|
|
29
|
+
export function get_oauth_config(): OAuthConfig {
|
|
30
|
+
const enable_google = get_config_boolean(
|
|
31
|
+
SECTION_NAME,
|
|
32
|
+
"enable_google",
|
|
33
|
+
DEFAULT_OAUTH.enable_google
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
const enable_email_password = get_config_boolean(
|
|
37
|
+
SECTION_NAME,
|
|
38
|
+
"enable_email_password",
|
|
39
|
+
DEFAULT_OAUTH.enable_email_password
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
const auto_link_unverified_accounts = get_config_boolean(
|
|
43
|
+
SECTION_NAME,
|
|
44
|
+
"auto_link_unverified_accounts",
|
|
45
|
+
DEFAULT_OAUTH.auto_link_unverified_accounts
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
const google_button_text = get_config_value(
|
|
49
|
+
SECTION_NAME,
|
|
50
|
+
"google_button_text",
|
|
51
|
+
DEFAULT_OAUTH.google_button_text
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
const oauth_divider_text = get_config_value(
|
|
55
|
+
SECTION_NAME,
|
|
56
|
+
"oauth_divider_text",
|
|
57
|
+
DEFAULT_OAUTH.oauth_divider_text
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
enable_google,
|
|
62
|
+
enable_email_password,
|
|
63
|
+
auto_link_unverified_accounts,
|
|
64
|
+
google_button_text,
|
|
65
|
+
oauth_divider_text,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Helper to check if Google OAuth is enabled
|
|
71
|
+
* @returns true if Google OAuth is enabled in config
|
|
72
|
+
*/
|
|
73
|
+
export function is_google_oauth_enabled(): boolean {
|
|
74
|
+
return get_config_boolean(SECTION_NAME, "enable_google", DEFAULT_OAUTH.enable_google);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Helper to check if email/password login is enabled
|
|
79
|
+
* @returns true if email/password login is enabled in config
|
|
80
|
+
*/
|
|
81
|
+
export function is_email_password_enabled(): boolean {
|
|
82
|
+
return get_config_boolean(
|
|
83
|
+
SECTION_NAME,
|
|
84
|
+
"enable_email_password",
|
|
85
|
+
DEFAULT_OAUTH.enable_email_password
|
|
86
|
+
);
|
|
87
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// file_description: server-only helper to read shared password requirements configuration from hazo_auth_config.ini
|
|
2
|
+
// section: imports
|
|
3
|
+
import { get_config_number, get_config_boolean } from "./config/config_loader.server.js";
|
|
4
|
+
import { DEFAULT_PASSWORD_REQUIREMENTS } from "./config/default_config.js";
|
|
5
|
+
|
|
6
|
+
// section: types
|
|
7
|
+
export type PasswordRequirementsConfig = {
|
|
8
|
+
minimum_length: number;
|
|
9
|
+
require_uppercase: boolean;
|
|
10
|
+
require_lowercase: boolean;
|
|
11
|
+
require_number: boolean;
|
|
12
|
+
require_special: boolean;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
// section: helpers
|
|
16
|
+
/**
|
|
17
|
+
* Reads shared password requirements configuration from hazo_auth_config.ini file
|
|
18
|
+
* Falls back to centralized defaults if hazo_auth_config.ini is not found or section is missing
|
|
19
|
+
* This configuration is used by both register and reset password layouts
|
|
20
|
+
* @returns Password requirements configuration options
|
|
21
|
+
*/
|
|
22
|
+
export function get_password_requirements_config(): PasswordRequirementsConfig {
|
|
23
|
+
const section = "hazo_auth__password_requirements";
|
|
24
|
+
|
|
25
|
+
// Read password requirements with centralized defaults
|
|
26
|
+
const minimum_length = get_config_number(section, "minimum_length", DEFAULT_PASSWORD_REQUIREMENTS.minimum_length);
|
|
27
|
+
const require_uppercase = get_config_boolean(section, "require_uppercase", DEFAULT_PASSWORD_REQUIREMENTS.require_uppercase);
|
|
28
|
+
const require_lowercase = get_config_boolean(section, "require_lowercase", DEFAULT_PASSWORD_REQUIREMENTS.require_lowercase);
|
|
29
|
+
const require_number = get_config_boolean(section, "require_number", DEFAULT_PASSWORD_REQUIREMENTS.require_number);
|
|
30
|
+
const require_special = get_config_boolean(section, "require_special", DEFAULT_PASSWORD_REQUIREMENTS.require_special);
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
minimum_length,
|
|
34
|
+
require_uppercase,
|
|
35
|
+
require_lowercase,
|
|
36
|
+
require_number,
|
|
37
|
+
require_special,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|