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.
Files changed (136) hide show
  1. package/bin/hazo_auth.mjs +35 -0
  2. package/cli-src/assets/images/forgot_password_default.jpg +0 -0
  3. package/cli-src/assets/images/login_default.jpg +0 -0
  4. package/cli-src/assets/images/register_default.jpg +0 -0
  5. package/cli-src/assets/images/reset_password_default.jpg +0 -0
  6. package/cli-src/assets/images/verify_email_default.jpg +0 -0
  7. package/cli-src/cli/generate.ts +276 -0
  8. package/cli-src/cli/index.ts +207 -0
  9. package/cli-src/cli/init.ts +254 -0
  10. package/cli-src/cli/init_users.ts +376 -0
  11. package/cli-src/cli/validate.ts +581 -0
  12. package/cli-src/lib/already_logged_in_config.server.ts +46 -0
  13. package/cli-src/lib/app_logger.ts +24 -0
  14. package/cli-src/lib/auth/auth_cache.ts +220 -0
  15. package/cli-src/lib/auth/auth_rate_limiter.ts +121 -0
  16. package/cli-src/lib/auth/auth_types.ts +117 -0
  17. package/cli-src/lib/auth/auth_utils.server.ts +196 -0
  18. package/cli-src/lib/auth/dev_lock_validator.edge.ts +171 -0
  19. package/cli-src/lib/auth/hazo_get_auth.server.ts +583 -0
  20. package/cli-src/lib/auth/index.ts +23 -0
  21. package/cli-src/lib/auth/nextauth_config.ts +227 -0
  22. package/cli-src/lib/auth/org_cache.ts +148 -0
  23. package/cli-src/lib/auth/scope_cache.ts +233 -0
  24. package/cli-src/lib/auth/server_auth.ts +88 -0
  25. package/cli-src/lib/auth/session_token_validator.edge.ts +92 -0
  26. package/cli-src/lib/auth_utility_config.server.ts +136 -0
  27. package/cli-src/lib/config/config_loader.server.ts +164 -0
  28. package/cli-src/lib/config/default_config.ts +243 -0
  29. package/cli-src/lib/dev_lock_config.server.ts +148 -0
  30. package/cli-src/lib/email_verification_config.server.ts +63 -0
  31. package/cli-src/lib/file_types_config.server.ts +25 -0
  32. package/cli-src/lib/forgot_password_config.server.ts +63 -0
  33. package/cli-src/lib/hazo_connect_instance.server.ts +101 -0
  34. package/cli-src/lib/hazo_connect_setup.server.ts +194 -0
  35. package/cli-src/lib/hazo_connect_setup.ts +54 -0
  36. package/cli-src/lib/index.ts +46 -0
  37. package/cli-src/lib/login_config.server.ts +106 -0
  38. package/cli-src/lib/messages_config.server.ts +45 -0
  39. package/cli-src/lib/migrations/apply_migration.ts +105 -0
  40. package/cli-src/lib/multi_tenancy_config.server.ts +94 -0
  41. package/cli-src/lib/my_settings_config.server.ts +135 -0
  42. package/cli-src/lib/oauth_config.server.ts +87 -0
  43. package/cli-src/lib/password_requirements_config.server.ts +40 -0
  44. package/cli-src/lib/profile_pic_menu_config.server.ts +138 -0
  45. package/cli-src/lib/profile_picture_config.server.ts +56 -0
  46. package/cli-src/lib/register_config.server.ts +101 -0
  47. package/cli-src/lib/reset_password_config.server.ts +103 -0
  48. package/cli-src/lib/scope_hierarchy_config.server.ts +151 -0
  49. package/cli-src/lib/services/email_service.ts +587 -0
  50. package/cli-src/lib/services/email_verification_service.ts +270 -0
  51. package/cli-src/lib/services/index.ts +16 -0
  52. package/cli-src/lib/services/login_service.ts +150 -0
  53. package/cli-src/lib/services/oauth_service.ts +494 -0
  54. package/cli-src/lib/services/org_service.ts +965 -0
  55. package/cli-src/lib/services/password_change_service.ts +154 -0
  56. package/cli-src/lib/services/password_reset_service.ts +418 -0
  57. package/cli-src/lib/services/profile_picture_remove_service.ts +120 -0
  58. package/cli-src/lib/services/profile_picture_service.ts +451 -0
  59. package/cli-src/lib/services/profile_picture_source_mapper.ts +62 -0
  60. package/cli-src/lib/services/registration_service.ts +185 -0
  61. package/cli-src/lib/services/scope_labels_service.ts +348 -0
  62. package/cli-src/lib/services/scope_service.ts +778 -0
  63. package/cli-src/lib/services/session_token_service.ts +178 -0
  64. package/cli-src/lib/services/token_service.ts +240 -0
  65. package/cli-src/lib/services/user_profiles_cache.ts +189 -0
  66. package/cli-src/lib/services/user_profiles_service.ts +264 -0
  67. package/cli-src/lib/services/user_scope_service.ts +554 -0
  68. package/cli-src/lib/services/user_update_service.ts +141 -0
  69. package/cli-src/lib/ui_shell_config.server.ts +73 -0
  70. package/cli-src/lib/ui_sizes_config.server.ts +37 -0
  71. package/cli-src/lib/user_fields_config.server.ts +31 -0
  72. package/cli-src/lib/user_management_config.server.ts +39 -0
  73. package/cli-src/lib/user_profiles_config.server.ts +55 -0
  74. package/cli-src/lib/utils/api_route_helpers.ts +60 -0
  75. package/cli-src/lib/utils/error_sanitizer.ts +75 -0
  76. package/cli-src/lib/utils/password_validator.ts +65 -0
  77. package/cli-src/lib/utils.ts +11 -0
  78. package/cli-src/server/logging/logger_service.ts +56 -0
  79. package/cli-src/server/types/app_types.ts +74 -0
  80. package/cli-src/server/types/express.d.ts +16 -0
  81. package/dist/cli/index.js +18 -0
  82. package/dist/cli/init_users.d.ts +17 -0
  83. package/dist/cli/init_users.d.ts.map +1 -0
  84. package/dist/cli/init_users.js +307 -0
  85. package/dist/components/layouts/dev_lock/index.d.ts +29 -0
  86. package/dist/components/layouts/dev_lock/index.d.ts.map +1 -0
  87. package/dist/components/layouts/dev_lock/index.js +60 -0
  88. package/dist/components/layouts/index.d.ts +2 -0
  89. package/dist/components/layouts/index.d.ts.map +1 -1
  90. package/dist/components/layouts/index.js +1 -0
  91. package/dist/components/layouts/org_management/index.d.ts +26 -0
  92. package/dist/components/layouts/org_management/index.d.ts.map +1 -0
  93. package/dist/components/layouts/org_management/index.js +75 -0
  94. package/dist/components/layouts/shared/config/layout_customization.d.ts +2 -7
  95. package/dist/components/layouts/shared/config/layout_customization.d.ts.map +1 -1
  96. package/dist/components/layouts/user_management/components/org_hierarchy_tab.d.ts +13 -0
  97. package/dist/components/layouts/user_management/components/org_hierarchy_tab.d.ts.map +1 -0
  98. package/dist/components/layouts/user_management/components/org_hierarchy_tab.js +276 -0
  99. package/dist/components/layouts/user_management/index.d.ts +3 -1
  100. package/dist/components/layouts/user_management/index.d.ts.map +1 -1
  101. package/dist/components/layouts/user_management/index.js +10 -4
  102. package/dist/lib/auth/auth_types.d.ts +6 -0
  103. package/dist/lib/auth/auth_types.d.ts.map +1 -1
  104. package/dist/lib/auth/dev_lock_validator.edge.d.ts +38 -0
  105. package/dist/lib/auth/dev_lock_validator.edge.d.ts.map +1 -0
  106. package/dist/lib/auth/dev_lock_validator.edge.js +122 -0
  107. package/dist/lib/auth/hazo_get_auth.server.d.ts.map +1 -1
  108. package/dist/lib/auth/hazo_get_auth.server.js +61 -1
  109. package/dist/lib/auth/org_cache.d.ts +65 -0
  110. package/dist/lib/auth/org_cache.d.ts.map +1 -0
  111. package/dist/lib/auth/org_cache.js +103 -0
  112. package/dist/lib/config/default_config.d.ts +76 -0
  113. package/dist/lib/config/default_config.d.ts.map +1 -1
  114. package/dist/lib/config/default_config.js +42 -0
  115. package/dist/lib/dev_lock_config.server.d.ts +41 -0
  116. package/dist/lib/dev_lock_config.server.d.ts.map +1 -0
  117. package/dist/lib/dev_lock_config.server.js +50 -0
  118. package/dist/lib/multi_tenancy_config.server.d.ts +30 -0
  119. package/dist/lib/multi_tenancy_config.server.d.ts.map +1 -0
  120. package/dist/lib/multi_tenancy_config.server.js +41 -0
  121. package/dist/lib/services/org_service.d.ts +191 -0
  122. package/dist/lib/services/org_service.d.ts.map +1 -0
  123. package/dist/lib/services/org_service.js +746 -0
  124. package/dist/lib/utils/password_validator.d.ts +7 -1
  125. package/dist/lib/utils/password_validator.d.ts.map +1 -1
  126. package/dist/page_components/dev_lock.d.ts +11 -0
  127. package/dist/page_components/dev_lock.d.ts.map +1 -0
  128. package/dist/page_components/dev_lock.js +17 -0
  129. package/dist/page_components/index.d.ts +1 -0
  130. package/dist/page_components/index.d.ts.map +1 -1
  131. package/dist/page_components/index.js +1 -0
  132. package/dist/page_components/org_management.d.ts +27 -0
  133. package/dist/page_components/org_management.d.ts.map +1 -0
  134. package/dist/page_components/org_management.js +18 -0
  135. package/hazo_auth_config.example.ini +30 -0
  136. package/package.json +27 -3
@@ -0,0 +1,148 @@
1
+ // file_description: server-only helper to read dev lock configuration from hazo_auth_config.ini
2
+ // section: imports
3
+ import { get_config_value, get_config_boolean, get_config_number } from "./config/config_loader.server.js";
4
+ import { DEFAULT_DEV_LOCK } from "./config/default_config.js";
5
+
6
+ // section: types
7
+ export type DevLockConfig = {
8
+ /** Enable the development lock screen */
9
+ enable: boolean;
10
+ /** Session duration in days */
11
+ session_duration_days: number;
12
+ /** Background color */
13
+ background_color: string;
14
+ /** Logo image path */
15
+ logo_path: string;
16
+ /** Logo width in pixels */
17
+ logo_width: number;
18
+ /** Logo height in pixels */
19
+ logo_height: number;
20
+ /** Application name displayed below logo */
21
+ application_name: string;
22
+ /** Limited access text displayed with lock icon */
23
+ limited_access_text: string;
24
+ /** Password input placeholder text */
25
+ password_placeholder: string;
26
+ /** Submit button text */
27
+ submit_button_text: string;
28
+ /** Error message for incorrect password */
29
+ error_message: string;
30
+ /** Text color for labels */
31
+ text_color: string;
32
+ /** Accent color for button */
33
+ accent_color: string;
34
+ };
35
+
36
+ // section: constants
37
+ const SECTION_NAME = "hazo_auth__dev_lock";
38
+
39
+ // section: helpers
40
+ /**
41
+ * Reads dev lock configuration from hazo_auth_config.ini file
42
+ * Falls back to defaults if hazo_auth_config.ini is not found or section is missing
43
+ * @returns Dev lock configuration options
44
+ */
45
+ export function get_dev_lock_config(): DevLockConfig {
46
+ const enable = get_config_boolean(
47
+ SECTION_NAME,
48
+ "enable",
49
+ DEFAULT_DEV_LOCK.enable
50
+ );
51
+
52
+ const session_duration_days = get_config_number(
53
+ SECTION_NAME,
54
+ "session_duration_days",
55
+ DEFAULT_DEV_LOCK.session_duration_days
56
+ );
57
+
58
+ const background_color = get_config_value(
59
+ SECTION_NAME,
60
+ "background_color",
61
+ DEFAULT_DEV_LOCK.background_color
62
+ );
63
+
64
+ const logo_path = get_config_value(
65
+ SECTION_NAME,
66
+ "logo_path",
67
+ DEFAULT_DEV_LOCK.logo_path
68
+ );
69
+
70
+ const logo_width = get_config_number(
71
+ SECTION_NAME,
72
+ "logo_width",
73
+ DEFAULT_DEV_LOCK.logo_width
74
+ );
75
+
76
+ const logo_height = get_config_number(
77
+ SECTION_NAME,
78
+ "logo_height",
79
+ DEFAULT_DEV_LOCK.logo_height
80
+ );
81
+
82
+ const application_name = get_config_value(
83
+ SECTION_NAME,
84
+ "application_name",
85
+ DEFAULT_DEV_LOCK.application_name
86
+ );
87
+
88
+ const limited_access_text = get_config_value(
89
+ SECTION_NAME,
90
+ "limited_access_text",
91
+ DEFAULT_DEV_LOCK.limited_access_text
92
+ );
93
+
94
+ const password_placeholder = get_config_value(
95
+ SECTION_NAME,
96
+ "password_placeholder",
97
+ DEFAULT_DEV_LOCK.password_placeholder
98
+ );
99
+
100
+ const submit_button_text = get_config_value(
101
+ SECTION_NAME,
102
+ "submit_button_text",
103
+ DEFAULT_DEV_LOCK.submit_button_text
104
+ );
105
+
106
+ const error_message = get_config_value(
107
+ SECTION_NAME,
108
+ "error_message",
109
+ DEFAULT_DEV_LOCK.error_message
110
+ );
111
+
112
+ const text_color = get_config_value(
113
+ SECTION_NAME,
114
+ "text_color",
115
+ DEFAULT_DEV_LOCK.text_color
116
+ );
117
+
118
+ const accent_color = get_config_value(
119
+ SECTION_NAME,
120
+ "accent_color",
121
+ DEFAULT_DEV_LOCK.accent_color
122
+ );
123
+
124
+ return {
125
+ enable,
126
+ session_duration_days,
127
+ background_color,
128
+ logo_path,
129
+ logo_width,
130
+ logo_height,
131
+ application_name,
132
+ limited_access_text,
133
+ password_placeholder,
134
+ submit_button_text,
135
+ error_message,
136
+ text_color,
137
+ accent_color,
138
+ };
139
+ }
140
+
141
+ /**
142
+ * Helper to check if dev lock is enabled in config
143
+ * Note: Also requires HAZO_AUTH_DEV_LOCK_ENABLED env var for actual enforcement
144
+ * @returns true if dev lock is enabled in config
145
+ */
146
+ export function is_dev_lock_enabled(): boolean {
147
+ return get_config_boolean(SECTION_NAME, "enable", DEFAULT_DEV_LOCK.enable);
148
+ }
@@ -0,0 +1,63 @@
1
+ // file_description: server-only helper to read email verification layout configuration from hazo_auth_config.ini
2
+ // section: imports
3
+ import { get_already_logged_in_config } from "./already_logged_in_config.server.js";
4
+ import { get_config_value } from "./config/config_loader.server.js";
5
+ import verifyEmailDefaultImage from "../assets/images/verify_email_default.jpg.js";
6
+
7
+ // section: types
8
+ import type { StaticImageData } from "next/image";
9
+
10
+ export type EmailVerificationConfig = {
11
+ alreadyLoggedInMessage: string;
12
+ showLogoutButton: boolean;
13
+ showReturnHomeButton: boolean;
14
+ returnHomeButtonLabel: string;
15
+ returnHomePath: string;
16
+ imageSrc: string | StaticImageData;
17
+ imageAlt: string;
18
+ imageBackgroundColor: string;
19
+ };
20
+
21
+ // section: helpers
22
+ /**
23
+ * Reads email verification layout configuration from hazo_auth_config.ini file
24
+ * Falls back to defaults if hazo_auth_config.ini is not found or section is missing
25
+ * @returns Email verification configuration options
26
+ */
27
+ export function get_email_verification_config(): EmailVerificationConfig {
28
+ const section = "hazo_auth__email_verification_layout";
29
+
30
+ // Get shared already logged in config
31
+ const alreadyLoggedInConfig = get_already_logged_in_config();
32
+
33
+ // Read image configuration
34
+ // If not set in config, falls back to default image from assets
35
+ const imageSrc = get_config_value(
36
+ section,
37
+ "image_src",
38
+ "" // Empty string means not set in config
39
+ ) || verifyEmailDefaultImage;
40
+
41
+ const imageAlt = get_config_value(
42
+ section,
43
+ "image_alt",
44
+ "Email verification illustration"
45
+ );
46
+ const imageBackgroundColor = get_config_value(
47
+ section,
48
+ "image_background_color",
49
+ "#f1f5f9"
50
+ );
51
+
52
+ return {
53
+ alreadyLoggedInMessage: alreadyLoggedInConfig.message,
54
+ showLogoutButton: alreadyLoggedInConfig.showLogoutButton,
55
+ showReturnHomeButton: alreadyLoggedInConfig.showReturnHomeButton,
56
+ returnHomeButtonLabel: alreadyLoggedInConfig.returnHomeButtonLabel,
57
+ returnHomePath: alreadyLoggedInConfig.returnHomePath,
58
+ imageSrc,
59
+ imageAlt,
60
+ imageBackgroundColor,
61
+ };
62
+ }
63
+
@@ -0,0 +1,25 @@
1
+ // file_description: server-only helper to read file type configuration from hazo_auth_config.ini
2
+ // section: imports
3
+ import { get_config_array } from "./config/config_loader.server.js";
4
+
5
+ // section: types
6
+ export type FileTypesConfig = {
7
+ allowed_image_extensions: string[];
8
+ allowed_image_mime_types: string[];
9
+ };
10
+
11
+ // section: helpers
12
+ /**
13
+ * Reads file type configuration from hazo_auth_config.ini file
14
+ * Falls back to defaults if hazo_auth_config.ini is not found or section is missing
15
+ * @returns File types configuration options
16
+ */
17
+ export function get_file_types_config(): FileTypesConfig {
18
+ const section = "hazo_auth__file_types";
19
+
20
+ return {
21
+ allowed_image_extensions: get_config_array(section, "allowed_image_extensions", ["jpg", "jpeg", "png"]),
22
+ allowed_image_mime_types: get_config_array(section, "allowed_image_mime_types", ["image/jpeg", "image/jpg", "image/png"]),
23
+ };
24
+ }
25
+
@@ -0,0 +1,63 @@
1
+ // file_description: server-only helper to read forgot password layout configuration from hazo_auth_config.ini
2
+ // section: imports
3
+ import { get_already_logged_in_config } from "./already_logged_in_config.server.js";
4
+ import { get_config_value } from "./config/config_loader.server.js";
5
+ import forgotPasswordDefaultImage from "../assets/images/forgot_password_default.jpg.js";
6
+
7
+ // section: types
8
+ import type { StaticImageData } from "next/image";
9
+
10
+ export type ForgotPasswordConfig = {
11
+ alreadyLoggedInMessage: string;
12
+ showLogoutButton: boolean;
13
+ showReturnHomeButton: boolean;
14
+ returnHomeButtonLabel: string;
15
+ returnHomePath: string;
16
+ imageSrc: string | StaticImageData;
17
+ imageAlt: string;
18
+ imageBackgroundColor: string;
19
+ };
20
+
21
+ // section: helpers
22
+ /**
23
+ * Reads forgot password layout configuration from hazo_auth_config.ini file
24
+ * Falls back to defaults if hazo_auth_config.ini is not found or section is missing
25
+ * @returns Forgot password configuration options
26
+ */
27
+ export function get_forgot_password_config(): ForgotPasswordConfig {
28
+ const section = "hazo_auth__forgot_password_layout";
29
+
30
+ // Get shared already logged in config
31
+ const alreadyLoggedInConfig = get_already_logged_in_config();
32
+
33
+ // Read image configuration
34
+ // If not set in config, falls back to default image from assets
35
+ const imageSrc = get_config_value(
36
+ section,
37
+ "image_src",
38
+ "" // Empty string means not set in config
39
+ ) || forgotPasswordDefaultImage;
40
+
41
+ const imageAlt = get_config_value(
42
+ section,
43
+ "image_alt",
44
+ "Password recovery illustration"
45
+ );
46
+ const imageBackgroundColor = get_config_value(
47
+ section,
48
+ "image_background_color",
49
+ "#f1f5f9"
50
+ );
51
+
52
+ return {
53
+ alreadyLoggedInMessage: alreadyLoggedInConfig.message,
54
+ showLogoutButton: alreadyLoggedInConfig.showLogoutButton,
55
+ showReturnHomeButton: alreadyLoggedInConfig.showReturnHomeButton,
56
+ returnHomeButtonLabel: alreadyLoggedInConfig.returnHomeButtonLabel,
57
+ returnHomePath: alreadyLoggedInConfig.returnHomePath,
58
+ imageSrc,
59
+ imageAlt,
60
+ imageBackgroundColor,
61
+ };
62
+ }
63
+
@@ -0,0 +1,101 @@
1
+ // file_description: singleton instance of hazo_connect adapter - initialized once and reused across all routes
2
+ // This ensures all routes/components use the same database connection
3
+ // Uses the new hazo_connect singleton API from hazo_connect/nextjs/setup
4
+ // Reads configuration from hazo_auth_config.ini using hazo_config
5
+ // section: imports
6
+ import type { HazoConnectAdapter } from "hazo_connect";
7
+ import { getHazoConnectSingleton } from "hazo_connect/nextjs/setup";
8
+ import { create_sqlite_hazo_connect_server, get_hazo_connect_config_options } from "./hazo_connect_setup.server.js";
9
+ import { initializeAdminService, getSqliteAdminService } from "hazo_connect/server";
10
+ import { create_app_logger } from "./app_logger.js";
11
+
12
+ // section: singleton_state
13
+ let hazoConnectInstance: HazoConnectAdapter | null = null;
14
+ let isInitialized = false;
15
+
16
+ // section: helpers
17
+ /**
18
+ * Gets or creates the singleton hazo_connect adapter instance
19
+ * This ensures all routes/components use the same database connection
20
+ *
21
+ * Uses the new hazo_connect singleton API which:
22
+ * - Automatically reuses the adapter instance
23
+ * - Automatically registers SQLite adapters with the admin service
24
+ * - Is thread-safe for Next.js serverless environments
25
+ * - Reads configuration from hazo_auth_config.ini using hazo_config (falls back to environment variables)
26
+ *
27
+ * Falls back to manual singleton if the new API is not available
28
+ *
29
+ * @returns The singleton HazoConnectAdapter instance
30
+ */
31
+ export function get_hazo_connect_instance(): HazoConnectAdapter {
32
+ // Use the new singleton API from hazo_connect
33
+ // This automatically handles:
34
+ // - Instance reuse
35
+ // - Admin service registration (via registerSqliteAdapter)
36
+ // - Thread-safety for Next.js serverless
37
+ // - Configuration from hazo_auth_config.ini (via hazo_config) or environment variables
38
+ try {
39
+ // Get configuration from hazo_auth_config.ini (falls back to environment variables)
40
+ const config_options = get_hazo_connect_config_options();
41
+ const logger = create_app_logger();
42
+ logger.debug("hazo_connect_singleton_attempt", {
43
+ filename: "hazo_connect_instance.server.ts",
44
+ line_number: 38,
45
+ config_options,
46
+ note: "Attempting to get singleton with these options",
47
+ });
48
+ return getHazoConnectSingleton(config_options);
49
+ } catch (error) {
50
+ const logger = create_app_logger();
51
+ const error_message = error instanceof Error ? error.message : "Unknown error";
52
+ logger.error("hazo_connect_singleton_failed", {
53
+ filename: "hazo_connect_instance.server.ts",
54
+ line_number: 45,
55
+ error: error_message,
56
+ error_stack: error instanceof Error ? error.stack : undefined,
57
+ note: "Falling back to manual singleton implementation",
58
+ });
59
+
60
+ // Fallback: Manual singleton implementation if new API fails
61
+ // This should not happen with the updated package, but kept for safety
62
+ if (!hazoConnectInstance) {
63
+ // Get config options to determine database type
64
+ const config_options = get_hazo_connect_config_options();
65
+ const db_type = config_options.type;
66
+
67
+ // Only initialize SQLite admin service for SQLite databases
68
+ if (db_type === "sqlite" && !isInitialized) {
69
+ initializeAdminService({ enable_admin_ui: true });
70
+ isInitialized = true;
71
+ }
72
+
73
+ // Create the adapter instance (reads from hazo_auth_config.ini)
74
+ // Note: Despite the name, this function supports both SQLite and PostgREST
75
+ hazoConnectInstance = create_sqlite_hazo_connect_server();
76
+
77
+ // Note: Database migrations should be applied manually via SQLite Admin UI
78
+ // or through a separate migration script. The token_service has fallback
79
+ // logic to work without the token_type column if migration hasn't been applied.
80
+
81
+ // Finalize initialization by getting the admin service (only for SQLite)
82
+ if (db_type === "sqlite") {
83
+ try {
84
+ getSqliteAdminService();
85
+ } catch (adminError) {
86
+ const logger = create_app_logger();
87
+ const error_message = adminError instanceof Error ? adminError.message : "Unknown error";
88
+ logger.warn("hazo_connect_instance_admin_service_init_failed", {
89
+ filename: "hazo_connect_instance.server.ts",
90
+ line_number: 0,
91
+ error: error_message,
92
+ note: "Could not get SqliteAdminService during initialization, continuing...",
93
+ });
94
+ }
95
+ }
96
+ }
97
+
98
+ return hazoConnectInstance;
99
+ }
100
+ }
101
+
@@ -0,0 +1,194 @@
1
+ // file_description: server-only helper to create hazo_connect instance (imports server-side code)
2
+ // This file should only be imported in server contexts (API routes, server components)
3
+ // Reads configuration from hazo_auth_config.ini using hazo_config
4
+ // section: imports
5
+ import { createHazoConnect } from "hazo_connect/server";
6
+ import { HazoConfig } from "hazo_config/dist/lib";
7
+ import path from "path";
8
+ import fs from "fs";
9
+ import { create_app_logger } from "./app_logger.js";
10
+ import { read_config_section } from "./config/config_loader.server.js";
11
+
12
+ // section: helpers
13
+ /**
14
+ * Reads hazo_connect configuration from hazo_auth_config.ini file
15
+ * Falls back to environment variables if hazo_auth_config.ini is not found or section is missing
16
+ * @returns Configuration options for hazo_connect
17
+ */
18
+ function get_hazo_connect_config(): {
19
+ type: "sqlite" | "postgrest";
20
+ sqlitePath?: string;
21
+ enableAdminUi: boolean;
22
+ readOnly?: boolean;
23
+ postgrestUrl?: string;
24
+ postgrestApiKey?: string;
25
+ } {
26
+ const default_config_path = path.resolve(process.cwd(), "hazo_auth_config.ini");
27
+ let hazo_connect_section: Record<string, string> | undefined;
28
+
29
+ // Try to read from hazo_auth_config.ini
30
+ const logger = create_app_logger();
31
+ hazo_connect_section = read_config_section("hazo_connect");
32
+
33
+ // Read type (defaults to sqlite)
34
+ const type = (
35
+ hazo_connect_section?.type ||
36
+ process.env.HAZO_CONNECT_TYPE ||
37
+ "sqlite"
38
+ ).toLowerCase() as "sqlite" | "postgrest";
39
+
40
+ // Read enable_admin_ui (defaults to true)
41
+ const enable_admin_ui_str =
42
+ hazo_connect_section?.enable_admin_ui ||
43
+ process.env.HAZO_CONNECT_ENABLE_ADMIN_UI ||
44
+ "true";
45
+ const enableAdminUi = enable_admin_ui_str.toLowerCase() === "true";
46
+
47
+ // Read read_only (defaults to false)
48
+ const read_only_str =
49
+ hazo_connect_section?.read_only ||
50
+ process.env.HAZO_CONNECT_SQLITE_READONLY ||
51
+ "false";
52
+ const readOnly = read_only_str.toLowerCase() === "true";
53
+
54
+ // SQLite configuration
55
+ if (type === "sqlite") {
56
+ const sqlite_path_config =
57
+ hazo_connect_section?.sqlite_path || process.env.HAZO_CONNECT_SQLITE_PATH;
58
+
59
+ let sqlite_path: string | undefined;
60
+
61
+ if (sqlite_path_config) {
62
+ // If path is absolute, use as-is; otherwise resolve relative to process.cwd()
63
+ sqlite_path = path.isAbsolute(sqlite_path_config)
64
+ ? sqlite_path_config
65
+ : path.resolve(process.cwd(), sqlite_path_config);
66
+
67
+ // Normalize the path to ensure consistency (resolves .., ., etc.)
68
+ sqlite_path = path.normalize(sqlite_path);
69
+ } else {
70
+ // Fallback to test fixture database
71
+ const fallback_sqlite_path = path.resolve(
72
+ process.cwd(),
73
+ "__tests__",
74
+ "fixtures",
75
+ "hazo_auth.sqlite"
76
+ );
77
+ sqlite_path = path.normalize(fallback_sqlite_path);
78
+ }
79
+
80
+ // Log the resolved path for debugging
81
+ logger.debug("hazo_connect_sqlite_path_resolved", {
82
+ filename: "hazo_connect_setup.server.ts",
83
+ line_number: 0,
84
+ sqlite_path,
85
+ process_cwd: process.cwd(),
86
+ config_source: hazo_connect_section ? "hazo_auth_config.ini" : "environment variables",
87
+ });
88
+
89
+ return {
90
+ type: "sqlite",
91
+ sqlitePath: sqlite_path,
92
+ enableAdminUi,
93
+ readOnly,
94
+ };
95
+ }
96
+
97
+ // PostgREST configuration
98
+ if (type === "postgrest") {
99
+ const postgrest_url =
100
+ hazo_connect_section?.postgrest_url ||
101
+ process.env.HAZO_CONNECT_POSTGREST_URL ||
102
+ process.env.POSTGREST_URL;
103
+ // API key must only come from environment variables for security
104
+ // Check multiple possible env var names for compatibility
105
+ const postgrest_api_key =
106
+ process.env.postgrest_api_key || // hazo_connect package expects this
107
+ process.env.HAZO_CONNECT_POSTGREST_API_KEY ||
108
+ process.env.POSTGREST_API_KEY;
109
+
110
+ if (!postgrest_url) {
111
+ throw new Error(
112
+ "PostgREST URL is required. Set postgrest_url in [hazo_connect] section of hazo_auth_config.ini or HAZO_CONNECT_POSTGREST_URL environment variable."
113
+ );
114
+ }
115
+
116
+ return {
117
+ type: "postgrest",
118
+ postgrestUrl: postgrest_url,
119
+ postgrestApiKey: postgrest_api_key,
120
+ enableAdminUi,
121
+ };
122
+ }
123
+
124
+ throw new Error(
125
+ `Unsupported HAZO_CONNECT_TYPE: ${type}. Supported types: sqlite, postgrest`
126
+ );
127
+ }
128
+
129
+ /**
130
+ * Server-only function to create hazo_connect adapter
131
+ * Reads configuration from hazo_auth_config.ini using hazo_config, falls back to environment variables
132
+ * This should only be called from server-side code (API routes, server components)
133
+ */
134
+ export function create_sqlite_hazo_connect_server() {
135
+ const config = get_hazo_connect_config();
136
+
137
+ if (config.type === "sqlite") {
138
+ return createHazoConnect({
139
+ type: "sqlite",
140
+ database: config.sqlitePath!,
141
+ enable_admin_ui: config.enableAdminUi,
142
+ });
143
+ }
144
+
145
+ if (config.type === "postgrest") {
146
+ // Ensure we have a value (empty string if not set, for PostgREST instances without auth)
147
+ const apiKey = config.postgrestApiKey || "";
148
+
149
+ return createHazoConnect({
150
+ type: "postgrest",
151
+ baseUrl: config.postgrestUrl!,
152
+ apiKey: apiKey, // Pass empty string if not set
153
+ });
154
+ }
155
+
156
+ throw new Error(`Unsupported database type: ${config.type}`);
157
+ }
158
+
159
+ /**
160
+ * Gets hazo_connect configuration options for use with singleton API
161
+ * Reads from hazo_auth_config.ini using hazo_config, falls back to environment variables
162
+ * @returns Configuration options compatible with getHazoConnectSingleton
163
+ */
164
+ export function get_hazo_connect_config_options(): {
165
+ type?: "sqlite" | "postgrest";
166
+ sqlitePath?: string;
167
+ enableAdminUi?: boolean;
168
+ readOnly?: boolean;
169
+ baseUrl?: string;
170
+ apiKey?: string;
171
+ } {
172
+ const config = get_hazo_connect_config();
173
+
174
+ if (config.type === "sqlite") {
175
+ return {
176
+ type: "sqlite",
177
+ sqlitePath: config.sqlitePath,
178
+ enableAdminUi: config.enableAdminUi,
179
+ readOnly: config.readOnly,
180
+ };
181
+ }
182
+
183
+ if (config.type === "postgrest") {
184
+ return {
185
+ type: "postgrest",
186
+ baseUrl: config.postgrestUrl, // Corrected from postgrestUrl
187
+ apiKey: config.postgrestApiKey || "", // Corrected from postgrestApiKey and ensured string value
188
+ };
189
+ }
190
+
191
+ // Fallback: return empty object to let it use environment variables
192
+ return {};
193
+ }
194
+
@@ -0,0 +1,54 @@
1
+ // file_description: helper function to create hazo_connect instance with configuration from environment variables
2
+ // This file provides a client-safe wrapper that returns a mock on client-side
3
+ // section: imports
4
+ // Note: We don't import server-side code here to avoid client-side bundling issues
5
+
6
+ // section: helpers
7
+ /**
8
+ * Creates a hazo_connect instance configured from environment variables
9
+ *
10
+ * Environment variables:
11
+ * - HAZO_CONNECT_TYPE: Database type ("sqlite" | "postgrest") - defaults to "sqlite"
12
+ * - HAZO_CONNECT_SQLITE_PATH: Path to SQLite database file (relative to process.cwd() or absolute)
13
+ * - HAZO_CONNECT_POSTGREST_URL: PostgREST API URL (for postgrest type)
14
+ * - HAZO_CONNECT_POSTGREST_API_KEY: PostgREST API key (for postgrest type)
15
+ *
16
+ * Falls back to test fixture database if HAZO_CONNECT_SQLITE_PATH is not set
17
+ *
18
+ * Note: For client-side usage (Next.js pages), this returns a mock adapter
19
+ * since SQLite cannot run in browser environments. Use PostgREST for client-side database access.
20
+ */
21
+ // Lazy loader for server module - prevents webpack from statically analyzing the require
22
+ function loadServerModule() {
23
+ // Use Function constructor to create a dynamic require that webpack can't analyze
24
+ // eslint-disable-next-line no-new-func
25
+ const requireFunc = new Function('modulePath', 'return require(modulePath)');
26
+ return requireFunc('./hazo_connect_setup.server');
27
+ }
28
+
29
+ export function create_sqlite_hazo_connect() {
30
+ // Check if we're in a browser/client environment
31
+ if (typeof window !== "undefined") {
32
+ // Return a mock adapter for client-side usage
33
+ return create_client_mock_hazo_connect();
34
+ }
35
+
36
+ // Server-side: dynamically load server module
37
+ // Using Function constructor prevents webpack from statically analyzing the require
38
+ const serverModule = loadServerModule();
39
+ return serverModule.create_sqlite_hazo_connect_server();
40
+ }
41
+
42
+ /**
43
+ * Creates a mock hazo_connect adapter for client-side usage
44
+ * This satisfies the LayoutDataClient interface without requiring SQLite
45
+ */
46
+ function create_client_mock_hazo_connect() {
47
+ return {
48
+ healthCheck: async () => {
49
+ // Mock health check for client-side - no-op
50
+ return Promise.resolve();
51
+ },
52
+ };
53
+ }
54
+