hazo_auth 0.1.2 → 1.0.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 (89) hide show
  1. package/hazo_auth_config.example.ini +75 -0
  2. package/instrumentation.ts +1 -1
  3. package/next.config.mjs +1 -1
  4. package/package.json +4 -1
  5. package/src/app/api/{auth → hazo_auth/auth}/upload_profile_picture/route.ts +2 -2
  6. package/src/app/api/{auth → hazo_auth}/change_password/route.ts +23 -0
  7. package/src/app/api/hazo_auth/get_auth/route.ts +89 -0
  8. package/src/app/api/hazo_auth/invalidate_cache/route.ts +139 -0
  9. package/src/app/api/{auth → hazo_auth}/library_photos/route.ts +3 -0
  10. package/src/app/api/{auth → hazo_auth}/logout/route.ts +27 -0
  11. package/src/app/api/hazo_auth/upload_profile_picture/route.ts +268 -0
  12. package/src/app/api/hazo_auth/user_management/permissions/route.ts +367 -0
  13. package/src/app/api/hazo_auth/user_management/roles/route.ts +442 -0
  14. package/src/app/api/hazo_auth/user_management/users/roles/route.ts +367 -0
  15. package/src/app/api/hazo_auth/user_management/users/route.ts +239 -0
  16. package/src/app/api/{auth → hazo_auth}/validate_reset_token/route.ts +3 -0
  17. package/src/app/api/{auth → hazo_auth}/verify_email/route.ts +3 -0
  18. package/src/app/globals.css +1 -1
  19. package/src/app/hazo_auth/user_management/page.tsx +14 -0
  20. package/src/app/hazo_auth/user_management/user_management_page_client.tsx +16 -0
  21. package/src/app/hazo_connect/api/sqlite/data/route.ts +7 -1
  22. package/src/app/hazo_connect/api/sqlite/schema/route.ts +14 -4
  23. package/src/app/hazo_connect/api/sqlite/tables/route.ts +14 -4
  24. package/src/app/hazo_connect/sqlite_admin/sqlite-admin-client.tsx +40 -3
  25. package/src/app/layout.tsx +1 -1
  26. package/src/app/page.tsx +4 -4
  27. package/src/components/layouts/email_verification/hooks/use_email_verification.ts +4 -4
  28. package/src/components/layouts/email_verification/index.tsx +1 -1
  29. package/src/components/layouts/forgot_password/hooks/use_forgot_password_form.ts +1 -1
  30. package/src/components/layouts/login/hooks/use_login_form.ts +2 -2
  31. package/src/components/layouts/my_settings/components/profile_picture_dialog.tsx +1 -1
  32. package/src/components/layouts/my_settings/components/profile_picture_library_tab.tsx +35 -6
  33. package/src/components/layouts/my_settings/hooks/use_my_settings.ts +5 -5
  34. package/src/components/layouts/my_settings/index.tsx +1 -1
  35. package/src/components/layouts/register/hooks/use_register_form.ts +1 -1
  36. package/src/components/layouts/reset_password/hooks/use_reset_password_form.ts +3 -3
  37. package/src/components/layouts/reset_password/index.tsx +2 -2
  38. package/src/components/layouts/shared/components/logout_button.tsx +1 -1
  39. package/src/components/layouts/shared/components/profile_pic_menu.tsx +321 -0
  40. package/src/components/layouts/shared/components/profile_pic_menu_wrapper.tsx +40 -0
  41. package/src/components/layouts/shared/components/sidebar_layout_wrapper.tsx +22 -72
  42. package/src/components/layouts/shared/components/unauthorized_guard.tsx +1 -1
  43. package/src/components/layouts/shared/hooks/use_auth_status.ts +1 -1
  44. package/src/components/layouts/shared/hooks/use_hazo_auth.ts +158 -0
  45. package/src/components/layouts/user_management/components/roles_matrix.tsx +607 -0
  46. package/src/components/layouts/user_management/index.tsx +1295 -0
  47. package/src/components/ui/alert-dialog.tsx +141 -0
  48. package/src/components/ui/checkbox.tsx +30 -0
  49. package/src/components/ui/dropdown-menu.tsx +201 -0
  50. package/src/components/ui/table.tsx +120 -0
  51. package/src/lib/auth/auth_cache.ts +220 -0
  52. package/src/lib/auth/auth_rate_limiter.ts +121 -0
  53. package/src/lib/auth/auth_types.ts +65 -0
  54. package/src/lib/auth/hazo_get_auth.server.ts +333 -0
  55. package/src/lib/auth_utility_config.server.ts +136 -0
  56. package/src/lib/hazo_connect_setup.server.ts +2 -3
  57. package/src/lib/my_settings_config.server.ts +1 -1
  58. package/src/lib/profile_pic_menu_config.server.ts +138 -0
  59. package/src/lib/reset_password_config.server.ts +5 -5
  60. package/src/lib/services/email_service.ts +2 -2
  61. package/src/lib/services/profile_picture_remove_service.ts +1 -1
  62. package/src/lib/services/token_service.ts +2 -2
  63. package/src/lib/user_management_config.server.ts +40 -0
  64. package/src/lib/utils.ts +1 -1
  65. package/src/middleware.ts +15 -13
  66. package/src/server/types/express.d.ts +1 -0
  67. package/src/stories/project_overview.stories.tsx +1 -1
  68. package/tailwind.config.ts +1 -1
  69. /package/src/app/api/{auth → hazo_auth}/forgot_password/route.ts +0 -0
  70. /package/src/app/api/{auth → hazo_auth}/login/route.ts +0 -0
  71. /package/src/app/api/{auth → hazo_auth}/me/route.ts +0 -0
  72. /package/src/app/api/{auth → hazo_auth}/profile_picture/[filename]/route.ts +0 -0
  73. /package/src/app/api/{auth → hazo_auth}/register/route.ts +0 -0
  74. /package/src/app/api/{auth → hazo_auth}/remove_profile_picture/route.ts +0 -0
  75. /package/src/app/api/{auth → hazo_auth}/resend_verification/route.ts +0 -0
  76. /package/src/app/api/{auth → hazo_auth}/reset_password/route.ts +0 -0
  77. /package/src/app/api/{auth → hazo_auth}/update_user/route.ts +0 -0
  78. /package/src/app/{forgot_password → hazo_auth/forgot_password}/forgot_password_page_client.tsx +0 -0
  79. /package/src/app/{forgot_password → hazo_auth/forgot_password}/page.tsx +0 -0
  80. /package/src/app/{login → hazo_auth/login}/login_page_client.tsx +0 -0
  81. /package/src/app/{login → hazo_auth/login}/page.tsx +0 -0
  82. /package/src/app/{my_settings → hazo_auth/my_settings}/my_settings_page_client.tsx +0 -0
  83. /package/src/app/{my_settings → hazo_auth/my_settings}/page.tsx +0 -0
  84. /package/src/app/{register → hazo_auth/register}/page.tsx +0 -0
  85. /package/src/app/{register → hazo_auth/register}/register_page_client.tsx +0 -0
  86. /package/src/app/{reset_password → hazo_auth/reset_password}/page.tsx +0 -0
  87. /package/src/app/{reset_password → hazo_auth/reset_password}/reset_password_page_client.tsx +0 -0
  88. /package/src/app/{verify_email → hazo_auth/verify_email}/page.tsx +0 -0
  89. /package/src/app/{verify_email → hazo_auth/verify_email}/verify_email_page_client.tsx +0 -0
@@ -19,11 +19,21 @@ export async function GET(request: NextRequest) {
19
19
  // Get singleton hazo_connect instance (initializes admin service if needed)
20
20
  get_hazo_connect_instance();
21
21
 
22
- const service = getSqliteAdminService()
23
- const schema = await service.getTableSchema(table)
24
- return NextResponse.json({ data: schema })
22
+ let service;
23
+ try {
24
+ service = getSqliteAdminService();
25
+ } catch (serviceError) {
26
+ const errorMessage = serviceError instanceof Error ? serviceError.message : "Unknown error";
27
+ return NextResponse.json(
28
+ { error: `SQLite Admin Service not available: ${errorMessage}. Make sure enable_admin_ui is set to true in hazo_auth_config.ini.` },
29
+ { status: 500 }
30
+ );
31
+ }
32
+
33
+ const schema = await service.getTableSchema(table);
34
+ return NextResponse.json({ data: schema });
25
35
  } catch (error) {
26
- return toErrorResponse(error, `Failed to fetch schema for table '${table}'`)
36
+ return toErrorResponse(error, `Failed to fetch schema for table '${table}'`);
27
37
  }
28
38
  }
29
39
 
@@ -10,11 +10,21 @@ export async function GET() {
10
10
  // Get singleton hazo_connect instance (initializes admin service if needed)
11
11
  get_hazo_connect_instance();
12
12
 
13
- const service = getSqliteAdminService()
14
- const tables = await service.listTables()
15
- return NextResponse.json({ data: tables })
13
+ let service;
14
+ try {
15
+ service = getSqliteAdminService();
16
+ } catch (serviceError) {
17
+ const errorMessage = serviceError instanceof Error ? serviceError.message : "Unknown error";
18
+ return NextResponse.json(
19
+ { error: `SQLite Admin Service not available: ${errorMessage}. Make sure enable_admin_ui is set to true in hazo_auth_config.ini.` },
20
+ { status: 500 }
21
+ );
22
+ }
23
+
24
+ const tables = await service.listTables();
25
+ return NextResponse.json({ data: tables });
16
26
  } catch (error) {
17
- return toErrorResponse(error, "Failed to list SQLite tables")
27
+ return toErrorResponse(error, "Failed to list SQLite tables");
18
28
  }
19
29
  }
20
30
 
@@ -91,7 +91,19 @@ export default function SqliteAdminClient({
91
91
  try {
92
92
  const schemaResponse = await fetch(`/hazo_connect/api/sqlite/schema?table=${encodeURIComponent(tableName)}`)
93
93
  if (!schemaResponse.ok) {
94
- throw new Error(await schemaResponse.text())
94
+ const contentType = schemaResponse.headers.get("content-type");
95
+ if (contentType && contentType.includes("application/json")) {
96
+ const errorData = await schemaResponse.json();
97
+ throw new Error(errorData.error || `Failed to fetch schema: ${schemaResponse.statusText}`);
98
+ } else {
99
+ const errorText = await schemaResponse.text();
100
+ throw new Error(`Failed to fetch schema: ${errorText.substring(0, 200)}`);
101
+ }
102
+ }
103
+ const contentType = schemaResponse.headers.get("content-type");
104
+ if (!contentType || !contentType.includes("application/json")) {
105
+ const text = await schemaResponse.text();
106
+ throw new Error(`Expected JSON but received ${contentType || "unknown content type"}. Response: ${text.substring(0, 200)}`);
95
107
  }
96
108
  const schemaJson = await schemaResponse.json()
97
109
  setSchema(schemaJson.data as TableSchema)
@@ -170,7 +182,20 @@ export default function SqliteAdminClient({
170
182
 
171
183
  const response = await fetch(`/hazo_connect/api/sqlite/data?${params.toString()}`)
172
184
  if (!response.ok) {
173
- throw new Error(await response.text())
185
+ const contentType = response.headers.get("content-type");
186
+ if (contentType && contentType.includes("application/json")) {
187
+ const errorData = await response.json();
188
+ throw new Error(errorData.error || `Failed to load data: ${response.statusText}`);
189
+ } else {
190
+ const errorText = await response.text();
191
+ throw new Error(`Failed to load data: ${errorText.substring(0, 200)}`);
192
+ }
193
+ }
194
+
195
+ const contentType = response.headers.get("content-type");
196
+ if (!contentType || !contentType.includes("application/json")) {
197
+ const text = await response.text();
198
+ throw new Error(`Expected JSON but received ${contentType || "unknown content type"}. Response: ${text.substring(0, 200)}`);
174
199
  }
175
200
 
176
201
  const json = (await response.json()) as DataResponse
@@ -197,7 +222,19 @@ export default function SqliteAdminClient({
197
222
  try {
198
223
  const response = await fetch("/hazo_connect/api/sqlite/tables")
199
224
  if (!response.ok) {
200
- throw new Error(await response.text())
225
+ const contentType = response.headers.get("content-type");
226
+ if (contentType && contentType.includes("application/json")) {
227
+ const errorData = await response.json();
228
+ throw new Error(errorData.error || `Failed to refresh tables: ${response.statusText}`);
229
+ } else {
230
+ const errorText = await response.text();
231
+ throw new Error(`Failed to refresh tables: ${errorText.substring(0, 200)}`);
232
+ }
233
+ }
234
+ const contentType = response.headers.get("content-type");
235
+ if (!contentType || !contentType.includes("application/json")) {
236
+ const text = await response.text();
237
+ throw new Error(`Expected JSON but received ${contentType || "unknown content type"}. Response: ${text.substring(0, 200)}`);
201
238
  }
202
239
  const json = await response.json()
203
240
  setTables(json.data ?? [])
@@ -1,4 +1,4 @@
1
- // file_description: define the root layout wrapper for the ui_component project
1
+ // file_description: define the root layout wrapper for the hazo_auth project
2
2
  import type { Metadata } from "next";
3
3
  import local_font from "next/font/local";
4
4
  import { Toaster } from "@/components/ui/sonner";
package/src/app/page.tsx CHANGED
@@ -41,7 +41,7 @@ export default function home_page() {
41
41
  <SidebarMenuItem className="cls_home_sidebar_test_login_item">
42
42
  <SidebarMenuButton asChild>
43
43
  <Link
44
- href="/login"
44
+ href="/hazo_auth/login"
45
45
  className="cls_home_sidebar_test_login_link flex items-center gap-2"
46
46
  aria-label="Test login layout component"
47
47
  >
@@ -53,7 +53,7 @@ export default function home_page() {
53
53
  <SidebarMenuItem className="cls_home_sidebar_test_register_item">
54
54
  <SidebarMenuButton asChild>
55
55
  <Link
56
- href="/register"
56
+ href="/hazo_auth/register"
57
57
  className="cls_home_sidebar_test_register_link flex items-center gap-2"
58
58
  aria-label="Test register layout component"
59
59
  >
@@ -65,7 +65,7 @@ export default function home_page() {
65
65
  <SidebarMenuItem className="cls_home_sidebar_test_forgot_password_item">
66
66
  <SidebarMenuButton asChild>
67
67
  <Link
68
- href="/forgot_password"
68
+ href="/hazo_auth/forgot_password"
69
69
  className="cls_home_sidebar_test_forgot_password_link flex items-center gap-2"
70
70
  aria-label="Test forgot password layout component"
71
71
  >
@@ -77,7 +77,7 @@ export default function home_page() {
77
77
  <SidebarMenuItem className="cls_home_sidebar_test_email_verification_item">
78
78
  <SidebarMenuButton asChild>
79
79
  <Link
80
- href="/verify_email"
80
+ href="/hazo_auth/verify_email"
81
81
  className="cls_home_sidebar_test_email_verification_link flex items-center gap-2"
82
82
  aria-label="Test email verification layout component"
83
83
  >
@@ -47,7 +47,7 @@ const buildInitialValues = (initialEmail?: string): EmailVerificationFormValues
47
47
  export const use_email_verification = <TClient,>({
48
48
  dataClient,
49
49
  redirectDelay = 5,
50
- loginPath = "/login",
50
+ loginPath = "/hazo_auth/login",
51
51
  }: UseEmailVerificationParams<TClient>): UseEmailVerificationResult => {
52
52
  const router = useRouter();
53
53
  const searchParams = useSearchParams();
@@ -91,7 +91,7 @@ export const use_email_verification = <TClient,>({
91
91
  setErrorMessage(undefined);
92
92
 
93
93
  try {
94
- const response = await fetch(`/api/auth/verify_email?token=${encodeURIComponent(token)}`, {
94
+ const response = await fetch(`/api/hazo_auth/verify_email?token=${encodeURIComponent(token)}`, {
95
95
  method: "GET",
96
96
  });
97
97
 
@@ -131,7 +131,7 @@ export const use_email_verification = <TClient,>({
131
131
 
132
132
  // Try to extract email from error response if available
133
133
  try {
134
- const response = await fetch(`/api/auth/verify_email?token=${encodeURIComponent(token)}`, {
134
+ const response = await fetch(`/api/hazo_auth/verify_email?token=${encodeURIComponent(token)}`, {
135
135
  method: "GET",
136
136
  });
137
137
  const data = await response.json();
@@ -221,7 +221,7 @@ export const use_email_verification = <TClient,>({
221
221
  setErrors({});
222
222
 
223
223
  try {
224
- const response = await fetch("/api/auth/resend_verification", {
224
+ const response = await fetch("/api/hazo_auth/resend_verification", {
225
225
  method: "POST",
226
226
  headers: {
227
227
  "Content-Type": "application/json",
@@ -69,7 +69,7 @@ export default function email_verification_layout<TClient>({
69
69
  success_labels,
70
70
  error_labels,
71
71
  redirect_delay = 5,
72
- login_path = "/login",
72
+ login_path = "/hazo_auth/login",
73
73
  data_client,
74
74
  already_logged_in_message,
75
75
  showLogoutButton = true,
@@ -113,7 +113,7 @@ export const use_forgot_password_form = <TClient,>({
113
113
  setErrors({});
114
114
 
115
115
  try {
116
- const response = await fetch("/api/auth/forgot_password", {
116
+ const response = await fetch("/api/hazo_auth/forgot_password", {
117
117
  method: "POST",
118
118
  headers: {
119
119
  "Content-Type": "application/json",
@@ -181,7 +181,7 @@ export const use_login_form = <TClient,>({
181
181
  setClientIp(currentIp);
182
182
 
183
183
  // Attempt login via API route
184
- const response = await fetch("/api/auth/login", {
184
+ const response = await fetch("/api/hazo_auth/login", {
185
185
  method: "POST",
186
186
  headers: {
187
187
  "Content-Type": "application/json",
@@ -202,7 +202,7 @@ export const use_login_form = <TClient,>({
202
202
  const messageParam = encodeURIComponent(
203
203
  "Your email address has not been verified. Please verify your email to continue."
204
204
  );
205
- router.push(`/verify_email?email=${emailParam}&message=${messageParam}`);
205
+ router.push(`/hazo_auth/verify_email?email=${emailParam}&message=${messageParam}`);
206
206
  return;
207
207
  }
208
208
 
@@ -188,7 +188,7 @@ export function ProfilePictureDialog({
188
188
  const formData = new FormData();
189
189
  formData.append("file", file);
190
190
 
191
- const response = await fetch("/api/auth/upload_profile_picture", {
191
+ const response = await fetch("/api/hazo_auth/upload_profile_picture", {
192
192
  method: "POST",
193
193
  credentials: "include",
194
194
  body: formData,
@@ -57,7 +57,7 @@ export function ProfilePictureLibraryTab({
57
57
  const loadCategories = async () => {
58
58
  setLoadingCategories(true);
59
59
  try {
60
- const response = await fetch("/api/auth/library_photos");
60
+ const response = await fetch("/api/hazo_auth/library_photos");
61
61
  const data = await response.json();
62
62
  if (data.success && data.categories) {
63
63
  setCategories(data.categories);
@@ -99,7 +99,7 @@ export function ProfilePictureLibraryTab({
99
99
  const loadPhotos = async () => {
100
100
  setLoadingPhotos(true);
101
101
  try {
102
- const response = await fetch(`/api/auth/library_photos?category=${encodeURIComponent(selectedCategory)}`);
102
+ const response = await fetch(`/api/hazo_auth/library_photos?category=${encodeURIComponent(selectedCategory)}`);
103
103
  const data = await response.json();
104
104
  if (data.success && data.photos) {
105
105
  setPhotos(data.photos);
@@ -140,6 +140,21 @@ export function ProfilePictureLibraryTab({
140
140
  return "L";
141
141
  };
142
142
 
143
+ // Map column count to Tailwind grid class
144
+ const getGridColumnsClass = (columns: number): string => {
145
+ const columnMap: Record<number, string> = {
146
+ 1: "grid-cols-1",
147
+ 2: "grid-cols-2",
148
+ 3: "grid-cols-3",
149
+ 4: "grid-cols-4",
150
+ 5: "grid-cols-5",
151
+ 6: "grid-cols-6",
152
+ 7: "grid-cols-7",
153
+ 8: "grid-cols-8",
154
+ };
155
+ return columnMap[columns] || "grid-cols-4";
156
+ };
157
+
143
158
  return (
144
159
  <div className="cls_profile_picture_library_tab flex flex-col gap-4">
145
160
  {/* Switch */}
@@ -213,7 +228,7 @@ export function ProfilePictureLibraryTab({
213
228
  <Loader2 className="h-6 w-6 text-slate-400 animate-spin" aria-hidden="true" />
214
229
  </div>
215
230
  ) : photos.length > 0 ? (
216
- <div className={`cls_profile_picture_library_tab_photos_grid grid grid-cols-${libraryPhotoGridColumns} gap-3 overflow-y-auto p-4 border border-slate-200 rounded-lg bg-slate-50 min-h-[400px] max-h-[400px]`}>
231
+ <div className={`cls_profile_picture_library_tab_photos_grid grid ${getGridColumnsClass(libraryPhotoGridColumns)} gap-3 overflow-y-auto p-4 border border-slate-200 rounded-lg bg-slate-50 min-h-[400px] max-h-[400px]`}>
217
232
  {photos.map((photoUrl) => (
218
233
  <button
219
234
  key={photoUrl}
@@ -221,16 +236,21 @@ export function ProfilePictureLibraryTab({
221
236
  onClick={() => handlePhotoClick(photoUrl)}
222
237
  className={`
223
238
  cls_profile_picture_library_tab_photo_thumbnail
224
- aspect-square rounded-lg overflow-hidden border-2 transition-colors
239
+ aspect-square rounded-lg overflow-hidden border-2 transition-colors cursor-pointer
225
240
  ${selectedPhoto === photoUrl ? "border-blue-500 ring-2 ring-blue-200" : "border-slate-200 hover:border-slate-300"}
226
241
  `}
227
- aria-label={`Select ${photoUrl}`}
242
+ aria-label={`Select photo ${photoUrl.split('/').pop()}`}
228
243
  >
229
244
  <img
230
245
  src={photoUrl}
231
- alt="Library photo thumbnail"
246
+ alt={`Library photo ${photoUrl.split('/').pop()}`}
232
247
  className="cls_profile_picture_library_tab_photo_thumbnail_image w-full h-full object-cover"
233
248
  loading="lazy"
249
+ onError={(e) => {
250
+ // Fallback if image fails to load
251
+ const target = e.target as HTMLImageElement;
252
+ target.style.display = 'none';
253
+ }}
234
254
  />
235
255
  </button>
236
256
  ))}
@@ -256,6 +276,15 @@ export function ProfilePictureLibraryTab({
256
276
  src={selectedPhoto}
257
277
  alt="Selected library photo preview"
258
278
  className="cls_profile_picture_library_tab_preview_image max-w-full max-h-[350px] rounded-lg object-contain"
279
+ onError={(e) => {
280
+ // Fallback if preview image fails to load
281
+ const target = e.target as HTMLImageElement;
282
+ target.style.display = 'none';
283
+ const wrapper = target.parentElement;
284
+ if (wrapper) {
285
+ wrapper.innerHTML = '<p class="text-sm text-red-500">Failed to load preview</p>';
286
+ }
287
+ }}
259
288
  />
260
289
  </div>
261
290
  <p className="cls_profile_picture_library_tab_preview_text text-sm text-slate-600 text-center">
@@ -134,7 +134,7 @@ export function use_my_settings({
134
134
  }
135
135
 
136
136
  try {
137
- const response = await fetch("/api/auth/update_user", {
137
+ const response = await fetch("/api/hazo_auth/update_user", {
138
138
  method: "PATCH",
139
139
  headers: {
140
140
  "Content-Type": "application/json",
@@ -171,7 +171,7 @@ export function use_my_settings({
171
171
  }
172
172
 
173
173
  try {
174
- const response = await fetch("/api/auth/update_user", {
174
+ const response = await fetch("/api/hazo_auth/update_user", {
175
175
  method: "PATCH",
176
176
  headers: {
177
177
  "Content-Type": "application/json",
@@ -304,7 +304,7 @@ export function use_my_settings({
304
304
  }
305
305
 
306
306
  try {
307
- const response = await fetch("/api/auth/change_password", {
307
+ const response = await fetch("/api/hazo_auth/change_password", {
308
308
  method: "POST",
309
309
  headers: {
310
310
  "Content-Type": "application/json",
@@ -371,7 +371,7 @@ export function use_my_settings({
371
371
  */
372
372
  const handleProfilePictureSave = useCallback(async (profilePictureUrl: string, profileSource: "upload" | "library" | "gravatar") => {
373
373
  try {
374
- const response = await fetch("/api/auth/update_user", {
374
+ const response = await fetch("/api/hazo_auth/update_user", {
375
375
  method: "PATCH",
376
376
  headers: {
377
377
  "Content-Type": "application/json",
@@ -408,7 +408,7 @@ export function use_my_settings({
408
408
  */
409
409
  const handleProfilePictureRemove = useCallback(async () => {
410
410
  try {
411
- const response = await fetch("/api/auth/remove_profile_picture", {
411
+ const response = await fetch("/api/hazo_auth/remove_profile_picture", {
412
412
  method: "DELETE",
413
413
  headers: {
414
414
  "Content-Type": "application/json",
@@ -94,7 +94,7 @@ export default function my_settings_layout({
94
94
  userFields,
95
95
  unauthorizedMessage = "You must be logged in to access this page.",
96
96
  loginButtonLabel = "Go to login",
97
- loginPath = "/login",
97
+ loginPath = "/hazo_auth/login",
98
98
  heading = "Account Settings",
99
99
  subHeading = "Manage your profile, password, and email preferences.",
100
100
  profilePhotoLabel = "Profile Photo",
@@ -194,7 +194,7 @@ export const use_register_form = <TClient,>({
194
194
  setErrors({});
195
195
 
196
196
  try {
197
- const response = await fetch("/api/auth/register", {
197
+ const response = await fetch("/api/hazo_auth/register", {
198
198
  method: "POST",
199
199
  headers: {
200
200
  "Content-Type": "application/json",
@@ -54,7 +54,7 @@ const buildInitialValues = (): ResetPasswordFormValues => ({
54
54
  export const use_reset_password_form = <TClient,>({
55
55
  passwordRequirements,
56
56
  dataClient,
57
- loginPath = "/login",
57
+ loginPath = "/hazo_auth/login",
58
58
  }: UseResetPasswordFormParams<TClient>): UseResetPasswordFormResult => {
59
59
  const router = useRouter();
60
60
  const searchParams = useSearchParams();
@@ -85,7 +85,7 @@ export const use_reset_password_form = <TClient,>({
85
85
  setTokenError(null);
86
86
 
87
87
  try {
88
- const response = await fetch(`/api/auth/validate_reset_token?token=${encodeURIComponent(tokenParam)}`, {
88
+ const response = await fetch(`/api/hazo_auth/validate_reset_token?token=${encodeURIComponent(tokenParam)}`, {
89
89
  method: "GET",
90
90
  });
91
91
 
@@ -217,7 +217,7 @@ export const use_reset_password_form = <TClient,>({
217
217
  setIsSubmitting(true);
218
218
 
219
219
  try {
220
- const response = await fetch("/api/auth/reset_password", {
220
+ const response = await fetch("/api/hazo_auth/reset_password", {
221
221
  method: "POST",
222
222
  headers: {
223
223
  "Content-Type": "application/json",
@@ -75,8 +75,8 @@ export default function reset_password_layout<TClient>({
75
75
  returnHomePath = "/",
76
76
  errorMessage = "Reset password link invalid or has expired. Please go to Reset Password page to get a new link.",
77
77
  successMessage = "Password reset successfully. Redirecting to login...",
78
- loginPath = "/login",
79
- forgotPasswordPath = "/forgot_password",
78
+ loginPath = "/hazo_auth/login",
79
+ forgotPasswordPath = "/hazo_auth/forgot_password",
80
80
  }: ResetPasswordLayoutProps<TClient>) {
81
81
  const fieldDefinitions = createResetPasswordFieldDefinitions(field_overrides);
82
82
  const resolvedLabels = resolveResetPasswordLabels(labels);
@@ -30,7 +30,7 @@ export function LogoutButton({
30
30
  setIsLoggingOut(true);
31
31
 
32
32
  try {
33
- const response = await fetch("/api/auth/logout", {
33
+ const response = await fetch("/api/hazo_auth/logout", {
34
34
  method: "POST",
35
35
  headers: {
36
36
  "Content-Type": "application/json",