hazo_auth 4.3.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 (105) hide show
  1. package/cli-src/lib/already_logged_in_config.server.ts +1 -1
  2. package/cli-src/lib/app_logger.ts +1 -1
  3. package/cli-src/lib/auth/auth_types.ts +7 -0
  4. package/cli-src/lib/auth/auth_utils.server.ts +2 -2
  5. package/cli-src/lib/auth/dev_lock_validator.edge.ts +171 -0
  6. package/cli-src/lib/auth/hazo_get_auth.server.ts +84 -13
  7. package/cli-src/lib/auth/index.ts +5 -5
  8. package/cli-src/lib/auth/nextauth_config.ts +4 -4
  9. package/cli-src/lib/auth/org_cache.ts +148 -0
  10. package/cli-src/lib/auth/server_auth.ts +2 -2
  11. package/cli-src/lib/auth/session_token_validator.edge.ts +1 -0
  12. package/cli-src/lib/auth_utility_config.server.ts +1 -1
  13. package/cli-src/lib/config/config_loader.server.ts +1 -1
  14. package/cli-src/lib/config/default_config.ts +44 -0
  15. package/cli-src/lib/dev_lock_config.server.ts +148 -0
  16. package/cli-src/lib/email_verification_config.server.ts +3 -3
  17. package/cli-src/lib/file_types_config.server.ts +1 -1
  18. package/cli-src/lib/forgot_password_config.server.ts +3 -3
  19. package/cli-src/lib/hazo_connect_instance.server.ts +2 -2
  20. package/cli-src/lib/hazo_connect_setup.server.ts +2 -2
  21. package/cli-src/lib/index.ts +24 -24
  22. package/cli-src/lib/login_config.server.ts +4 -4
  23. package/cli-src/lib/messages_config.server.ts +1 -1
  24. package/cli-src/lib/multi_tenancy_config.server.ts +94 -0
  25. package/cli-src/lib/my_settings_config.server.ts +7 -7
  26. package/cli-src/lib/oauth_config.server.ts +2 -2
  27. package/cli-src/lib/password_requirements_config.server.ts +2 -2
  28. package/cli-src/lib/profile_pic_menu_config.server.ts +1 -1
  29. package/cli-src/lib/profile_picture_config.server.ts +2 -2
  30. package/cli-src/lib/register_config.server.ts +5 -5
  31. package/cli-src/lib/reset_password_config.server.ts +4 -4
  32. package/cli-src/lib/scope_hierarchy_config.server.ts +2 -2
  33. package/cli-src/lib/services/email_service.ts +2 -2
  34. package/cli-src/lib/services/email_verification_service.ts +3 -3
  35. package/cli-src/lib/services/login_service.ts +3 -3
  36. package/cli-src/lib/services/oauth_service.ts +4 -4
  37. package/cli-src/lib/services/org_service.ts +965 -0
  38. package/cli-src/lib/services/password_change_service.ts +3 -3
  39. package/cli-src/lib/services/password_reset_service.ts +3 -3
  40. package/cli-src/lib/services/profile_picture_remove_service.ts +3 -3
  41. package/cli-src/lib/services/profile_picture_service.ts +5 -5
  42. package/cli-src/lib/services/registration_service.ts +8 -8
  43. package/cli-src/lib/services/scope_labels_service.ts +3 -3
  44. package/cli-src/lib/services/scope_service.ts +2 -2
  45. package/cli-src/lib/services/session_token_service.ts +3 -2
  46. package/cli-src/lib/services/token_service.ts +2 -2
  47. package/cli-src/lib/services/user_profiles_service.ts +4 -4
  48. package/cli-src/lib/services/user_scope_service.ts +3 -3
  49. package/cli-src/lib/services/user_update_service.ts +4 -4
  50. package/cli-src/lib/ui_shell_config.server.ts +1 -1
  51. package/cli-src/lib/ui_sizes_config.server.ts +1 -1
  52. package/cli-src/lib/user_fields_config.server.ts +1 -1
  53. package/cli-src/lib/user_management_config.server.ts +1 -1
  54. package/cli-src/lib/user_profiles_config.server.ts +1 -1
  55. package/cli-src/lib/utils/error_sanitizer.ts +1 -1
  56. package/cli-src/server/types/app_types.ts +74 -0
  57. package/cli-src/server/types/express.d.ts +16 -0
  58. package/dist/components/layouts/dev_lock/index.d.ts +29 -0
  59. package/dist/components/layouts/dev_lock/index.d.ts.map +1 -0
  60. package/dist/components/layouts/dev_lock/index.js +60 -0
  61. package/dist/components/layouts/index.d.ts +2 -0
  62. package/dist/components/layouts/index.d.ts.map +1 -1
  63. package/dist/components/layouts/index.js +1 -0
  64. package/dist/components/layouts/org_management/index.d.ts +26 -0
  65. package/dist/components/layouts/org_management/index.d.ts.map +1 -0
  66. package/dist/components/layouts/org_management/index.js +75 -0
  67. package/dist/components/layouts/user_management/components/org_hierarchy_tab.d.ts +13 -0
  68. package/dist/components/layouts/user_management/components/org_hierarchy_tab.d.ts.map +1 -0
  69. package/dist/components/layouts/user_management/components/org_hierarchy_tab.js +276 -0
  70. package/dist/components/layouts/user_management/index.d.ts +3 -1
  71. package/dist/components/layouts/user_management/index.d.ts.map +1 -1
  72. package/dist/components/layouts/user_management/index.js +10 -4
  73. package/dist/lib/auth/auth_types.d.ts +6 -0
  74. package/dist/lib/auth/auth_types.d.ts.map +1 -1
  75. package/dist/lib/auth/dev_lock_validator.edge.d.ts +38 -0
  76. package/dist/lib/auth/dev_lock_validator.edge.d.ts.map +1 -0
  77. package/dist/lib/auth/dev_lock_validator.edge.js +122 -0
  78. package/dist/lib/auth/hazo_get_auth.server.d.ts.map +1 -1
  79. package/dist/lib/auth/hazo_get_auth.server.js +61 -1
  80. package/dist/lib/auth/org_cache.d.ts +65 -0
  81. package/dist/lib/auth/org_cache.d.ts.map +1 -0
  82. package/dist/lib/auth/org_cache.js +103 -0
  83. package/dist/lib/config/default_config.d.ts +76 -0
  84. package/dist/lib/config/default_config.d.ts.map +1 -1
  85. package/dist/lib/config/default_config.js +42 -0
  86. package/dist/lib/dev_lock_config.server.d.ts +41 -0
  87. package/dist/lib/dev_lock_config.server.d.ts.map +1 -0
  88. package/dist/lib/dev_lock_config.server.js +50 -0
  89. package/dist/lib/multi_tenancy_config.server.d.ts +30 -0
  90. package/dist/lib/multi_tenancy_config.server.d.ts.map +1 -0
  91. package/dist/lib/multi_tenancy_config.server.js +41 -0
  92. package/dist/lib/services/org_service.d.ts +191 -0
  93. package/dist/lib/services/org_service.d.ts.map +1 -0
  94. package/dist/lib/services/org_service.js +746 -0
  95. package/dist/page_components/dev_lock.d.ts +11 -0
  96. package/dist/page_components/dev_lock.d.ts.map +1 -0
  97. package/dist/page_components/dev_lock.js +17 -0
  98. package/dist/page_components/index.d.ts +1 -0
  99. package/dist/page_components/index.d.ts.map +1 -1
  100. package/dist/page_components/index.js +1 -0
  101. package/dist/page_components/org_management.d.ts +27 -0
  102. package/dist/page_components/org_management.d.ts.map +1 -0
  103. package/dist/page_components/org_management.js +18 -0
  104. package/hazo_auth_config.example.ini +30 -0
  105. package/package.json +23 -2
@@ -11,6 +11,8 @@ import { validate_session_token } from "../services/session_token_service";
11
11
  import { is_hrbac_enabled, get_scope_hierarchy_config } from "../scope_hierarchy_config.server";
12
12
  import { check_user_scope_access, get_user_scopes } from "../services/user_scope_service";
13
13
  import { is_valid_scope_level } from "../services/scope_service";
14
+ import { is_multi_tenancy_enabled, get_multi_tenancy_config } from "../multi_tenancy_config.server";
15
+ import { get_org_cache } from "./org_cache";
14
16
  // section: helpers
15
17
  /**
16
18
  * Gets client IP address from request
@@ -49,7 +51,7 @@ async function fetch_user_data_from_db(user_id) {
49
51
  if (user_db.is_active === false) {
50
52
  throw new Error("User is inactive");
51
53
  }
52
- // Build user object
54
+ // Build user object with base fields
53
55
  const user = {
54
56
  id: user_db.id,
55
57
  name: user_db.name || null,
@@ -57,6 +59,64 @@ async function fetch_user_data_from_db(user_id) {
57
59
  is_active: user_db.is_active === true,
58
60
  profile_picture_url: user_db.profile_picture_url || null,
59
61
  };
62
+ // Fetch org info if multi-tenancy is enabled and user has org_id
63
+ if (is_multi_tenancy_enabled() && user_db.org_id) {
64
+ const mt_config = get_multi_tenancy_config();
65
+ const org_cache = get_org_cache(mt_config.org_cache_max_entries, mt_config.org_cache_ttl_minutes);
66
+ const user_org_id = user_db.org_id;
67
+ // Check org cache first
68
+ let cached_org = org_cache.get(user_org_id);
69
+ if (!cached_org) {
70
+ // Fetch org info from database
71
+ const org_service = createCrudService(hazoConnect, "hazo_org");
72
+ const orgs = await org_service.findBy({ id: user_org_id });
73
+ if (Array.isArray(orgs) && orgs.length > 0) {
74
+ const org = orgs[0];
75
+ const org_entry = {
76
+ org_id: org.id,
77
+ org_name: org.name,
78
+ parent_org_id: org.parent_org_id || null,
79
+ parent_org_name: null,
80
+ root_org_id: org.root_org_id || null,
81
+ root_org_name: null,
82
+ };
83
+ // Fetch parent org name if exists
84
+ if (org_entry.parent_org_id) {
85
+ const parent_orgs = await org_service.findBy({ id: org_entry.parent_org_id });
86
+ if (Array.isArray(parent_orgs) && parent_orgs.length > 0) {
87
+ org_entry.parent_org_name = parent_orgs[0].name;
88
+ }
89
+ }
90
+ // Fetch root org name if exists
91
+ if (org_entry.root_org_id) {
92
+ const root_orgs = await org_service.findBy({ id: org_entry.root_org_id });
93
+ if (Array.isArray(root_orgs) && root_orgs.length > 0) {
94
+ org_entry.root_org_name = root_orgs[0].name;
95
+ }
96
+ }
97
+ else if (user_db.root_org_id) {
98
+ // Fallback to user's root_org_id if org doesn't have one
99
+ const root_orgs = await org_service.findBy({ id: user_db.root_org_id });
100
+ if (Array.isArray(root_orgs) && root_orgs.length > 0) {
101
+ org_entry.root_org_id = root_orgs[0].id;
102
+ org_entry.root_org_name = root_orgs[0].name;
103
+ }
104
+ }
105
+ // Cache the org info
106
+ org_cache.set(user_org_id, org_entry);
107
+ cached_org = org_entry;
108
+ }
109
+ }
110
+ // Add org info to user object
111
+ if (cached_org) {
112
+ user.org_id = cached_org.org_id;
113
+ user.org_name = cached_org.org_name;
114
+ user.parent_org_id = cached_org.parent_org_id;
115
+ user.parent_org_name = cached_org.parent_org_name;
116
+ user.root_org_id = cached_org.root_org_id;
117
+ user.root_org_name = cached_org.root_org_name;
118
+ }
119
+ }
60
120
  // Fetch user roles
61
121
  const user_roles = await user_roles_service.findBy({ user_id });
62
122
  const role_ids = [];
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Cached organization info for hazo_get_auth
3
+ */
4
+ export type OrgCacheEntry = {
5
+ org_id: string;
6
+ org_name: string;
7
+ parent_org_id: string | null;
8
+ parent_org_name: string | null;
9
+ root_org_id: string | null;
10
+ root_org_name: string | null;
11
+ };
12
+ /**
13
+ * LRU cache implementation for organization lookups
14
+ * Uses Map to maintain insertion order for LRU eviction
15
+ */
16
+ declare class OrgCache {
17
+ private cache;
18
+ private max_size;
19
+ private ttl_ms;
20
+ constructor(max_size: number, ttl_minutes: number);
21
+ /**
22
+ * Gets a cache entry for an organization
23
+ * Returns undefined if not found or expired
24
+ * @param org_id - Organization ID to look up
25
+ * @returns Cache entry or undefined
26
+ */
27
+ get(org_id: string): OrgCacheEntry | undefined;
28
+ /**
29
+ * Sets a cache entry for an organization
30
+ * Evicts least recently used entries if cache is full
31
+ * @param org_id - Organization ID
32
+ * @param entry - Organization cache entry
33
+ */
34
+ set(org_id: string, entry: OrgCacheEntry): void;
35
+ /**
36
+ * Invalidates cache for a specific organization
37
+ * @param org_id - Organization ID to invalidate
38
+ */
39
+ invalidate(org_id: string): void;
40
+ /**
41
+ * Invalidates all cache entries
42
+ */
43
+ invalidate_all(): void;
44
+ /**
45
+ * Gets cache statistics
46
+ * @returns Object with cache size and max size
47
+ */
48
+ get_stats(): {
49
+ size: number;
50
+ max_size: number;
51
+ };
52
+ }
53
+ /**
54
+ * Gets or creates the global org cache instance
55
+ * @param max_size - Maximum cache size (default: 1000)
56
+ * @param ttl_minutes - TTL in minutes (default: 15)
57
+ * @returns Org cache instance
58
+ */
59
+ export declare function get_org_cache(max_size?: number, ttl_minutes?: number): OrgCache;
60
+ /**
61
+ * Resets the global org cache instance (useful for testing)
62
+ */
63
+ export declare function reset_org_cache(): void;
64
+ export {};
65
+ //# sourceMappingURL=org_cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"org_cache.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/org_cache.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,CAAC;AAUF;;;GAGG;AACH,cAAM,QAAQ;IACZ,OAAO,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAS;gBAEX,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;IAMjD;;;;;OAKG;IACH,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAuB9C;;;;;OAKG;IACH,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI;IAmB/C;;;OAGG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAIhC;;OAEG;IACH,cAAc,IAAI,IAAI;IAItB;;;OAGG;IACH,SAAS,IAAI;QACX,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;KAClB;CAMF;AAMD;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,GAAE,MAAa,EACvB,WAAW,GAAE,MAAW,GACvB,QAAQ,CAKV;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAEtC"}
@@ -0,0 +1,103 @@
1
+ // file_description: LRU cache implementation for organization lookups with TTL and size limits
2
+ // section: types
3
+ /**
4
+ * LRU cache implementation for organization lookups
5
+ * Uses Map to maintain insertion order for LRU eviction
6
+ */
7
+ class OrgCache {
8
+ constructor(max_size, ttl_minutes) {
9
+ this.cache = new Map();
10
+ this.max_size = max_size;
11
+ this.ttl_ms = ttl_minutes * 60 * 1000;
12
+ }
13
+ /**
14
+ * Gets a cache entry for an organization
15
+ * Returns undefined if not found or expired
16
+ * @param org_id - Organization ID to look up
17
+ * @returns Cache entry or undefined
18
+ */
19
+ get(org_id) {
20
+ const item = this.cache.get(org_id);
21
+ if (!item) {
22
+ return undefined;
23
+ }
24
+ const now = Date.now();
25
+ const age = now - item.timestamp;
26
+ // Check if entry is expired (TTL)
27
+ if (age > this.ttl_ms) {
28
+ this.cache.delete(org_id);
29
+ return undefined;
30
+ }
31
+ // Move to end (most recently used)
32
+ this.cache.delete(org_id);
33
+ this.cache.set(org_id, item);
34
+ return item.entry;
35
+ }
36
+ /**
37
+ * Sets a cache entry for an organization
38
+ * Evicts least recently used entries if cache is full
39
+ * @param org_id - Organization ID
40
+ * @param entry - Organization cache entry
41
+ */
42
+ set(org_id, entry) {
43
+ // Evict LRU entries if cache is full
44
+ while (this.cache.size >= this.max_size) {
45
+ const first_key = this.cache.keys().next().value;
46
+ if (first_key) {
47
+ this.cache.delete(first_key);
48
+ }
49
+ else {
50
+ break;
51
+ }
52
+ }
53
+ const item = {
54
+ entry,
55
+ timestamp: Date.now(),
56
+ };
57
+ this.cache.set(org_id, item);
58
+ }
59
+ /**
60
+ * Invalidates cache for a specific organization
61
+ * @param org_id - Organization ID to invalidate
62
+ */
63
+ invalidate(org_id) {
64
+ this.cache.delete(org_id);
65
+ }
66
+ /**
67
+ * Invalidates all cache entries
68
+ */
69
+ invalidate_all() {
70
+ this.cache.clear();
71
+ }
72
+ /**
73
+ * Gets cache statistics
74
+ * @returns Object with cache size and max size
75
+ */
76
+ get_stats() {
77
+ return {
78
+ size: this.cache.size,
79
+ max_size: this.max_size,
80
+ };
81
+ }
82
+ }
83
+ // section: singleton
84
+ // Global org cache instance (initialized with defaults, will be configured on first use)
85
+ let org_cache_instance = null;
86
+ /**
87
+ * Gets or creates the global org cache instance
88
+ * @param max_size - Maximum cache size (default: 1000)
89
+ * @param ttl_minutes - TTL in minutes (default: 15)
90
+ * @returns Org cache instance
91
+ */
92
+ export function get_org_cache(max_size = 1000, ttl_minutes = 15) {
93
+ if (!org_cache_instance) {
94
+ org_cache_instance = new OrgCache(max_size, ttl_minutes);
95
+ }
96
+ return org_cache_instance;
97
+ }
98
+ /**
99
+ * Resets the global org cache instance (useful for testing)
100
+ */
101
+ export function reset_org_cache() {
102
+ org_cache_instance = null;
103
+ }
@@ -123,6 +123,44 @@ export declare const DEFAULT_OAUTH: {
123
123
  /** Text displayed on the divider between OAuth and email/password form */
124
124
  readonly oauth_divider_text: "or continue with email";
125
125
  };
126
+ export declare const DEFAULT_MULTI_TENANCY: {
127
+ /** Enable multi-tenancy support (default: false) */
128
+ readonly enable_multi_tenancy: false;
129
+ /** Cache TTL in minutes for org lookups (default: 15) */
130
+ readonly org_cache_ttl_minutes: 15;
131
+ /** Maximum entries in org cache (default: 1000) */
132
+ readonly org_cache_max_entries: 1000;
133
+ /** Default user limit per organization (0 = unlimited) */
134
+ readonly default_user_limit: 0;
135
+ };
136
+ export declare const DEFAULT_DEV_LOCK: {
137
+ /** Enable the development lock screen (also requires HAZO_AUTH_DEV_LOCK_ENABLED env var) */
138
+ readonly enable: false;
139
+ /** Session duration in days */
140
+ readonly session_duration_days: 7;
141
+ /** Background color (default: black) */
142
+ readonly background_color: "#000000";
143
+ /** Logo image path (default: /logo.png in public folder) */
144
+ readonly logo_path: "/logo.png";
145
+ /** Logo width in pixels */
146
+ readonly logo_width: 120;
147
+ /** Logo height in pixels */
148
+ readonly logo_height: 120;
149
+ /** Application name displayed below logo */
150
+ readonly application_name: "";
151
+ /** Limited access text displayed with lock icon */
152
+ readonly limited_access_text: "Limited Access";
153
+ /** Password input placeholder text */
154
+ readonly password_placeholder: "Enter access password";
155
+ /** Submit button text */
156
+ readonly submit_button_text: "Unlock";
157
+ /** Error message for incorrect password */
158
+ readonly error_message: "Incorrect password";
159
+ /** Text color for labels (default: white) */
160
+ readonly text_color: "#ffffff";
161
+ /** Accent color for button (default: blue) */
162
+ readonly accent_color: "#3b82f6";
163
+ };
126
164
  /**
127
165
  * All default configuration values combined in one object
128
166
  * This makes it easy to see all defaults at a glance and export them as needed
@@ -253,6 +291,44 @@ export declare const HAZO_AUTH_DEFAULTS: {
253
291
  /** Text displayed on the divider between OAuth and email/password form */
254
292
  readonly oauth_divider_text: "or continue with email";
255
293
  };
294
+ readonly devLock: {
295
+ /** Enable the development lock screen (also requires HAZO_AUTH_DEV_LOCK_ENABLED env var) */
296
+ readonly enable: false;
297
+ /** Session duration in days */
298
+ readonly session_duration_days: 7;
299
+ /** Background color (default: black) */
300
+ readonly background_color: "#000000";
301
+ /** Logo image path (default: /logo.png in public folder) */
302
+ readonly logo_path: "/logo.png";
303
+ /** Logo width in pixels */
304
+ readonly logo_width: 120;
305
+ /** Logo height in pixels */
306
+ readonly logo_height: 120;
307
+ /** Application name displayed below logo */
308
+ readonly application_name: "";
309
+ /** Limited access text displayed with lock icon */
310
+ readonly limited_access_text: "Limited Access";
311
+ /** Password input placeholder text */
312
+ readonly password_placeholder: "Enter access password";
313
+ /** Submit button text */
314
+ readonly submit_button_text: "Unlock";
315
+ /** Error message for incorrect password */
316
+ readonly error_message: "Incorrect password";
317
+ /** Text color for labels (default: white) */
318
+ readonly text_color: "#ffffff";
319
+ /** Accent color for button (default: blue) */
320
+ readonly accent_color: "#3b82f6";
321
+ };
322
+ readonly multiTenancy: {
323
+ /** Enable multi-tenancy support (default: false) */
324
+ readonly enable_multi_tenancy: false;
325
+ /** Cache TTL in minutes for org lookups (default: 15) */
326
+ readonly org_cache_ttl_minutes: 15;
327
+ /** Maximum entries in org cache (default: 1000) */
328
+ readonly org_cache_max_entries: 1000;
329
+ /** Default user limit per organization (0 = unlimited) */
330
+ readonly default_user_limit: 0;
331
+ };
256
332
  };
257
333
  /**
258
334
  * Type representing the complete default configuration structure
@@ -1 +1 @@
1
- {"version":3,"file":"default_config.d.ts","sourceRoot":"","sources":["../../../src/lib/config/default_config.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,6BAA6B;;;;;;CAMhC,CAAC;AAGX,eAAO,MAAM,mBAAmB;;;;CAItB,CAAC;AAGX,eAAO,MAAM,uBAAuB;;;;;;;CAO1B,CAAC;AAGX,eAAO,MAAM,gBAAgB;;;;;;;;;CASnB,CAAC;AAGX,eAAO,MAAM,kBAAkB;;;CAGrB,CAAC;AAGX,eAAO,MAAM,gBAAgB;;;;;CAKnB,CAAC;AAGX,eAAO,MAAM,yBAAyB;;;;;;CAM5B,CAAC;AAGX,eAAO,MAAM,aAAa;4BACI,MAAM,GAAG,SAAS;;;;;;CAMtC,CAAC;AAGX,eAAO,MAAM,gBAAgB;4BACC,MAAM,GAAG,SAAS;;;;;CAKtC,CAAC;AAGX,eAAO,MAAM,uBAAuB;;;;CAI1B,CAAC;AAGX,eAAO,MAAM,sBAAsB;;;;CAIzB,CAAC;AAGX,eAAO,MAAM,0BAA0B;;;;;CAK7B,CAAC;AAGX,eAAO,MAAM,mBAAmB;;;;;CAKtB,CAAC;AAGX,eAAO,MAAM,uBAAuB;;;;CAI1B,CAAC;AAGX,eAAO,MAAM,oBAAoB;;;;CAIvB,CAAC;AAGX,eAAO,MAAM,gBAAgB;0BACE,YAAY,GAAG,cAAc;;;;;CAKlD,CAAC;AAGX,eAAO,MAAM,wBAAwB;;;;;;;;CAQ3B,CAAC;AAGX,eAAO,MAAM,iBAAiB;;CAEpB,CAAC;AAGX,eAAO,MAAM,aAAa;IACxB,kHAAkH;;IAElH,8CAA8C;;IAE9C,iGAAiG;;IAEjG,kDAAkD;;IAElD,0EAA0E;;CAElE,CAAC;AAGX;;;GAGG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAzGD,MAAM,GAAG,SAAS;;;;;;;;gCAUlB,MAAM,GAAG,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BAqDjB,YAAY,GAAG,cAAc;;;;;;;;;;;;;;;;;;;QAyB1D,kHAAkH;;QAElH,8CAA8C;;QAE9C,iGAAiG;;QAEjG,kDAAkD;;QAElD,0EAA0E;;;CA6BlE,CAAC;AAGX;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,kBAAkB,CAAC"}
1
+ {"version":3,"file":"default_config.d.ts","sourceRoot":"","sources":["../../../src/lib/config/default_config.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,6BAA6B;;;;;;CAMhC,CAAC;AAGX,eAAO,MAAM,mBAAmB;;;;CAItB,CAAC;AAGX,eAAO,MAAM,uBAAuB;;;;;;;CAO1B,CAAC;AAGX,eAAO,MAAM,gBAAgB;;;;;;;;;CASnB,CAAC;AAGX,eAAO,MAAM,kBAAkB;;;CAGrB,CAAC;AAGX,eAAO,MAAM,gBAAgB;;;;;CAKnB,CAAC;AAGX,eAAO,MAAM,yBAAyB;;;;;;CAM5B,CAAC;AAGX,eAAO,MAAM,aAAa;4BACI,MAAM,GAAG,SAAS;;;;;;CAMtC,CAAC;AAGX,eAAO,MAAM,gBAAgB;4BACC,MAAM,GAAG,SAAS;;;;;CAKtC,CAAC;AAGX,eAAO,MAAM,uBAAuB;;;;CAI1B,CAAC;AAGX,eAAO,MAAM,sBAAsB;;;;CAIzB,CAAC;AAGX,eAAO,MAAM,0BAA0B;;;;;CAK7B,CAAC;AAGX,eAAO,MAAM,mBAAmB;;;;;CAKtB,CAAC;AAGX,eAAO,MAAM,uBAAuB;;;;CAI1B,CAAC;AAGX,eAAO,MAAM,oBAAoB;;;;CAIvB,CAAC;AAGX,eAAO,MAAM,gBAAgB;0BACE,YAAY,GAAG,cAAc;;;;;CAKlD,CAAC;AAGX,eAAO,MAAM,wBAAwB;;;;;;;;CAQ3B,CAAC;AAGX,eAAO,MAAM,iBAAiB;;CAEpB,CAAC;AAGX,eAAO,MAAM,aAAa;IACxB,kHAAkH;;IAElH,8CAA8C;;IAE9C,iGAAiG;;IAEjG,kDAAkD;;IAElD,0EAA0E;;CAElE,CAAC;AAGX,eAAO,MAAM,qBAAqB;IAChC,oDAAoD;;IAEpD,yDAAyD;;IAEzD,mDAAmD;;IAEnD,0DAA0D;;CAElD,CAAC;AAGX,eAAO,MAAM,gBAAgB;IAC3B,4FAA4F;;IAE5F,+BAA+B;;IAE/B,wCAAwC;;IAExC,4DAA4D;;IAE5D,2BAA2B;;IAE3B,4BAA4B;;IAE5B,4CAA4C;;IAE5C,mDAAmD;;IAEnD,sCAAsC;;IAEtC,yBAAyB;;IAEzB,2CAA2C;;IAE3C,6CAA6C;;IAE7C,8CAA8C;;CAEtC,CAAC;AAGX;;;GAGG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAnJD,MAAM,GAAG,SAAS;;;;;;;;gCAUlB,MAAM,GAAG,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BAqDjB,YAAY,GAAG,cAAc;;;;;;;;;;;;;;;;;;;QAyB1D,kHAAkH;;QAElH,8CAA8C;;QAE9C,iGAAiG;;QAEjG,kDAAkD;;QAElD,0EAA0E;;;;QAkB1E,4FAA4F;;QAE5F,+BAA+B;;QAE/B,wCAAwC;;QAExC,4DAA4D;;QAE5D,2BAA2B;;QAE3B,4BAA4B;;QAE5B,4CAA4C;;QAE5C,mDAAmD;;QAEnD,sCAAsC;;QAEtC,yBAAyB;;QAEzB,2CAA2C;;QAE3C,6CAA6C;;QAE7C,8CAA8C;;;;QApC9C,oDAAoD;;QAEpD,yDAAyD;;QAEzD,mDAAmD;;QAEnD,0DAA0D;;;CA6DlD,CAAC;AAGX;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,kBAAkB,CAAC"}
@@ -145,6 +145,46 @@ export const DEFAULT_OAUTH = {
145
145
  /** Text displayed on the divider between OAuth and email/password form */
146
146
  oauth_divider_text: "or continue with email",
147
147
  };
148
+ // section: multi_tenancy
149
+ export const DEFAULT_MULTI_TENANCY = {
150
+ /** Enable multi-tenancy support (default: false) */
151
+ enable_multi_tenancy: false,
152
+ /** Cache TTL in minutes for org lookups (default: 15) */
153
+ org_cache_ttl_minutes: 15,
154
+ /** Maximum entries in org cache (default: 1000) */
155
+ org_cache_max_entries: 1000,
156
+ /** Default user limit per organization (0 = unlimited) */
157
+ default_user_limit: 0,
158
+ };
159
+ // section: dev_lock
160
+ export const DEFAULT_DEV_LOCK = {
161
+ /** Enable the development lock screen (also requires HAZO_AUTH_DEV_LOCK_ENABLED env var) */
162
+ enable: false,
163
+ /** Session duration in days */
164
+ session_duration_days: 7,
165
+ /** Background color (default: black) */
166
+ background_color: "#000000",
167
+ /** Logo image path (default: /logo.png in public folder) */
168
+ logo_path: "/logo.png",
169
+ /** Logo width in pixels */
170
+ logo_width: 120,
171
+ /** Logo height in pixels */
172
+ logo_height: 120,
173
+ /** Application name displayed below logo */
174
+ application_name: "",
175
+ /** Limited access text displayed with lock icon */
176
+ limited_access_text: "Limited Access",
177
+ /** Password input placeholder text */
178
+ password_placeholder: "Enter access password",
179
+ /** Submit button text */
180
+ submit_button_text: "Unlock",
181
+ /** Error message for incorrect password */
182
+ error_message: "Incorrect password",
183
+ /** Text color for labels (default: white) */
184
+ text_color: "#ffffff",
185
+ /** Accent color for button (default: blue) */
186
+ accent_color: "#3b82f6",
187
+ };
148
188
  // section: combined_defaults
149
189
  /**
150
190
  * All default configuration values combined in one object
@@ -170,4 +210,6 @@ export const HAZO_AUTH_DEFAULTS = {
170
210
  profilePicMenu: DEFAULT_PROFILE_PIC_MENU,
171
211
  apiPaths: DEFAULT_API_PATHS,
172
212
  oauth: DEFAULT_OAUTH,
213
+ devLock: DEFAULT_DEV_LOCK,
214
+ multiTenancy: DEFAULT_MULTI_TENANCY,
173
215
  };
@@ -0,0 +1,41 @@
1
+ export type DevLockConfig = {
2
+ /** Enable the development lock screen */
3
+ enable: boolean;
4
+ /** Session duration in days */
5
+ session_duration_days: number;
6
+ /** Background color */
7
+ background_color: string;
8
+ /** Logo image path */
9
+ logo_path: string;
10
+ /** Logo width in pixels */
11
+ logo_width: number;
12
+ /** Logo height in pixels */
13
+ logo_height: number;
14
+ /** Application name displayed below logo */
15
+ application_name: string;
16
+ /** Limited access text displayed with lock icon */
17
+ limited_access_text: string;
18
+ /** Password input placeholder text */
19
+ password_placeholder: string;
20
+ /** Submit button text */
21
+ submit_button_text: string;
22
+ /** Error message for incorrect password */
23
+ error_message: string;
24
+ /** Text color for labels */
25
+ text_color: string;
26
+ /** Accent color for button */
27
+ accent_color: string;
28
+ };
29
+ /**
30
+ * Reads dev lock configuration from hazo_auth_config.ini file
31
+ * Falls back to defaults if hazo_auth_config.ini is not found or section is missing
32
+ * @returns Dev lock configuration options
33
+ */
34
+ export declare function get_dev_lock_config(): DevLockConfig;
35
+ /**
36
+ * Helper to check if dev lock is enabled in config
37
+ * Note: Also requires HAZO_AUTH_DEV_LOCK_ENABLED env var for actual enforcement
38
+ * @returns true if dev lock is enabled in config
39
+ */
40
+ export declare function is_dev_lock_enabled(): boolean;
41
+ //# sourceMappingURL=dev_lock_config.server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev_lock_config.server.d.ts","sourceRoot":"","sources":["../../src/lib/dev_lock_config.server.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,aAAa,GAAG;IAC1B,yCAAyC;IACzC,MAAM,EAAE,OAAO,CAAC;IAChB,+BAA+B;IAC/B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,uBAAuB;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,2BAA2B;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,gBAAgB,EAAE,MAAM,CAAC;IACzB,mDAAmD;IACnD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,sCAAsC;IACtC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,yBAAyB;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,2CAA2C;IAC3C,aAAa,EAAE,MAAM,CAAC;IACtB,4BAA4B;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAMF;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,aAAa,CA8FnD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C"}
@@ -0,0 +1,50 @@
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";
4
+ import { DEFAULT_DEV_LOCK } from "./config/default_config";
5
+ // section: constants
6
+ const SECTION_NAME = "hazo_auth__dev_lock";
7
+ // section: helpers
8
+ /**
9
+ * Reads dev lock configuration from hazo_auth_config.ini file
10
+ * Falls back to defaults if hazo_auth_config.ini is not found or section is missing
11
+ * @returns Dev lock configuration options
12
+ */
13
+ export function get_dev_lock_config() {
14
+ const enable = get_config_boolean(SECTION_NAME, "enable", DEFAULT_DEV_LOCK.enable);
15
+ const session_duration_days = get_config_number(SECTION_NAME, "session_duration_days", DEFAULT_DEV_LOCK.session_duration_days);
16
+ const background_color = get_config_value(SECTION_NAME, "background_color", DEFAULT_DEV_LOCK.background_color);
17
+ const logo_path = get_config_value(SECTION_NAME, "logo_path", DEFAULT_DEV_LOCK.logo_path);
18
+ const logo_width = get_config_number(SECTION_NAME, "logo_width", DEFAULT_DEV_LOCK.logo_width);
19
+ const logo_height = get_config_number(SECTION_NAME, "logo_height", DEFAULT_DEV_LOCK.logo_height);
20
+ const application_name = get_config_value(SECTION_NAME, "application_name", DEFAULT_DEV_LOCK.application_name);
21
+ const limited_access_text = get_config_value(SECTION_NAME, "limited_access_text", DEFAULT_DEV_LOCK.limited_access_text);
22
+ const password_placeholder = get_config_value(SECTION_NAME, "password_placeholder", DEFAULT_DEV_LOCK.password_placeholder);
23
+ const submit_button_text = get_config_value(SECTION_NAME, "submit_button_text", DEFAULT_DEV_LOCK.submit_button_text);
24
+ const error_message = get_config_value(SECTION_NAME, "error_message", DEFAULT_DEV_LOCK.error_message);
25
+ const text_color = get_config_value(SECTION_NAME, "text_color", DEFAULT_DEV_LOCK.text_color);
26
+ const accent_color = get_config_value(SECTION_NAME, "accent_color", DEFAULT_DEV_LOCK.accent_color);
27
+ return {
28
+ enable,
29
+ session_duration_days,
30
+ background_color,
31
+ logo_path,
32
+ logo_width,
33
+ logo_height,
34
+ application_name,
35
+ limited_access_text,
36
+ password_placeholder,
37
+ submit_button_text,
38
+ error_message,
39
+ text_color,
40
+ accent_color,
41
+ };
42
+ }
43
+ /**
44
+ * Helper to check if dev lock is enabled in config
45
+ * Note: Also requires HAZO_AUTH_DEV_LOCK_ENABLED env var for actual enforcement
46
+ * @returns true if dev lock is enabled in config
47
+ */
48
+ export function is_dev_lock_enabled() {
49
+ return get_config_boolean(SECTION_NAME, "enable", DEFAULT_DEV_LOCK.enable);
50
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Multi-tenancy configuration options
3
+ */
4
+ export type MultiTenancyConfig = {
5
+ /** Whether multi-tenancy is enabled (default: false) */
6
+ enable_multi_tenancy: boolean;
7
+ /** Cache TTL in minutes for org lookups (default: 15) */
8
+ org_cache_ttl_minutes: number;
9
+ /** Maximum entries in org cache (default: 1000) */
10
+ org_cache_max_entries: number;
11
+ /** Default user limit per organization (0 = unlimited) */
12
+ default_user_limit: number;
13
+ };
14
+ /**
15
+ * Reads multi-tenancy configuration from hazo_auth_config.ini file
16
+ * Falls back to defaults if config file is not found or section is missing
17
+ * @returns Multi-tenancy configuration options
18
+ */
19
+ export declare function get_multi_tenancy_config(): MultiTenancyConfig;
20
+ /**
21
+ * Checks if multi-tenancy is enabled in the configuration
22
+ * Convenience function for quick checks
23
+ */
24
+ export declare function is_multi_tenancy_enabled(): boolean;
25
+ /**
26
+ * Gets the default user limit from config
27
+ * Returns 0 if not configured (unlimited)
28
+ */
29
+ export declare function get_default_user_limit(): number;
30
+ //# sourceMappingURL=multi_tenancy_config.server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multi_tenancy_config.server.d.ts","sourceRoot":"","sources":["../../src/lib/multi_tenancy_config.server.ts"],"names":[],"mappings":"AAWA;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,wDAAwD;IACxD,oBAAoB,EAAE,OAAO,CAAC;IAC9B,yDAAyD;IACzD,qBAAqB,EAAE,MAAM,CAAC;IAC9B,mDAAmD;IACnD,qBAAqB,EAAE,MAAM,CAAC;IAC9B,0DAA0D;IAC1D,kBAAkB,EAAE,MAAM,CAAC;CAC5B,CAAC;AAQF;;;;GAIG;AACH,wBAAgB,wBAAwB,IAAI,kBAAkB,CAiC7D;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,OAAO,CAMlD;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAM/C"}
@@ -0,0 +1,41 @@
1
+ // file_description: server-only helper to read multi-tenancy configuration from hazo_auth_config.ini
2
+ // section: imports
3
+ import { get_config_number, get_config_boolean, } from "./config/config_loader.server";
4
+ import { DEFAULT_MULTI_TENANCY } from "./config/default_config";
5
+ // section: constants
6
+ const SECTION_NAME = "hazo_auth__multi_tenancy";
7
+ // section: helpers
8
+ /**
9
+ * Reads multi-tenancy configuration from hazo_auth_config.ini file
10
+ * Falls back to defaults if config file is not found or section is missing
11
+ * @returns Multi-tenancy configuration options
12
+ */
13
+ export function get_multi_tenancy_config() {
14
+ // Core multi-tenancy enablement
15
+ const enable_multi_tenancy = get_config_boolean(SECTION_NAME, "enable_multi_tenancy", DEFAULT_MULTI_TENANCY.enable_multi_tenancy);
16
+ // Cache settings
17
+ const org_cache_ttl_minutes = get_config_number(SECTION_NAME, "org_cache_ttl_minutes", DEFAULT_MULTI_TENANCY.org_cache_ttl_minutes);
18
+ const org_cache_max_entries = get_config_number(SECTION_NAME, "org_cache_max_entries", DEFAULT_MULTI_TENANCY.org_cache_max_entries);
19
+ // Default user limit
20
+ const default_user_limit = get_config_number(SECTION_NAME, "default_user_limit", DEFAULT_MULTI_TENANCY.default_user_limit);
21
+ return {
22
+ enable_multi_tenancy,
23
+ org_cache_ttl_minutes,
24
+ org_cache_max_entries,
25
+ default_user_limit,
26
+ };
27
+ }
28
+ /**
29
+ * Checks if multi-tenancy is enabled in the configuration
30
+ * Convenience function for quick checks
31
+ */
32
+ export function is_multi_tenancy_enabled() {
33
+ return get_config_boolean(SECTION_NAME, "enable_multi_tenancy", DEFAULT_MULTI_TENANCY.enable_multi_tenancy);
34
+ }
35
+ /**
36
+ * Gets the default user limit from config
37
+ * Returns 0 if not configured (unlimited)
38
+ */
39
+ export function get_default_user_limit() {
40
+ return get_config_number(SECTION_NAME, "default_user_limit", DEFAULT_MULTI_TENANCY.default_user_limit);
41
+ }