hazo_auth 8.0.1 → 9.0.1

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 (72) hide show
  1. package/cli-src/lib/AGENTS.md +26 -0
  2. package/cli-src/lib/app_logger.ts +3 -7
  3. package/cli-src/lib/auth/auth_utils.server.ts +2 -1
  4. package/cli-src/lib/auth/ensure_anon_id.server.ts +2 -1
  5. package/cli-src/lib/auth/hazo_get_auth.server.ts +11 -4
  6. package/cli-src/lib/config/hazo_auth_core_config.ts +44 -0
  7. package/cli-src/lib/cookies_config.server.ts +13 -10
  8. package/cli-src/lib/hazo_connect_setup.server.ts +19 -11
  9. package/cli-src/lib/legal/legal_docs_service.ts +2 -1
  10. package/cli-src/lib/services/email_service.ts +22 -11
  11. package/cli-src/lib/services/firm_service.ts +2 -1
  12. package/cli-src/lib/services/otp_service.ts +3 -2
  13. package/cli-src/lib/services/profile_picture_service.ts +2 -1
  14. package/cli-src/lib/services/relationship_service.ts +5 -4
  15. package/cli-src/lib/services/session_token_service.ts +3 -2
  16. package/cli-src/lib/utils/api_route_helpers.ts +4 -59
  17. package/cli-src/lib/utils/get_origin_url.ts +5 -61
  18. package/cli-src/lib/utils.ts +4 -10
  19. package/config/hazo_auth_config.example.ini +6 -0
  20. package/dist/components/ui/input-otp.d.ts +2 -2
  21. package/dist/components/ui/sheet.d.ts +1 -1
  22. package/dist/lib/app_logger.d.ts +2 -3
  23. package/dist/lib/app_logger.d.ts.map +1 -1
  24. package/dist/lib/app_logger.js +3 -5
  25. package/dist/lib/auth/auth_utils.server.d.ts.map +1 -1
  26. package/dist/lib/auth/auth_utils.server.js +2 -1
  27. package/dist/lib/auth/ensure_anon_id.server.d.ts.map +1 -1
  28. package/dist/lib/auth/ensure_anon_id.server.js +2 -1
  29. package/dist/lib/auth/hazo_get_auth.server.d.ts.map +1 -1
  30. package/dist/lib/auth/hazo_get_auth.server.js +11 -4
  31. package/dist/lib/config/hazo_auth_core_config.d.ts +44 -0
  32. package/dist/lib/config/hazo_auth_core_config.d.ts.map +1 -0
  33. package/dist/lib/config/hazo_auth_core_config.js +40 -0
  34. package/dist/lib/cookies_config.server.d.ts.map +1 -1
  35. package/dist/lib/cookies_config.server.js +12 -7
  36. package/dist/lib/hazo_connect_setup.server.d.ts.map +1 -1
  37. package/dist/lib/hazo_connect_setup.server.js +18 -5
  38. package/dist/lib/legal/legal_docs_service.d.ts.map +1 -1
  39. package/dist/lib/legal/legal_docs_service.js +2 -1
  40. package/dist/lib/services/email_service.d.ts +1 -1
  41. package/dist/lib/services/email_service.d.ts.map +1 -1
  42. package/dist/lib/services/email_service.js +21 -9
  43. package/dist/lib/services/firm_service.d.ts.map +1 -1
  44. package/dist/lib/services/firm_service.js +2 -1
  45. package/dist/lib/services/otp_service.d.ts.map +1 -1
  46. package/dist/lib/services/otp_service.js +3 -2
  47. package/dist/lib/services/profile_picture_service.d.ts.map +1 -1
  48. package/dist/lib/services/profile_picture_service.js +2 -1
  49. package/dist/lib/services/relationship_service.d.ts.map +1 -1
  50. package/dist/lib/services/relationship_service.js +5 -4
  51. package/dist/lib/services/session_token_service.d.ts.map +1 -1
  52. package/dist/lib/services/session_token_service.js +3 -2
  53. package/dist/lib/utils/api_route_helpers.d.ts +1 -12
  54. package/dist/lib/utils/api_route_helpers.d.ts.map +1 -1
  55. package/dist/lib/utils/api_route_helpers.js +4 -57
  56. package/dist/lib/utils/get_origin_url.d.ts +1 -22
  57. package/dist/lib/utils/get_origin_url.d.ts.map +1 -1
  58. package/dist/lib/utils/get_origin_url.js +5 -57
  59. package/dist/lib/utils.d.ts +2 -3
  60. package/dist/lib/utils.d.ts.map +1 -1
  61. package/dist/lib/utils.js +4 -9
  62. package/dist/server/config/config_loader.js +2 -2
  63. package/dist/server/index.js +1 -1
  64. package/dist/server/routes/remove_profile_picture.d.ts.map +1 -1
  65. package/dist/server/routes/remove_profile_picture.js +6 -1
  66. package/dist/server/routes/upload_profile_picture.d.ts.map +1 -1
  67. package/dist/server/routes/upload_profile_picture.js +6 -1
  68. package/dist/server/routes/user_management_users.d.ts +1 -1
  69. package/dist/server/server.d.ts.map +1 -1
  70. package/dist/server/server.js +7 -0
  71. package/dist/server_pages/otp.js +1 -1
  72. package/package.json +29 -14
@@ -1,11 +1,5 @@
1
- // file_description: provide shared utility helpers for the hazo_auth project
2
- import { clsx, type ClassValue } from "clsx";
3
- import { twMerge } from "tailwind-merge";
1
+ // file_description: re-exports cn and merge_class_names from hazo_ui (canonical source)
2
+ export { cn } from "hazo_ui";
4
3
 
5
- // section: tailwind_merge_helper
6
- export function merge_class_names(...inputs: ClassValue[]) {
7
- return twMerge(clsx(inputs));
8
- }
9
-
10
- // section: shadcn_compatibility_helper
11
- export const cn = (...inputs: ClassValue[]) => merge_class_names(...inputs);
4
+ // merge_class_names alias — kept for backward compatibility
5
+ export { cn as merge_class_names } from "hazo_ui";
@@ -729,3 +729,9 @@ company_name = My Company
729
729
  # [hazo_auth__login_layout]
730
730
  # image_src = /your-custom-image.jpg
731
731
 
732
+ ; ── Log level overrides (per hazo_logs D-015) ────────────────────────────────
733
+ ; Uncomment to tune log verbosity for specific namespaces.
734
+ ; Format: namespace = TRACE | DEBUG | INFO | WARN | ERROR
735
+ [log.overrides]
736
+ ; hazo_auth = DEBUG
737
+
@@ -1,5 +1,5 @@
1
1
  import * as React from "react";
2
- declare const InputOTP: React.ForwardRefExoticComponent<(Omit<Omit<React.InputHTMLAttributes<HTMLInputElement>, "maxLength" | "value" | "onChange" | "textAlign" | "onComplete" | "pushPasswordManagerStrategy" | "pasteTransformer" | "containerClassName" | "noScriptCSSFallback"> & {
2
+ declare const InputOTP: React.ForwardRefExoticComponent<(Omit<Omit<React.InputHTMLAttributes<HTMLInputElement>, "value" | "onChange" | "maxLength" | "textAlign" | "onComplete" | "pushPasswordManagerStrategy" | "pasteTransformer" | "containerClassName" | "noScriptCSSFallback"> & {
3
3
  value?: string;
4
4
  onChange?: (newValue: string) => unknown;
5
5
  maxLength: number;
@@ -12,7 +12,7 @@ declare const InputOTP: React.ForwardRefExoticComponent<(Omit<Omit<React.InputHT
12
12
  } & {
13
13
  render: (props: import("input-otp").RenderProps) => React.ReactNode;
14
14
  children?: never;
15
- } & React.RefAttributes<HTMLInputElement>, "ref"> | Omit<Omit<React.InputHTMLAttributes<HTMLInputElement>, "maxLength" | "value" | "onChange" | "textAlign" | "onComplete" | "pushPasswordManagerStrategy" | "pasteTransformer" | "containerClassName" | "noScriptCSSFallback"> & {
15
+ } & React.RefAttributes<HTMLInputElement>, "ref"> | Omit<Omit<React.InputHTMLAttributes<HTMLInputElement>, "value" | "onChange" | "maxLength" | "textAlign" | "onComplete" | "pushPasswordManagerStrategy" | "pasteTransformer" | "containerClassName" | "noScriptCSSFallback"> & {
16
16
  value?: string;
17
17
  onChange?: (newValue: string) => unknown;
18
18
  maxLength: number;
@@ -7,7 +7,7 @@ declare const SheetClose: React.ForwardRefExoticComponent<SheetPrimitive.DialogC
7
7
  declare const SheetPortal: React.FC<SheetPrimitive.DialogPortalProps>;
8
8
  declare const SheetOverlay: React.ForwardRefExoticComponent<Omit<SheetPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
9
9
  declare const SheetContent: React.ForwardRefExoticComponent<Omit<SheetPrimitive.DialogContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & VariantProps<(props?: ({
10
- side?: "left" | "right" | "top" | "bottom" | null | undefined;
10
+ side?: "top" | "right" | "bottom" | "left" | null | undefined;
11
11
  } & import("class-variance-authority/types").ClassProp) | undefined) => string> & React.RefAttributes<HTMLDivElement>>;
12
12
  declare const SheetHeader: {
13
13
  ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
@@ -1,7 +1,6 @@
1
- import "server-only";
2
1
  /**
3
2
  * Returns the hazo_auth logger instance
4
- * Uses hazo_logs for consistent logging across hazo packages
3
+ * Uses hazo_core for consistent logging across hazo packages
5
4
  */
6
- export declare const create_app_logger: () => import("hazo_logs").Logger;
5
+ export declare const create_app_logger: () => import("hazo_core").HazoCoreLogger;
7
6
  //# sourceMappingURL=app_logger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"app_logger.d.ts","sourceRoot":"","sources":["../../src/lib/app_logger.ts"],"names":[],"mappings":"AAEA,OAAO,aAAa,CAAC;AASrB;;;GAGG;AACH,eAAO,MAAM,iBAAiB,kCAAe,CAAC"}
1
+ {"version":3,"file":"app_logger.d.ts","sourceRoot":"","sources":["../../src/lib/app_logger.ts"],"names":[],"mappings":"AAQA;;;GAGG;AACH,eAAO,MAAM,iBAAiB,0CAAe,CAAC"}
@@ -1,13 +1,11 @@
1
- // file_description: server-only wrapper for the main app logging service using hazo_logs
2
- // section: server-only-guard
3
- import "server-only";
1
+ // file_description: server-only wrapper for the main app logging service using hazo_core
4
2
  // section: imports
5
- import { createLogger } from "hazo_logs";
3
+ import { createLogger } from "hazo_core";
6
4
  // section: logger_instance
7
5
  // Create a singleton logger for the hazo_auth package
8
6
  const logger = createLogger("hazo_auth");
9
7
  /**
10
8
  * Returns the hazo_auth logger instance
11
- * Uses hazo_logs for consistent logging across hazo packages
9
+ * Uses hazo_core for consistent logging across hazo packages
12
10
  */
13
11
  export const create_app_logger = () => logger;
@@ -1 +1 @@
1
- {"version":3,"file":"auth_utils.server.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/auth_utils.server.ts"],"names":[],"mappings":"AAEA,OAAO,aAAa,CAAC;AAGrB,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAOxD,MAAM,MAAM,QAAQ,GAAG;IACrB,aAAa,EAAE,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,cAAc,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;CAC/D,CAAC;AAEF,MAAM,MAAM,UAAU,GAClB,QAAQ,GACR;IAAE,aAAa,EAAE,KAAK,CAAA;CAAE,CAAC;AAmB7B;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CA8CtF;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAG7E;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAQ1E;AAED;;;;;GAKG;AACH,wBAAsB,oCAAoC,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC;IACxF,WAAW,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB,CAAC,CA6DD"}
1
+ {"version":3,"file":"auth_utils.server.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/auth_utils.server.ts"],"names":[],"mappings":"AAEA,OAAO,aAAa,CAAC;AAGrB,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQxD,MAAM,MAAM,QAAQ,GAAG;IACrB,aAAa,EAAE,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,cAAc,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;CAC/D,CAAC;AAEF,MAAM,MAAM,UAAU,GAClB,QAAQ,GACR;IAAE,aAAa,EAAE,KAAK,CAAA;CAAE,CAAC;AAmB7B;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CA8CtF;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAG7E;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAQ1E;AAED;;;;;GAKG;AACH,wBAAsB,oCAAoC,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC;IACxF,WAAW,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB,CAAC,CA6DD"}
@@ -3,6 +3,7 @@
3
3
  import "server-only";
4
4
  // section: imports
5
5
  import { NextResponse } from "next/server";
6
+ import { HazoAuthError } from "hazo_core";
6
7
  import { get_hazo_connect_instance } from "../hazo_connect_instance.server.js";
7
8
  import { createCrudService } from "hazo_connect/server";
8
9
  import { map_db_source_to_ui } from "../services/profile_picture_source_mapper.js";
@@ -89,7 +90,7 @@ export async function is_authenticated(request) {
89
90
  export async function require_auth(request) {
90
91
  const result = await get_authenticated_user(request);
91
92
  if (!result.authenticated) {
92
- throw new Error("Authentication required");
93
+ throw new HazoAuthError({ code: 'HAZO_AUTH_FORBIDDEN', pkg: 'hazo_auth', message: 'Authentication required' });
93
94
  }
94
95
  return result;
95
96
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ensure_anon_id.server.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/ensure_anon_id.server.ts"],"names":[],"mappings":"AAqBA,OAAO,aAAa,CAAC;AAGrB,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAgB1C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CA8B1E"}
1
+ {"version":3,"file":"ensure_anon_id.server.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/ensure_anon_id.server.ts"],"names":[],"mappings":"AAqBA,OAAO,aAAa,CAAC;AAGrB,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAiB1C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CA8B1E"}
@@ -20,6 +20,7 @@
20
20
  // section: server-only-guard
21
21
  import "server-only";
22
22
  import { cookies } from "next/headers";
23
+ import { generateRequestId } from "hazo_core";
23
24
  import { BASE_COOKIE_NAMES, get_cookie_name, get_cookie_options, } from "../cookies_config.server.js";
24
25
  // section: constants
25
26
  const TWO_YEARS_SECONDS = 60 * 60 * 24 * 365 * 2;
@@ -58,7 +59,7 @@ export async function ensure_anon_id(request) {
58
59
  return existing;
59
60
  }
60
61
  // Issue a new id and queue the Set-Cookie via the next/headers cookie store.
61
- const new_id = crypto.randomUUID();
62
+ const new_id = generateRequestId().slice(4);
62
63
  const cookie_options = get_cookie_options({
63
64
  httpOnly: true,
64
65
  secure: process.env.NODE_ENV === "production",
@@ -1 +1 @@
1
- {"version":3,"file":"hazo_get_auth.server.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/hazo_get_auth.server.ts"],"names":[],"mappings":"AAEA,OAAO,aAAa,CAAC;AAGrB,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAK1C,OAAO,KAAK,EACV,cAAc,EAEd,eAAe,EAGhB,MAAM,cAAc,CAAC;AA+DtB;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAU1D;AA6SD;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,cAAc,CAAC,CAmNzB"}
1
+ {"version":3,"file":"hazo_get_auth.server.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/hazo_get_auth.server.ts"],"names":[],"mappings":"AAEA,OAAO,aAAa,CAAC;AAGrB,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAM1C,OAAO,KAAK,EACV,cAAc,EAEd,eAAe,EAGhB,MAAM,cAAc,CAAC;AA+DtB;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAU1D;AA6SD;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,cAAc,CAAC,CAyNzB"}
@@ -1,6 +1,7 @@
1
1
  // file_description: server-side implementation of hazo_get_auth utility for API routes
2
2
  // section: server-only-guard
3
3
  import "server-only";
4
+ import { HazoNotFoundError, HazoAuthError, HazoRateLimitError, getCorrelationId } from "hazo_core";
4
5
  import { get_hazo_connect_instance } from "../hazo_connect_instance.server.js";
5
6
  import { createCrudService } from "hazo_connect/server";
6
7
  import { create_app_logger } from "../app_logger.js";
@@ -134,12 +135,12 @@ async function fetch_user_data_from_db(user_id) {
134
135
  // Fetch user
135
136
  const users = await users_service.findBy({ id: user_id });
136
137
  if (!Array.isArray(users) || users.length === 0) {
137
- throw new Error("User not found");
138
+ throw new HazoNotFoundError({ code: 'HAZO_AUTH_USER_NOT_FOUND', pkg: 'hazo_auth', message: 'User not found' });
138
139
  }
139
140
  const user_db = users[0];
140
141
  // Check if user is active (status must be 'ACTIVE')
141
142
  if (user_db.status !== "ACTIVE") {
142
- throw new Error("User is inactive");
143
+ throw new HazoAuthError({ code: 'HAZO_AUTH_FORBIDDEN', pkg: 'hazo_auth', message: 'User account is inactive' });
143
144
  }
144
145
  // Build user object
145
146
  const user = {
@@ -332,6 +333,7 @@ export async function hazo_get_auth(request, options) {
332
333
  line_number: get_line_number(),
333
334
  error: token_error_message,
334
335
  note: "Falling back to simple cookie check",
336
+ correlation_id: getCorrelationId(),
335
337
  });
336
338
  }
337
339
  }
@@ -349,8 +351,9 @@ export async function hazo_get_auth(request, options) {
349
351
  filename: get_filename(),
350
352
  line_number: get_line_number(),
351
353
  ip: client_ip,
354
+ correlation_id: getCorrelationId(),
352
355
  });
353
- throw new Error("Rate limit exceeded. Please try again later.");
356
+ throw new HazoRateLimitError({ code: 'HAZO_AUTH_RATE_LIMITED', pkg: 'hazo_auth', message: 'Rate limit exceeded. Please try again later.' });
354
357
  }
355
358
  return {
356
359
  authenticated: false,
@@ -366,8 +369,9 @@ export async function hazo_get_auth(request, options) {
366
369
  filename: get_filename(),
367
370
  line_number: get_line_number(),
368
371
  user_id,
372
+ correlation_id: getCorrelationId(),
369
373
  });
370
- throw new Error("Rate limit exceeded. Please try again later.");
374
+ throw new HazoRateLimitError({ code: 'HAZO_AUTH_RATE_LIMITED', pkg: 'hazo_auth', message: 'Rate limit exceeded. Please try again later.' });
371
375
  }
372
376
  // Check cache
373
377
  let cached_entry = cache.get(user_id);
@@ -397,6 +401,7 @@ export async function hazo_get_auth(request, options) {
397
401
  line_number: get_line_number(),
398
402
  user_id,
399
403
  error: error_message,
404
+ correlation_id: getCorrelationId(),
400
405
  });
401
406
  return {
402
407
  authenticated: false,
@@ -424,6 +429,7 @@ export async function hazo_get_auth(request, options) {
424
429
  missing_permissions,
425
430
  user_permissions: permissions,
426
431
  ip: client_ip,
432
+ correlation_id: getCorrelationId(),
427
433
  });
428
434
  }
429
435
  // Throw error if strict mode
@@ -452,6 +458,7 @@ export async function hazo_get_auth(request, options) {
452
458
  scope_id: options.scope_id,
453
459
  user_scopes: scope_result.user_scopes,
454
460
  ip: client_ip,
461
+ correlation_id: getCorrelationId(),
455
462
  });
456
463
  }
457
464
  // Throw error if strict mode and scope access denied
@@ -0,0 +1,44 @@
1
+ import { z } from 'zod';
2
+ declare const HazoAuthCoreConfigSchema: z.ZodObject<{
3
+ hazo_auth__tokens: z.ZodPipe<z.ZodOptional<z.ZodObject<{
4
+ access_token_ttl_seconds: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<number, string | undefined>>;
5
+ refresh_token_ttl_seconds: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<number, string | undefined>>;
6
+ }, z.core.$strip>>, z.ZodTransform<{
7
+ access_token_ttl_seconds: number;
8
+ refresh_token_ttl_seconds: number;
9
+ }, {
10
+ access_token_ttl_seconds: number;
11
+ refresh_token_ttl_seconds: number;
12
+ } | undefined>>;
13
+ hazo_auth__cookies: z.ZodPipe<z.ZodOptional<z.ZodObject<{
14
+ cookie_prefix: z.ZodDefault<z.ZodOptional<z.ZodString>>;
15
+ cookie_domain: z.ZodDefault<z.ZodOptional<z.ZodString>>;
16
+ }, z.core.$strip>>, z.ZodTransform<{
17
+ cookie_prefix: string;
18
+ cookie_domain: string;
19
+ }, {
20
+ cookie_prefix: string;
21
+ cookie_domain: string;
22
+ } | undefined>>;
23
+ hazo_auth__rate_limit: z.ZodPipe<z.ZodOptional<z.ZodObject<{
24
+ max_attempts: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<number, string | undefined>>;
25
+ window_minutes: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<number, string | undefined>>;
26
+ }, z.core.$strip>>, z.ZodTransform<{
27
+ max_attempts: number;
28
+ window_minutes: number;
29
+ }, {
30
+ max_attempts: number;
31
+ window_minutes: number;
32
+ } | undefined>>;
33
+ log: z.ZodPipe<z.ZodOptional<z.ZodObject<{
34
+ overrides: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
35
+ }, z.core.$strip>>, z.ZodTransform<{
36
+ overrides: Record<string, string>;
37
+ }, {
38
+ overrides: Record<string, string>;
39
+ } | undefined>>;
40
+ }, z.core.$strip>;
41
+ export type HazoAuthCoreConfig = z.infer<typeof HazoAuthCoreConfigSchema>;
42
+ export declare function getHazoAuthCoreConfig(): HazoAuthCoreConfig;
43
+ export {};
44
+ //# sourceMappingURL=hazo_auth_core_config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hazo_auth_core_config.d.ts","sourceRoot":"","sources":["../../../src/lib/config/hazo_auth_core_config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,QAAA,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4B5B,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,wBAAgB,qBAAqB,IAAI,kBAAkB,CAK1D"}
@@ -0,0 +1,40 @@
1
+ // file_description: Zod-validated config loader for hazo_auth core settings.
2
+ // Covers server-critical sections ([hazo_auth__tokens], [hazo_auth__cookies], [hazo_auth__rate_limit], [log.overrides]).
3
+ // UI sections (login_layout, register_layout, etc.) are still handled by config_loader.server.ts.
4
+ import { z } from 'zod';
5
+ import { loadConfig } from 'hazo_core';
6
+ const HazoAuthCoreConfigSchema = z.object({
7
+ hazo_auth__tokens: z
8
+ .object({
9
+ access_token_ttl_seconds: z.string().optional().transform(v => v ? parseInt(v, 10) : 900),
10
+ refresh_token_ttl_seconds: z.string().optional().transform(v => v ? parseInt(v, 10) : 2592000),
11
+ })
12
+ .optional()
13
+ .transform(v => v !== null && v !== void 0 ? v : { access_token_ttl_seconds: 900, refresh_token_ttl_seconds: 2592000 }),
14
+ hazo_auth__cookies: z
15
+ .object({
16
+ cookie_prefix: z.string().optional().default(''),
17
+ cookie_domain: z.string().optional().default(''),
18
+ })
19
+ .optional()
20
+ .transform(v => v !== null && v !== void 0 ? v : { cookie_prefix: '', cookie_domain: '' }),
21
+ hazo_auth__rate_limit: z
22
+ .object({
23
+ max_attempts: z.string().optional().transform(v => v ? parseInt(v, 10) : 5),
24
+ window_minutes: z.string().optional().transform(v => v ? parseInt(v, 10) : 5),
25
+ })
26
+ .optional()
27
+ .transform(v => v !== null && v !== void 0 ? v : { max_attempts: 5, window_minutes: 5 }),
28
+ log: z
29
+ .object({
30
+ overrides: z.record(z.string(), z.string()).optional().default({}),
31
+ })
32
+ .optional()
33
+ .transform(v => v !== null && v !== void 0 ? v : { overrides: {} }),
34
+ });
35
+ export function getHazoAuthCoreConfig() {
36
+ return loadConfig({
37
+ pkg: 'hazo_auth',
38
+ schema: HazoAuthCoreConfigSchema,
39
+ });
40
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"cookies_config.server.d.ts","sourceRoot":"","sources":["../../src/lib/cookies_config.server.ts"],"names":[],"mappings":"AAEA,OAAO,aAAa,CAAC;AAMrB,MAAM,MAAM,aAAa,GAAG;IAC1B,6FAA6F;IAC7F,aAAa,EAAE,MAAM,CAAC;IACtB,6EAA6E;IAC7E,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAYF,eAAO,MAAM,iBAAiB;;;;;;;;CAQpB,CAAC;AAGX;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,aAAa,CAoBlD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAGzD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAQzG;AAKD;;;GAGG;AACH,wBAAgB,yBAAyB,IAAI,aAAa,CAKzD;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,IAAI,CAEjD"}
1
+ {"version":3,"file":"cookies_config.server.d.ts","sourceRoot":"","sources":["../../src/lib/cookies_config.server.ts"],"names":[],"mappings":"AAEA,OAAO,aAAa,CAAC;AAMrB,MAAM,MAAM,aAAa,GAAG;IAC1B,6FAA6F;IAC7F,aAAa,EAAE,MAAM,CAAC;IACtB,6EAA6E;IAC7E,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAYF,eAAO,MAAM,iBAAiB;;;;;;;;CAQpB,CAAC;AAGX;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,aAAa,CAuBlD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAGzD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAQzG;AAKD;;;GAGG;AACH,wBAAgB,yBAAyB,IAAI,aAAa,CAKzD;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,IAAI,CAEjD"}
@@ -1,6 +1,7 @@
1
1
  // file_description: server-only helper to read cookie configuration from hazo_auth_config.ini
2
2
  // section: server-only-guard
3
3
  import "server-only";
4
+ import { HazoConfigError } from "hazo_core";
4
5
  import { read_config_section } from "./config/config_loader.server.js";
5
6
  // section: defaults
6
7
  const DEFAULT_CONFIG = {
@@ -29,13 +30,17 @@ export function get_cookies_config() {
29
30
  const section = read_config_section(SECTION_NAME);
30
31
  const cookie_prefix = (section === null || section === void 0 ? void 0 : section.cookie_prefix) || "";
31
32
  if (!cookie_prefix) {
32
- throw new Error("[hazo_auth] cookie_prefix is required but not configured.\n" +
33
- "Set cookie_prefix in [hazo_auth__cookies] section of config/hazo_auth_config.ini:\n\n" +
34
- " [hazo_auth__cookies]\n" +
35
- " cookie_prefix = myapp_\n\n" +
36
- "Also set the matching environment variable for Edge runtime (middleware):\n" +
37
- " HAZO_AUTH_COOKIE_PREFIX=myapp_\n\n" +
38
- "This prevents cookie conflicts between apps using hazo_auth.");
33
+ throw new HazoConfigError({
34
+ code: 'HAZO_AUTH_CONFIG',
35
+ pkg: 'hazo_auth',
36
+ message: "[hazo_auth] cookie_prefix is required but not configured.\n" +
37
+ "Set cookie_prefix in [hazo_auth__cookies] section of config/hazo_auth_config.ini:\n\n" +
38
+ " [hazo_auth__cookies]\n" +
39
+ " cookie_prefix = myapp_\n\n" +
40
+ "Also set the matching environment variable for Edge runtime (middleware):\n" +
41
+ " HAZO_AUTH_COOKIE_PREFIX=myapp_\n\n" +
42
+ "This prevents cookie conflicts between apps using hazo_auth.",
43
+ });
39
44
  }
40
45
  return {
41
46
  cookie_prefix,
@@ -1 +1 @@
1
- {"version":3,"file":"hazo_connect_setup.server.d.ts","sourceRoot":"","sources":["../../src/lib/hazo_connect_setup.server.ts"],"names":[],"mappings":"AAEA,OAAO,aAAa,CAAC;AAsJrB;;;;GAIG;AACH,wBAAgB,iCAAiC,8CAuBhD;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,IAAI;IACjD,IAAI,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAsBA"}
1
+ {"version":3,"file":"hazo_connect_setup.server.d.ts","sourceRoot":"","sources":["../../src/lib/hazo_connect_setup.server.ts"],"names":[],"mappings":"AAEA,OAAO,aAAa,CAAC;AA8JrB;;;;GAIG;AACH,wBAAgB,iCAAiC,8CAuBhD;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,IAAI;IACjD,IAAI,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAsBA"}
@@ -5,6 +5,7 @@ import "server-only";
5
5
  // Reads configuration from hazo_auth_config.ini using hazo_config
6
6
  // section: imports
7
7
  import { createHazoConnect } from "hazo_connect/server";
8
+ import { HazoConfigError } from "hazo_core";
8
9
  import path from "path";
9
10
  import { create_app_logger } from "./app_logger.js";
10
11
  import { read_config_section } from "./config/config_loader.server.js";
@@ -52,8 +53,12 @@ function get_hazo_connect_config() {
52
53
  sqlite_path = path.normalize(fallback_sqlite_path);
53
54
  }
54
55
  else {
55
- throw new Error("[hazo_auth] sqlite_path not configured. Set sqlite_path in [hazo_connect] section of config/hazo_auth_config.ini, " +
56
- "or set HAZO_CONNECT_SQLITE_PATH environment variable.");
56
+ throw new HazoConfigError({
57
+ code: 'HAZO_AUTH_CONFIG',
58
+ pkg: 'hazo_auth',
59
+ message: "[hazo_auth] sqlite_path not configured. Set sqlite_path in [hazo_connect] section of config/hazo_auth_config.ini, " +
60
+ "or set HAZO_CONNECT_SQLITE_PATH environment variable.",
61
+ });
57
62
  }
58
63
  // Validate config keys for typos
59
64
  if (hazo_connect_section) {
@@ -96,7 +101,11 @@ function get_hazo_connect_config() {
96
101
  process.env.HAZO_CONNECT_POSTGREST_API_KEY ||
97
102
  process.env.POSTGREST_API_KEY;
98
103
  if (!postgrest_url) {
99
- throw new Error("PostgREST URL is required. Set postgrest_url in [hazo_connect] section of hazo_auth_config.ini or HAZO_CONNECT_POSTGREST_URL environment variable.");
104
+ throw new HazoConfigError({
105
+ code: 'HAZO_AUTH_CONFIG',
106
+ pkg: 'hazo_auth',
107
+ message: 'PostgREST URL is required. Set postgrest_url in [hazo_connect] section of hazo_auth_config.ini or HAZO_CONNECT_POSTGREST_URL environment variable.',
108
+ });
100
109
  }
101
110
  return {
102
111
  type: "postgrest",
@@ -105,7 +114,11 @@ function get_hazo_connect_config() {
105
114
  enableAdminUi,
106
115
  };
107
116
  }
108
- throw new Error(`Unsupported HAZO_CONNECT_TYPE: ${type}. Supported types: sqlite, postgrest`);
117
+ throw new HazoConfigError({
118
+ code: 'HAZO_AUTH_CONFIG',
119
+ pkg: 'hazo_auth',
120
+ message: `Unsupported HAZO_CONNECT_TYPE: ${type}. Supported types: sqlite, postgrest`,
121
+ });
109
122
  }
110
123
  /**
111
124
  * Server-only function to create hazo_connect adapter
@@ -130,7 +143,7 @@ export function create_sqlite_hazo_connect_server() {
130
143
  apiKey: apiKey, // Pass empty string if not set
131
144
  });
132
145
  }
133
- throw new Error(`Unsupported database type: ${config.type}`);
146
+ throw new HazoConfigError({ code: 'HAZO_AUTH_CONFIG', pkg: 'hazo_auth', message: `Unsupported database type: ${config.type}` });
134
147
  }
135
148
  /**
136
149
  * Gets hazo_connect configuration options for use with singleton API
@@ -1 +1 @@
1
- {"version":3,"file":"legal_docs_service.d.ts","sourceRoot":"","sources":["../../../src/lib/legal/legal_docs_service.ts"],"names":[],"mappings":"AAaA;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EAC1C,EAAE,EAAE,MAAM,GAAG,IAAI,EACjB,UAAU,EAAE,MAAM,GAAG,IAAI,GACxB,OAAO,CAAC,IAAI,CAAC,CAwCf;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,EACrB,oBAAoB,EAAE,MAAM,GAC3B,OAAO,CAAC;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,CA2BnC;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,GAAG,EACZ,QAAQ,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAoB1E;AAED;;GAEG;AACH,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,KAAK,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC,CAAC,CAeF;AAED;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAkB7C"}
1
+ {"version":3,"file":"legal_docs_service.d.ts","sourceRoot":"","sources":["../../../src/lib/legal/legal_docs_service.ts"],"names":[],"mappings":"AAcA;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EAC1C,EAAE,EAAE,MAAM,GAAG,IAAI,EACjB,UAAU,EAAE,MAAM,GAAG,IAAI,GACxB,OAAO,CAAC,IAAI,CAAC,CAwCf;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,EACrB,oBAAoB,EAAE,MAAM,GAC3B,OAAO,CAAC;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,CA2BnC;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,GAAG,EACZ,QAAQ,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAoB1E;AAED;;GAEG;AACH,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,KAAK,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC,CAAC,CAeF;AAED;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAkB7C"}
@@ -1,9 +1,10 @@
1
1
  // file_description: service functions for the legal document acceptance system
2
2
  // section: imports
3
3
  import { createCrudService } from 'hazo_connect/server';
4
+ import { generateRequestId } from 'hazo_core';
4
5
  // section: helpers
5
6
  function generate_id() {
6
- return crypto.randomUUID();
7
+ return generateRequestId().slice(4);
7
8
  }
8
9
  // section: exports
9
10
  /**
@@ -1,4 +1,4 @@
1
- import type { EmailerConfig } from "hazo_notify";
1
+ import type { EmailerConfig } from "hazo_notify/adapters/email";
2
2
  import type { HazoConnectInstance } from "hazo_notify/template_manager";
3
3
  export type EmailOptions = {
4
4
  to: string;
@@ -1 +1 @@
1
- {"version":3,"file":"email_service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/email_service.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAoB,MAAM,aAAa,CAAC;AACnE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAGxE,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,iBAAiB,GAAG,oBAAoB,GAAG,kBAAkB,GAAG,iBAAiB,CAAC;AAElH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACnC,CAAC;AAiBF;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAEpE;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAE3E;AAgMD;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAwErG;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,aAAa,EAAE,iBAAiB,EAChC,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAyF/C"}
1
+ {"version":3,"file":"email_service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/email_service.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAoB,MAAM,4BAA4B,CAAC;AAClF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAGxE,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,iBAAiB,GAAG,oBAAoB,GAAG,kBAAkB,GAAG,iBAAiB,CAAC;AAElH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACnC,CAAC;AAiBF;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAEpE;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAE3E;AAmMD;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA4ErG;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,aAAa,EAAE,iBAAiB,EAChC,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA4F/C"}
@@ -1,6 +1,7 @@
1
1
  // file_description: service for sending emails with template support
2
2
  // section: imports
3
3
  import { create_app_logger } from "../app_logger.js";
4
+ import { HazoConfigError, optional_import } from "hazo_core";
4
5
  import { read_config_section } from "../config/config_loader.server.js";
5
6
  // section: singleton
6
7
  /**
@@ -49,8 +50,11 @@ async function get_hazo_notify_instance() {
49
50
  });
50
51
  try {
51
52
  // Dynamic import to avoid build-time issues with hazo_notify
52
- const hazo_notify_module = await import("hazo_notify");
53
- const { load_emailer_config } = hazo_notify_module;
53
+ const hazo_notify_email_module = await optional_import('hazo_notify/adapters/email');
54
+ if (!hazo_notify_email_module) {
55
+ throw new Error("hazo_notify is not installed");
56
+ }
57
+ const { load_emailer_config } = hazo_notify_email_module;
54
58
  hazo_notify_config = load_emailer_config();
55
59
  }
56
60
  catch (error) {
@@ -60,7 +64,7 @@ async function get_hazo_notify_instance() {
60
64
  line_number: 0,
61
65
  error: error_message,
62
66
  });
63
- throw new Error(`Failed to load hazo_notify config: ${error_message}`);
67
+ throw new HazoConfigError({ code: 'HAZO_AUTH_CONFIG', pkg: 'hazo_auth', message: `Failed to load hazo_notify config: ${error_message}` });
64
68
  }
65
69
  }
66
70
  return hazo_notify_config;
@@ -217,8 +221,12 @@ export async function send_email(options) {
217
221
  // Get hazo_notify configuration instance
218
222
  const notify_config = await get_hazo_notify_instance();
219
223
  // Dynamic import to avoid build-time issues with hazo_notify
220
- const hazo_notify_module = await import("hazo_notify");
221
- const { send_email: hazo_notify_send_email } = hazo_notify_module;
224
+ const hazo_notify_email_module = await optional_import('hazo_notify/adapters/email');
225
+ if (!hazo_notify_email_module) {
226
+ throw new Error("hazo_notify is not installed");
227
+ }
228
+ const { get_email_provider } = hazo_notify_email_module;
229
+ const provider = get_email_provider(notify_config);
222
230
  // Get from email and from name (hazo_auth_config overrides hazo_notify_config)
223
231
  // Priority: 1. options.from (explicit parameter), 2. hazo_auth_config.from_email, 3. hazo_notify_config.from_email
224
232
  const from_email = options.from || await get_email_from(notify_config);
@@ -233,7 +241,7 @@ export async function send_email(options) {
233
241
  from_name: from_name,
234
242
  };
235
243
  // Send email using hazo_notify
236
- const result = await hazo_notify_send_email(hazo_notify_options, notify_config);
244
+ const result = await provider.send_email(hazo_notify_options, notify_config);
237
245
  if (result.success) {
238
246
  logger.info("email_sent", {
239
247
  filename: "email_service.ts",
@@ -306,9 +314,13 @@ export async function send_template_email(template_type, to, data) {
306
314
  }
307
315
  }
308
316
  if (!hazo_notify_connect) {
309
- throw new Error("hazo_notify connect not initialized. Call set_hazo_notify_connect() " +
310
- "from instrumentation.ts with the same HazoConnectInstance you pass " +
311
- "to init_template_manager({ hazo_connect_factory }).");
317
+ throw new HazoConfigError({
318
+ code: 'HAZO_AUTH_CONFIG',
319
+ pkg: 'hazo_auth',
320
+ message: "hazo_notify connect not initialized. Call set_hazo_notify_connect() " +
321
+ "from instrumentation.ts with the same HazoConnectInstance you pass " +
322
+ "to init_template_manager({ hazo_connect_factory }).",
323
+ });
312
324
  }
313
325
  const notify_config = await get_hazo_notify_instance();
314
326
  const from = await get_email_from(notify_config);
@@ -1 +1 @@
1
- {"version":3,"file":"firm_service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/firm_service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAIvD,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAIzE,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAWF;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAqEjE;AAqFD;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,kBAAkB,EAC3B,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,gBAAgB,CAAC,CA4E3B;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,kBAAkB,EAC3B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAmCjE"}
1
+ {"version":3,"file":"firm_service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/firm_service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAKvD,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAIzE,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAWF;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAqEjE;AAqFD;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,kBAAkB,EAC3B,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,gBAAgB,CAAC,CA4E3B;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,kBAAkB,EAC3B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAmCjE"}
@@ -1,4 +1,5 @@
1
1
  import { createCrudService } from "hazo_connect/server";
2
+ import { generateRequestId } from "hazo_core";
2
3
  import { create_app_logger } from "../app_logger.js";
3
4
  import { sanitize_error_for_user } from "../utils/error_sanitizer.js";
4
5
  import { create_scope } from "./scope_service.js";
@@ -101,7 +102,7 @@ async function assign_owner_permissions(adapter, role_id) {
101
102
  let permission_id;
102
103
  if (!Array.isArray(permissions) || permissions.length === 0) {
103
104
  // Create permission with generated UUID
104
- const perm_id = crypto.randomUUID();
105
+ const perm_id = generateRequestId().slice(4);
105
106
  const inserted = await permission_service.insert({
106
107
  id: perm_id,
107
108
  permission_name: perm_name,
@@ -1 +1 @@
1
- {"version":3,"file":"otp_service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/otp_service.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAUrB;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAG1C;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEjE;AAED,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAMtF;AAID,MAAM,MAAM,qBAAqB,GAC7B;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GACZ;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,cAAc,CAAC;IAAC,mBAAmB,EAAE,MAAM,CAAA;CAAE,CAAC;AAItE;;;;;;;;;;;GAWG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;CACZ,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAmHjC;AAID,MAAM,MAAM,oBAAoB,GAC5B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GACnE;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,oBAAoB,GAAG,SAAS,CAAA;CAAE,CAAC;AAE3D,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAsHhC"}
1
+ {"version":3,"file":"otp_service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/otp_service.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAWrB;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAG1C;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEjE;AAED,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAMtF;AAID,MAAM,MAAM,qBAAqB,GAC7B;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GACZ;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,cAAc,CAAC;IAAC,mBAAmB,EAAE,MAAM,CAAA;CAAE,CAAC;AAItE;;;;;;;;;;;GAWG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;CACZ,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAmHjC;AAID,MAAM,MAAM,oBAAoB,GAC5B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GACnE;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,oBAAoB,GAAG,SAAS,CAAA;CAAE,CAAC;AAE3D,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAsHhC"}
@@ -1,5 +1,6 @@
1
1
  import "server-only";
2
2
  import crypto from "node:crypto";
3
+ import { generateRequestId } from "hazo_core";
3
4
  import argon2 from "argon2";
4
5
  import { createCrudService } from "hazo_connect/server";
5
6
  import { get_otp_config, hazo_auth_otp_session_ttl_seconds } from "../otp_config.server.js";
@@ -102,7 +103,7 @@ export async function request_email_otp(args) {
102
103
  const code = generate_otp_code();
103
104
  const otp_hash = await hash_otp_code(code);
104
105
  const expires_at = new Date(Date.now() + cfg.code_ttl_seconds * 1000).toISOString();
105
- const row_id = crypto.randomUUID();
106
+ const row_id = generateRequestId().slice(4);
106
107
  await otp_table.insert({
107
108
  id: row_id,
108
109
  user_id: existing_user ? String(existing_user.id) : null,
@@ -191,7 +192,7 @@ export async function verify_email_otp(args) {
191
192
  }
192
193
  else if (cfg.auto_register) {
193
194
  // Create user + bind scope/role
194
- const new_user_id = crypto.randomUUID();
195
+ const new_user_id = generateRequestId().slice(4);
195
196
  await users_table.insert({
196
197
  id: new_user_id,
197
198
  email_address: email,
@@ -1 +1 @@
1
- {"version":3,"file":"profile_picture_service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/profile_picture_service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AASvD,OAAO,EAAuB,KAAK,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAGnG,MAAM,MAAM,oBAAoB,GAAG,sBAAsB,CAAC;AAE1D,MAAM,MAAM,2BAA2B,GAAG;IACxC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,oBAAoB,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,SAAS,GAAG,cAAc,CAAC;CACpC,CAAC;AA2DF;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAOrE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,CAyBjD;AAED;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,MAAU,EAChB,SAAS,GAAE,MAAW,GACrB,mBAAmB,CA6FrB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAI7D;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAcxF;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,SAAS,GAAG,cAAc,GAAG,IAAI,CAGtE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAG1C;AA4DD,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,2BAA2B,GAAG,IAAI,CAAC,CA+D7C;AAED;;;;;;;GAOG;AACH,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,kBAAkB,EAC3B,OAAO,EAAE,MAAM,EACf,mBAAmB,EAAE,MAAM,EAC3B,cAAc,EAAE,oBAAoB,GACnC,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAsB/C"}
1
+ {"version":3,"file":"profile_picture_service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/profile_picture_service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAUvD,OAAO,EAAuB,KAAK,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAGnG,MAAM,MAAM,oBAAoB,GAAG,sBAAsB,CAAC;AAE1D,MAAM,MAAM,2BAA2B,GAAG;IACxC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,oBAAoB,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,SAAS,GAAG,cAAc,CAAC;CACpC,CAAC;AA2DF;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAOrE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,CAyBjD;AAED;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,MAAU,EAChB,SAAS,GAAE,MAAW,GACrB,mBAAmB,CA6FrB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAI7D;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAcxF;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,SAAS,GAAG,cAAc,GAAG,IAAI,CAGtE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAG1C;AA4DD,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,2BAA2B,GAAG,IAAI,CAAC,CA+D7C;AAED;;;;;;;GAOG;AACH,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,kBAAkB,EAC3B,OAAO,EAAE,MAAM,EACf,mBAAmB,EAAE,MAAM,EAC3B,cAAc,EAAE,oBAAoB,GACnC,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAsB/C"}
@@ -1,5 +1,6 @@
1
1
  import { createCrudService } from "hazo_connect/server";
2
2
  import gravatarUrl from "gravatar-url";
3
+ import { fetchWithRequestId } from "hazo_core";
3
4
  import { get_profile_picture_config } from "../profile_picture_config.server.js";
4
5
  import { get_ui_sizes_config } from "../ui_sizes_config.server.js";
5
6
  import { get_file_types_config } from "../file_types_config.server.js";
@@ -248,7 +249,7 @@ async function check_gravatar_exists(email) {
248
249
  const uiSizes = get_ui_sizes_config();
249
250
  const gravatar_url = get_gravatar_url(email, uiSizes.gravatar_size);
250
251
  // Make HEAD request to check if image exists without downloading it
251
- const response = await fetch(gravatar_url, {
252
+ const response = await fetchWithRequestId(gravatar_url, {
252
253
  method: 'HEAD',
253
254
  // Add timeout to prevent hanging
254
255
  signal: AbortSignal.timeout(5000) // 5 second timeout