hazo_auth 1.0.5 → 1.2.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 (31) hide show
  1. package/README.md +341 -0
  2. package/hazo_auth_config.example.ini +41 -0
  3. package/instrumentation.ts +2 -2
  4. package/package.json +2 -1
  5. package/scripts/init_users.ts +378 -0
  6. package/src/app/api/hazo_auth/login/route.ts +27 -1
  7. package/src/app/api/hazo_auth/register/route.ts +13 -10
  8. package/src/app/hazo_auth/forgot_password/page.tsx +3 -3
  9. package/src/app/hazo_auth/login/login_page_client.tsx +15 -0
  10. package/src/app/hazo_auth/login/page.tsx +16 -4
  11. package/src/app/hazo_auth/my_settings/page.tsx +3 -3
  12. package/src/app/hazo_auth/register/page.tsx +14 -4
  13. package/src/app/hazo_auth/register/register_page_client.tsx +9 -0
  14. package/src/app/hazo_auth/reset_password/page.tsx +3 -3
  15. package/src/app/hazo_auth/user_management/page.tsx +3 -3
  16. package/src/app/hazo_auth/verify_email/page.tsx +3 -3
  17. package/src/components/layouts/login/hooks/use_login_form.ts +13 -8
  18. package/src/components/layouts/login/index.tsx +28 -0
  19. package/src/components/layouts/register/hooks/use_register_form.ts +4 -1
  20. package/src/components/layouts/register/index.tsx +18 -0
  21. package/src/components/layouts/shared/components/auth_page_shell.tsx +36 -0
  22. package/src/components/layouts/shared/components/standalone_layout_wrapper.tsx +53 -0
  23. package/src/lib/config/config_loader.server.ts +20 -5
  24. package/src/lib/login_config.server.ts +25 -0
  25. package/src/lib/register_config.server.ts +17 -1
  26. package/src/lib/services/login_service.ts +19 -3
  27. package/src/lib/services/registration_service.ts +25 -4
  28. package/src/lib/services/user_profiles_service.ts +143 -0
  29. package/src/lib/services/user_update_service.ts +16 -3
  30. package/src/lib/ui_shell_config.server.ts +73 -0
  31. package/src/lib/utils/error_sanitizer.ts +75 -0
@@ -0,0 +1,378 @@
1
+ // file_description: script to initialize users, roles, and permissions from configuration
2
+ // Run with: npx tsx scripts/init_users.ts init_users
3
+ // section: imports
4
+ import { get_hazo_connect_instance } from "../src/lib/hazo_connect_instance.server";
5
+ import { createCrudService } from "hazo_connect/server";
6
+ import { get_user_management_config } from "../src/lib/user_management_config.server";
7
+ import { get_config_value } from "../src/lib/config/config_loader.server";
8
+ import { create_app_logger } from "../src/lib/app_logger";
9
+
10
+ // section: types
11
+ type InitSummary = {
12
+ permissions: {
13
+ inserted: string[];
14
+ existing: string[];
15
+ };
16
+ role: {
17
+ inserted: boolean;
18
+ existing: boolean;
19
+ role_id: number | null;
20
+ };
21
+ role_permissions: {
22
+ inserted: number;
23
+ existing: number;
24
+ };
25
+ user_role: {
26
+ inserted: boolean;
27
+ existing: boolean;
28
+ };
29
+ };
30
+
31
+ // section: helpers
32
+ /**
33
+ * Displays help information for available commands
34
+ */
35
+ function show_help(): void {
36
+ console.log(`
37
+ hazo_auth CLI - User and Permission Management
38
+
39
+ Usage: npx tsx scripts/init_users.ts <command>
40
+
41
+ Available Commands:
42
+ init_users Initialize users, roles, and permissions from configuration
43
+ - Reads permissions from hazo_auth_config.ini [hazo_auth__user_management] application_permission_list_defaults
44
+ - Creates default_super_user_role in hazo_roles
45
+ - Assigns all permissions to the super user role
46
+ - Finds user by email from hazo_auth_config.ini [hazo_auth__initial_setup] default_super_user_email
47
+ - Assigns super user role to the user
48
+ - Provides summary of what was inserted vs what already existed
49
+
50
+ help Show this help message
51
+
52
+ Configuration:
53
+ Add the following to hazo_auth_config.ini:
54
+
55
+ [hazo_auth__user_management]
56
+ application_permission_list_defaults = admin_user_management,admin_role_management,admin_permission_management
57
+
58
+ [hazo_auth__initial_setup]
59
+ default_super_user_email = admin@example.com
60
+
61
+ Examples:
62
+ npx tsx scripts/init_users.ts init_users
63
+ npx tsx scripts/init_users.ts help
64
+ `);
65
+ }
66
+
67
+ /**
68
+ * Initializes users, roles, and permissions from configuration
69
+ */
70
+ async function init_users(): Promise<void> {
71
+ const logger = create_app_logger();
72
+ const summary: InitSummary = {
73
+ permissions: {
74
+ inserted: [],
75
+ existing: [],
76
+ },
77
+ role: {
78
+ inserted: false,
79
+ existing: false,
80
+ role_id: null,
81
+ },
82
+ role_permissions: {
83
+ inserted: 0,
84
+ existing: 0,
85
+ },
86
+ user_role: {
87
+ inserted: false,
88
+ existing: false,
89
+ },
90
+ };
91
+
92
+ try {
93
+ console.log("Initializing users, roles, and permissions from configuration...\n");
94
+
95
+ // Get hazo_connect instance
96
+ const hazoConnect = get_hazo_connect_instance();
97
+ const permissions_service = createCrudService(hazoConnect, "hazo_permissions");
98
+ const roles_service = createCrudService(hazoConnect, "hazo_roles");
99
+ const role_permissions_service = createCrudService(hazoConnect, "hazo_role_permissions");
100
+ const users_service = createCrudService(hazoConnect, "hazo_users");
101
+ const user_roles_service = createCrudService(hazoConnect, "hazo_user_roles");
102
+
103
+ // 1. Get permissions from config
104
+ const config = get_user_management_config();
105
+ const permission_names = config.application_permission_list_defaults || [];
106
+
107
+ if (permission_names.length === 0) {
108
+ console.log("⚠ No permissions found in configuration.");
109
+ console.log(" Add permissions to [hazo_auth__user_management] application_permission_list_defaults\n");
110
+ return;
111
+ }
112
+
113
+ console.log(`Found ${permission_names.length} permission(s) in configuration:`);
114
+ permission_names.forEach((name) => console.log(` - ${name}`));
115
+ console.log();
116
+
117
+ // 2. Add permissions to hazo_permissions table
118
+ const permission_id_map: Record<string, number> = {};
119
+ const now = new Date().toISOString();
120
+
121
+ for (const permission_name of permission_names) {
122
+ const trimmed_name = permission_name.trim();
123
+ if (!trimmed_name) continue;
124
+
125
+ // Check if permission already exists
126
+ const existing_permissions = await permissions_service.findBy({
127
+ permission_name: trimmed_name,
128
+ });
129
+
130
+ if (Array.isArray(existing_permissions) && existing_permissions.length > 0) {
131
+ const existing_permission = existing_permissions[0];
132
+ const perm_id = existing_permission.id as number;
133
+ permission_id_map[trimmed_name] = perm_id;
134
+ summary.permissions.existing.push(trimmed_name);
135
+ console.log(`✓ Permission already exists: ${trimmed_name} (ID: ${perm_id})`);
136
+ } else {
137
+ // Insert new permission
138
+ const new_permission = await permissions_service.insert({
139
+ permission_name: trimmed_name,
140
+ description: `Permission for ${trimmed_name}`,
141
+ created_at: now,
142
+ changed_at: now,
143
+ });
144
+
145
+ const perm_id = Array.isArray(new_permission)
146
+ ? (new_permission[0] as { id: number }).id
147
+ : (new_permission as { id: number }).id;
148
+ permission_id_map[trimmed_name] = perm_id;
149
+ summary.permissions.inserted.push(trimmed_name);
150
+ console.log(`✓ Inserted permission: ${trimmed_name} (ID: ${perm_id})`);
151
+ }
152
+ }
153
+
154
+ console.log();
155
+
156
+ // 3. Create or get default_super_user_role
157
+ const role_name = "default_super_user_role";
158
+ const existing_roles = await roles_service.findBy({
159
+ role_name,
160
+ });
161
+
162
+ let role_id: number;
163
+ if (Array.isArray(existing_roles) && existing_roles.length > 0) {
164
+ role_id = existing_roles[0].id as number;
165
+ summary.role.existing = true;
166
+ summary.role.role_id = role_id;
167
+ console.log(`✓ Role already exists: ${role_name} (ID: ${role_id})`);
168
+ } else {
169
+ const new_role = await roles_service.insert({
170
+ role_name,
171
+ created_at: now,
172
+ changed_at: now,
173
+ });
174
+
175
+ role_id = Array.isArray(new_role)
176
+ ? (new_role[0] as { id: number }).id
177
+ : (new_role as { id: number }).id;
178
+ summary.role.inserted = true;
179
+ summary.role.role_id = role_id;
180
+ console.log(`✓ Created role: ${role_name} (ID: ${role_id})`);
181
+ }
182
+
183
+ console.log();
184
+
185
+ // 4. Assign all permissions to the role
186
+ const permission_ids = Object.values(permission_id_map);
187
+
188
+ for (const permission_id of permission_ids) {
189
+ // Check if role-permission assignment already exists
190
+ const existing_assignments = await role_permissions_service.findBy({
191
+ role_id,
192
+ permission_id,
193
+ });
194
+
195
+ if (Array.isArray(existing_assignments) && existing_assignments.length > 0) {
196
+ summary.role_permissions.existing++;
197
+ const perm_name = Object.keys(permission_id_map).find(
198
+ (key) => permission_id_map[key] === permission_id,
199
+ );
200
+ console.log(`✓ Role-permission already exists: ${role_name} -> ${perm_name}`);
201
+ } else {
202
+ await role_permissions_service.insert({
203
+ role_id,
204
+ permission_id,
205
+ created_at: now,
206
+ changed_at: now,
207
+ });
208
+ summary.role_permissions.inserted++;
209
+ const perm_name = Object.keys(permission_id_map).find(
210
+ (key) => permission_id_map[key] === permission_id,
211
+ );
212
+ console.log(`✓ Assigned permission to role: ${role_name} -> ${perm_name}`);
213
+ }
214
+ }
215
+
216
+ console.log();
217
+
218
+ // 5. Get super user email from config
219
+ const super_user_email = get_config_value(
220
+ "hazo_auth__initial_setup",
221
+ "default_super_user_email",
222
+ "",
223
+ ).trim();
224
+
225
+ if (!super_user_email) {
226
+ console.log("⚠ No super user email found in configuration.");
227
+ console.log(" Add [hazo_auth__initial_setup] default_super_user_email to config\n");
228
+ print_summary(summary);
229
+ return;
230
+ }
231
+
232
+ console.log(`Looking up user with email: ${super_user_email}`);
233
+
234
+ // 6. Find user by email
235
+ const users = await users_service.findBy({
236
+ email_address: super_user_email,
237
+ });
238
+
239
+ if (!Array.isArray(users) || users.length === 0) {
240
+ console.log(`✗ User not found with email: ${super_user_email}`);
241
+ console.log(" Please ensure the user exists in the database before running this script.\n");
242
+ print_summary(summary);
243
+ return;
244
+ }
245
+
246
+ const user = users[0];
247
+ const user_id = user.id as string;
248
+ console.log(`✓ Found user: ${super_user_email} (ID: ${user_id})`);
249
+ console.log();
250
+
251
+ // 7. Assign role to user
252
+ const existing_user_roles = await user_roles_service.findBy({
253
+ user_id,
254
+ role_id,
255
+ });
256
+
257
+ if (Array.isArray(existing_user_roles) && existing_user_roles.length > 0) {
258
+ summary.user_role.existing = true;
259
+ console.log(`✓ User already has role assigned: ${user_id} -> ${role_name}`);
260
+ } else {
261
+ await user_roles_service.insert({
262
+ user_id,
263
+ role_id,
264
+ created_at: now,
265
+ changed_at: now,
266
+ });
267
+ summary.user_role.inserted = true;
268
+ console.log(`✓ Assigned role to user: ${user_id} -> ${role_name}`);
269
+ }
270
+
271
+ console.log();
272
+
273
+ // 8. Print summary
274
+ print_summary(summary);
275
+
276
+ logger.info("init_users_completed", {
277
+ filename: "init_users.ts",
278
+ line_number: 0,
279
+ summary,
280
+ });
281
+ } catch (error) {
282
+ const error_message = error instanceof Error ? error.message : "Unknown error";
283
+ const error_stack = error instanceof Error ? error.stack : undefined;
284
+
285
+ console.error("\n✗ Error initializing users:");
286
+ console.error(` ${error_message}`);
287
+ if (error_stack) {
288
+ console.error("\nStack trace:");
289
+ console.error(error_stack);
290
+ }
291
+
292
+ const logger = create_app_logger();
293
+ logger.error("init_users_failed", {
294
+ filename: "init_users.ts",
295
+ line_number: 0,
296
+ error_message,
297
+ error_stack,
298
+ });
299
+
300
+ process.exit(1);
301
+ }
302
+ }
303
+
304
+ /**
305
+ * Prints a summary of what was inserted vs what already existed
306
+ */
307
+ function print_summary(summary: InitSummary): void {
308
+ console.log("=".repeat(60));
309
+ console.log("INITIALIZATION SUMMARY");
310
+ console.log("=".repeat(60));
311
+ console.log();
312
+
313
+ // Permissions summary
314
+ console.log("Permissions:");
315
+ if (summary.permissions.inserted.length > 0) {
316
+ console.log(` ✓ Inserted (${summary.permissions.inserted.length}):`);
317
+ summary.permissions.inserted.forEach((name) => console.log(` - ${name}`));
318
+ }
319
+ if (summary.permissions.existing.length > 0) {
320
+ console.log(` ⊙ Already existed (${summary.permissions.existing.length}):`);
321
+ summary.permissions.existing.forEach((name) => console.log(` - ${name}`));
322
+ }
323
+ console.log();
324
+
325
+ // Role summary
326
+ console.log("Role:");
327
+ if (summary.role.inserted) {
328
+ console.log(` ✓ Inserted: default_super_user_role (ID: ${summary.role.role_id})`);
329
+ }
330
+ if (summary.role.existing) {
331
+ console.log(` ⊙ Already existed: default_super_user_role (ID: ${summary.role.role_id})`);
332
+ }
333
+ console.log();
334
+
335
+ // Role permissions summary
336
+ console.log("Role-Permission Assignments:");
337
+ if (summary.role_permissions.inserted > 0) {
338
+ console.log(` ✓ Inserted: ${summary.role_permissions.inserted} assignment(s)`);
339
+ }
340
+ if (summary.role_permissions.existing > 0) {
341
+ console.log(` ⊙ Already existed: ${summary.role_permissions.existing} assignment(s)`);
342
+ }
343
+ console.log();
344
+
345
+ // User role summary
346
+ console.log("User-Role Assignment:");
347
+ if (summary.user_role.inserted) {
348
+ console.log(` ✓ Inserted: Super user role assigned to user`);
349
+ }
350
+ if (summary.user_role.existing) {
351
+ console.log(` ⊙ Already existed: User already has super user role`);
352
+ }
353
+ console.log();
354
+
355
+ console.log("=".repeat(60));
356
+ }
357
+
358
+ // section: main
359
+ function main(): void {
360
+ const command = process.argv[2];
361
+
362
+ if (!command || command === "help" || command === "--help" || command === "-h") {
363
+ show_help();
364
+ return;
365
+ }
366
+
367
+ if (command === "init_users") {
368
+ void init_users();
369
+ } else {
370
+ console.error(`Unknown command: ${command}\n`);
371
+ show_help();
372
+ process.exit(1);
373
+ }
374
+ }
375
+
376
+ main();
377
+
378
+
@@ -6,6 +6,7 @@ import { create_app_logger } from "../../../../lib/app_logger";
6
6
  import { authenticate_user } from "../../../../lib/services/login_service";
7
7
  import { createCrudService } from "hazo_connect/server";
8
8
  import { get_filename, get_line_number } from "../../../../lib/utils/api_route_helpers";
9
+ import { get_login_config } from "../../../../lib/login_config.server";
9
10
 
10
11
  // section: api_handler
11
12
  export async function POST(request: NextRequest) {
@@ -13,7 +14,7 @@ export async function POST(request: NextRequest) {
13
14
 
14
15
  try {
15
16
  const body = await request.json();
16
- const { email, password } = body;
17
+ const { email, password, url_on_logon } = body;
17
18
 
18
19
  // Validate input
19
20
  if (!email || !password) {
@@ -106,6 +107,30 @@ export async function POST(request: NextRequest) {
106
107
  const user = users && users.length > 0 ? users[0] : null;
107
108
  const user_name = user?.name as string | undefined;
108
109
 
110
+ // Determine redirect URL priority:
111
+ // 1. url_on_logon from request body (if valid)
112
+ // 2. stored_url_on_logon from database (if available)
113
+ // 3. redirect_route_on_successful_login from config
114
+ // 4. Default to "/"
115
+
116
+ let redirectUrl = "/";
117
+
118
+ // Check priority 1: Request body
119
+ if (url_on_logon && typeof url_on_logon === "string" && url_on_logon.startsWith("/") && !url_on_logon.startsWith("//")) {
120
+ redirectUrl = url_on_logon;
121
+ }
122
+ // Check priority 2: Stored URL from DB
123
+ else if (result.stored_url_on_logon && typeof result.stored_url_on_logon === "string") {
124
+ redirectUrl = result.stored_url_on_logon;
125
+ }
126
+ // Check priority 3: Config
127
+ else {
128
+ const loginConfig = get_login_config();
129
+ if (loginConfig.redirectRoute) {
130
+ redirectUrl = loginConfig.redirectRoute;
131
+ }
132
+ }
133
+
109
134
  // Create response with cookies
110
135
  const response = NextResponse.json(
111
136
  {
@@ -114,6 +139,7 @@ export async function POST(request: NextRequest) {
114
139
  user_id: user_id,
115
140
  email,
116
141
  name: user_name,
142
+ redirectUrl,
117
143
  },
118
144
  { status: 200 }
119
145
  );
@@ -5,6 +5,7 @@ import { get_hazo_connect_instance } from "../../../../lib/hazo_connect_instance
5
5
  import { create_app_logger } from "../../../../lib/app_logger";
6
6
  import { register_user } from "../../../../lib/services/registration_service";
7
7
  import { get_filename, get_line_number } from "../../../../lib/utils/api_route_helpers";
8
+ import { sanitize_error_for_user } from "../../../../lib/utils/error_sanitizer";
8
9
 
9
10
  // section: api_handler
10
11
  export async function POST(request: NextRequest) {
@@ -12,7 +13,7 @@ export async function POST(request: NextRequest) {
12
13
 
13
14
  try {
14
15
  const body = await request.json();
15
- const { name, email, password } = body;
16
+ const { name, email, password, url_on_logon } = body;
16
17
 
17
18
  // Validate input
18
19
  if (!email || !password) {
@@ -52,6 +53,7 @@ export async function POST(request: NextRequest) {
52
53
  email,
53
54
  password,
54
55
  name,
56
+ url_on_logon,
55
57
  });
56
58
 
57
59
  if (!result.success) {
@@ -87,18 +89,19 @@ export async function POST(request: NextRequest) {
87
89
  { status: 201 }
88
90
  );
89
91
  } catch (error) {
90
- const error_message = error instanceof Error ? error.message : "Unknown error";
91
- const error_stack = error instanceof Error ? error.stack : undefined;
92
-
93
- logger.error("registration_error", {
94
- filename: get_filename(),
95
- line_number: get_line_number(),
96
- error_message,
97
- error_stack,
92
+ const user_friendly_error = sanitize_error_for_user(error, {
93
+ logToConsole: true,
94
+ logToLogger: true,
95
+ logger,
96
+ context: {
97
+ filename: get_filename(),
98
+ line_number: get_line_number(),
99
+ operation: "register_api_route",
100
+ },
98
101
  });
99
102
 
100
103
  return NextResponse.json(
101
- { error: "Registration failed. Please try again." },
104
+ { error: user_friendly_error },
102
105
  { status: 500 }
103
106
  );
104
107
  }
@@ -1,6 +1,6 @@
1
1
  // file_description: render the forgot password page shell and mount the forgot password layout component within sidebar
2
2
  // section: imports
3
- import { SidebarLayoutWrapper } from "../../../components/layouts/shared/components/sidebar_layout_wrapper";
3
+ import { AuthPageShell } from "../../../components/layouts/shared/components/auth_page_shell";
4
4
  import { ForgotPasswordPageClient } from "./forgot_password_page_client";
5
5
  import { get_forgot_password_config } from "../../../lib/forgot_password_config.server";
6
6
 
@@ -10,7 +10,7 @@ export default function forgot_password_page() {
10
10
  const forgotPasswordConfig = get_forgot_password_config();
11
11
 
12
12
  return (
13
- <SidebarLayoutWrapper>
13
+ <AuthPageShell>
14
14
  <ForgotPasswordPageClient
15
15
  alreadyLoggedInMessage={forgotPasswordConfig.alreadyLoggedInMessage}
16
16
  showLogoutButton={forgotPasswordConfig.showLogoutButton}
@@ -18,7 +18,7 @@ export default function forgot_password_page() {
18
18
  returnHomeButtonLabel={forgotPasswordConfig.returnHomeButtonLabel}
19
19
  returnHomePath={forgotPasswordConfig.returnHomePath}
20
20
  />
21
- </SidebarLayoutWrapper>
21
+ </AuthPageShell>
22
22
  );
23
23
  }
24
24
 
@@ -19,6 +19,11 @@ type LoginPageClientProps = {
19
19
  showReturnHomeButton?: boolean;
20
20
  returnHomeButtonLabel?: string;
21
21
  returnHomePath?: string;
22
+ forgotPasswordPath?: string;
23
+ forgotPasswordLabel?: string;
24
+ createAccountPath?: string;
25
+ createAccountLabel?: string;
26
+ urlOnLogon?: string;
22
27
  };
23
28
 
24
29
  // section: component
@@ -30,6 +35,11 @@ export function LoginPageClient({
30
35
  showReturnHomeButton,
31
36
  returnHomeButtonLabel,
32
37
  returnHomePath,
38
+ forgotPasswordPath,
39
+ forgotPasswordLabel,
40
+ createAccountPath,
41
+ createAccountLabel,
42
+ urlOnLogon,
33
43
  }: LoginPageClientProps) {
34
44
  const [dataClient, setDataClient] = useState<LayoutDataClient<unknown> | null>(null);
35
45
  const [logger, setLogger] = useState<ReturnType<typeof create_app_logger> | null>(null);
@@ -65,6 +75,11 @@ export function LoginPageClient({
65
75
  showReturnHomeButton={showReturnHomeButton}
66
76
  returnHomeButtonLabel={returnHomeButtonLabel}
67
77
  returnHomePath={returnHomePath}
78
+ forgot_password_path={forgotPasswordPath}
79
+ forgot_password_label={forgotPasswordLabel}
80
+ create_account_path={createAccountPath}
81
+ create_account_label={createAccountLabel}
82
+ urlOnLogon={urlOnLogon}
68
83
  />
69
84
  );
70
85
  }
@@ -1,16 +1,23 @@
1
1
  // file_description: render the login page shell and mount the login layout component within sidebar
2
2
  // section: imports
3
- import { SidebarLayoutWrapper } from "../../../components/layouts/shared/components/sidebar_layout_wrapper";
3
+ import { AuthPageShell } from "../../../components/layouts/shared/components/auth_page_shell";
4
4
  import { LoginPageClient } from "./login_page_client";
5
5
  import { get_login_config } from "../../../lib/login_config.server";
6
6
 
7
7
  // section: component
8
- export default function login_page() {
8
+ export default function login_page({
9
+ searchParams,
10
+ }: {
11
+ searchParams: { [key: string]: string | string[] | undefined };
12
+ }) {
9
13
  // Read login configuration from hazo_auth_config.ini (server-side)
10
14
  const loginConfig = get_login_config();
11
15
 
16
+ // Get url_on_logon from query params (if any)
17
+ const urlOnLogon = typeof searchParams.url_on_logon === "string" ? searchParams.url_on_logon : undefined;
18
+
12
19
  return (
13
- <SidebarLayoutWrapper>
20
+ <AuthPageShell>
14
21
  <LoginPageClient
15
22
  redirectRoute={loginConfig.redirectRoute}
16
23
  successMessage={loginConfig.successMessage}
@@ -19,8 +26,13 @@ export default function login_page() {
19
26
  showReturnHomeButton={loginConfig.showReturnHomeButton}
20
27
  returnHomeButtonLabel={loginConfig.returnHomeButtonLabel}
21
28
  returnHomePath={loginConfig.returnHomePath}
29
+ forgotPasswordPath={loginConfig.forgotPasswordPath}
30
+ forgotPasswordLabel={loginConfig.forgotPasswordLabel}
31
+ createAccountPath={loginConfig.createAccountPath}
32
+ createAccountLabel={loginConfig.createAccountLabel}
33
+ urlOnLogon={urlOnLogon}
22
34
  />
23
- </SidebarLayoutWrapper>
35
+ </AuthPageShell>
24
36
  );
25
37
  }
26
38
 
@@ -1,6 +1,6 @@
1
1
  // file_description: render the my settings page shell and mount the my settings layout component within sidebar
2
2
  // section: imports
3
- import { SidebarLayoutWrapper } from "../../../components/layouts/shared/components/sidebar_layout_wrapper";
3
+ import { AuthPageShell } from "../../../components/layouts/shared/components/auth_page_shell";
4
4
  import { MySettingsPageClient } from "./my_settings_page_client";
5
5
  import { get_my_settings_config } from "../../../lib/my_settings_config.server";
6
6
 
@@ -10,7 +10,7 @@ export default function my_settings_page() {
10
10
  const mySettingsConfig = get_my_settings_config();
11
11
 
12
12
  return (
13
- <SidebarLayoutWrapper>
13
+ <AuthPageShell>
14
14
  <MySettingsPageClient
15
15
  userFields={mySettingsConfig.userFields}
16
16
  passwordRequirements={mySettingsConfig.passwordRequirements}
@@ -34,7 +34,7 @@ export default function my_settings_page() {
34
34
  uiSizes={mySettingsConfig.uiSizes}
35
35
  fileTypes={mySettingsConfig.fileTypes}
36
36
  />
37
- </SidebarLayoutWrapper>
37
+ </AuthPageShell>
38
38
  );
39
39
  }
40
40
 
@@ -1,16 +1,23 @@
1
1
  // file_description: render the register page shell and mount the register layout component within sidebar
2
2
  // section: imports
3
- import { SidebarLayoutWrapper } from "../../../components/layouts/shared/components/sidebar_layout_wrapper";
3
+ import { AuthPageShell } from "../../../components/layouts/shared/components/auth_page_shell";
4
4
  import { RegisterPageClient } from "./register_page_client";
5
5
  import { get_register_config } from "../../../lib/register_config.server";
6
6
 
7
7
  // section: component
8
- export default function register_page() {
8
+ export default function register_page({
9
+ searchParams,
10
+ }: {
11
+ searchParams: { [key: string]: string | string[] | undefined };
12
+ }) {
9
13
  // Read register configuration from hazo_auth_config.ini (server-side)
10
14
  const registerConfig = get_register_config();
11
15
 
16
+ // Get url_on_logon from query params (if any)
17
+ const urlOnLogon = typeof searchParams.url_on_logon === "string" ? searchParams.url_on_logon : undefined;
18
+
12
19
  return (
13
- <SidebarLayoutWrapper>
20
+ <AuthPageShell>
14
21
  <RegisterPageClient
15
22
  showNameField={registerConfig.showNameField}
16
23
  passwordRequirements={registerConfig.passwordRequirements}
@@ -19,8 +26,11 @@ export default function register_page() {
19
26
  showReturnHomeButton={registerConfig.showReturnHomeButton}
20
27
  returnHomeButtonLabel={registerConfig.returnHomeButtonLabel}
21
28
  returnHomePath={registerConfig.returnHomePath}
29
+ signInPath={registerConfig.signInPath}
30
+ signInLabel={registerConfig.signInLabel}
31
+ urlOnLogon={urlOnLogon}
22
32
  />
23
- </SidebarLayoutWrapper>
33
+ </AuthPageShell>
24
34
  );
25
35
  }
26
36
 
@@ -24,6 +24,9 @@ type RegisterPageClientProps = {
24
24
  showReturnHomeButton?: boolean;
25
25
  returnHomeButtonLabel?: string;
26
26
  returnHomePath?: string;
27
+ signInPath?: string;
28
+ signInLabel?: string;
29
+ urlOnLogon?: string;
27
30
  };
28
31
 
29
32
  // section: component
@@ -35,6 +38,9 @@ export function RegisterPageClient({
35
38
  showReturnHomeButton,
36
39
  returnHomeButtonLabel,
37
40
  returnHomePath,
41
+ signInPath,
42
+ signInLabel,
43
+ urlOnLogon,
38
44
  }: RegisterPageClientProps) {
39
45
  const [dataClient, setDataClient] = useState<LayoutDataClient<unknown> | null>(null);
40
46
 
@@ -66,6 +72,9 @@ export function RegisterPageClient({
66
72
  showReturnHomeButton={showReturnHomeButton}
67
73
  returnHomeButtonLabel={returnHomeButtonLabel}
68
74
  returnHomePath={returnHomePath}
75
+ signInPath={signInPath}
76
+ signInLabel={signInLabel}
77
+ urlOnLogon={urlOnLogon}
69
78
  />
70
79
  );
71
80
  }