@sonicjs-cms/core 3.0.0-beta.14 → 3.0.0-beta.16

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 (87) hide show
  1. package/dist/{app-Bo0X1OWX.d.ts → app-01M0dIwt.d.ts} +1 -1
  2. package/dist/{app-Do66yCcV.d.cts → app-aj39TGHB.d.cts} +1 -1
  3. package/dist/{chunk-SIPBHWMG.cjs → chunk-3XFA3E2F.cjs} +4 -4
  4. package/dist/{chunk-SIPBHWMG.cjs.map → chunk-3XFA3E2F.cjs.map} +1 -1
  5. package/dist/{chunk-QNPT6BQP.js → chunk-7P2IJM4K.js} +3 -3
  6. package/dist/{chunk-QNPT6BQP.js.map → chunk-7P2IJM4K.js.map} +1 -1
  7. package/dist/{chunk-32SDMKZ7.js → chunk-HYO2MSFI.js} +2 -2
  8. package/dist/{chunk-32SDMKZ7.js.map → chunk-HYO2MSFI.js.map} +1 -1
  9. package/dist/{chunk-H5FB6GKR.cjs → chunk-IA24HACT.cjs} +2 -2
  10. package/dist/{chunk-H5FB6GKR.cjs.map → chunk-IA24HACT.cjs.map} +1 -1
  11. package/dist/{chunk-75JKPNUZ.js → chunk-IQZA2OY5.js} +3 -3
  12. package/dist/{chunk-75JKPNUZ.js.map → chunk-IQZA2OY5.js.map} +1 -1
  13. package/dist/{chunk-5L6EMI7A.js → chunk-IXUNNFZZ.js} +6 -5
  14. package/dist/chunk-IXUNNFZZ.js.map +1 -0
  15. package/dist/{chunk-U7T5EOHJ.js → chunk-JRMBHDGM.js} +4 -4
  16. package/dist/{chunk-U7T5EOHJ.js.map → chunk-JRMBHDGM.js.map} +1 -1
  17. package/dist/{chunk-INE5E3SL.js → chunk-KIB7K5LV.js} +27 -2
  18. package/dist/chunk-KIB7K5LV.js.map +1 -0
  19. package/dist/{chunk-ZTEJHSYS.cjs → chunk-KMCLNO4K.cjs} +5 -5
  20. package/dist/{chunk-ZTEJHSYS.cjs.map → chunk-KMCLNO4K.cjs.map} +1 -1
  21. package/dist/{chunk-L3KHLEHL.cjs → chunk-KMM45BTY.cjs} +53 -15
  22. package/dist/chunk-KMM45BTY.cjs.map +1 -0
  23. package/dist/{chunk-4YRYGDCQ.cjs → chunk-KOXFYFOF.cjs} +4 -4
  24. package/dist/{chunk-4YRYGDCQ.cjs.map → chunk-KOXFYFOF.cjs.map} +1 -1
  25. package/dist/{chunk-WIV3R2MJ.cjs → chunk-KZIBF2EV.cjs} +27 -2
  26. package/dist/chunk-KZIBF2EV.cjs.map +1 -0
  27. package/dist/{chunk-G5LC7MYH.cjs → chunk-LXYDJU6U.cjs} +12 -11
  28. package/dist/chunk-LXYDJU6U.cjs.map +1 -0
  29. package/dist/{chunk-O32IZ6JS.js → chunk-PA2UIFB7.js} +43 -5
  30. package/dist/chunk-PA2UIFB7.js.map +1 -0
  31. package/dist/{chunk-SSOP7G4R.cjs → chunk-SC2WZFNQ.cjs} +309 -243
  32. package/dist/chunk-SC2WZFNQ.cjs.map +1 -0
  33. package/dist/{chunk-HNUGMALL.js → chunk-UOFRE5PY.js} +104 -39
  34. package/dist/chunk-UOFRE5PY.js.map +1 -0
  35. package/dist/{chunk-IESEVHXL.js → chunk-VVYVFCML.js} +12 -3
  36. package/dist/chunk-VVYVFCML.js.map +1 -0
  37. package/dist/{chunk-HIKBY7MS.cjs → chunk-XWVDSM2L.cjs} +12 -3
  38. package/dist/chunk-XWVDSM2L.cjs.map +1 -0
  39. package/dist/config-SM2UWSDN.js +6 -0
  40. package/dist/{config-PLJTDINX.js.map → config-SM2UWSDN.js.map} +1 -1
  41. package/dist/config-YCRSU7ZP.cjs +19 -0
  42. package/dist/{config-FLOUCYHH.cjs.map → config-YCRSU7ZP.cjs.map} +1 -1
  43. package/dist/{define-plugin-BzNHc1ZI.d.ts → define-plugin-BYIey6sp.d.ts} +1 -1
  44. package/dist/{define-plugin-IWDKYaVm.d.cts → define-plugin-DsKiGu1q.d.cts} +1 -1
  45. package/dist/index.cjs +775 -297
  46. package/dist/index.cjs.map +1 -1
  47. package/dist/index.d.cts +194 -7
  48. package/dist/index.d.ts +194 -7
  49. package/dist/index.js +527 -59
  50. package/dist/index.js.map +1 -1
  51. package/dist/middleware.cjs +33 -33
  52. package/dist/middleware.d.cts +2 -2
  53. package/dist/middleware.d.ts +2 -2
  54. package/dist/middleware.js +4 -4
  55. package/dist/migrations-F4LBAHQN.js +4 -0
  56. package/dist/{migrations-DOPZXFK3.js.map → migrations-F4LBAHQN.js.map} +1 -1
  57. package/dist/migrations-KMCULV6H.cjs +13 -0
  58. package/dist/{migrations-TYYC66P4.cjs.map → migrations-KMCULV6H.cjs.map} +1 -1
  59. package/dist/plugins.cjs +40 -40
  60. package/dist/plugins.d.cts +2 -2
  61. package/dist/plugins.d.ts +2 -2
  62. package/dist/plugins.js +3 -3
  63. package/dist/routes.cjs +27 -27
  64. package/dist/routes.d.cts +2 -2
  65. package/dist/routes.d.ts +2 -2
  66. package/dist/routes.js +7 -7
  67. package/dist/services.cjs +18 -18
  68. package/dist/services.js +2 -2
  69. package/dist/{types-Dea1eNxU.d.cts → types-DT7XN5TX.d.cts} +1 -1
  70. package/dist/{types-Dea1eNxU.d.ts → types-DT7XN5TX.d.ts} +1 -1
  71. package/dist/utils.cjs +3 -3
  72. package/dist/utils.js +1 -1
  73. package/package.json +2 -2
  74. package/dist/chunk-5L6EMI7A.js.map +0 -1
  75. package/dist/chunk-G5LC7MYH.cjs.map +0 -1
  76. package/dist/chunk-HIKBY7MS.cjs.map +0 -1
  77. package/dist/chunk-HNUGMALL.js.map +0 -1
  78. package/dist/chunk-IESEVHXL.js.map +0 -1
  79. package/dist/chunk-INE5E3SL.js.map +0 -1
  80. package/dist/chunk-L3KHLEHL.cjs.map +0 -1
  81. package/dist/chunk-O32IZ6JS.js.map +0 -1
  82. package/dist/chunk-SSOP7G4R.cjs.map +0 -1
  83. package/dist/chunk-WIV3R2MJ.cjs.map +0 -1
  84. package/dist/config-FLOUCYHH.cjs +0 -19
  85. package/dist/config-PLJTDINX.js +0 -6
  86. package/dist/migrations-DOPZXFK3.js +0 -4
  87. package/dist/migrations-TYYC66P4.cjs +0 -13
@@ -32,8 +32,17 @@ async function isFirstUserRegistration(db) {
32
32
  return false;
33
33
  }
34
34
  }
35
+ var emailSchema = z.string().email("Valid email is required").refine(
36
+ (value) => {
37
+ const at = value.lastIndexOf("@");
38
+ if (at < 0) return false;
39
+ const domain = value.slice(at + 1);
40
+ return domain.split(".").every((label) => label.length > 0 && !label.startsWith("-") && !label.endsWith("-"));
41
+ },
42
+ { message: "Valid email is required" }
43
+ );
35
44
  var baseRegistrationSchema = z.object({
36
- email: z.string().email("Valid email is required"),
45
+ email: emailSchema,
37
46
  password: z.string().min(8, "Password must be at least 8 characters"),
38
47
  firstName: z.string().min(1, "First name is required").optional(),
39
48
  lastName: z.string().min(1, "Last name is required").optional()
@@ -62,5 +71,5 @@ var authValidationService = {
62
71
  };
63
72
 
64
73
  export { authValidationService, isFirstUserRegistration, isRegistrationEnabled };
65
- //# sourceMappingURL=chunk-IESEVHXL.js.map
66
- //# sourceMappingURL=chunk-IESEVHXL.js.map
74
+ //# sourceMappingURL=chunk-VVYVFCML.js.map
75
+ //# sourceMappingURL=chunk-VVYVFCML.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/services/auth-validation.ts"],"names":[],"mappings":"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","file":"chunk-VVYVFCML.js","sourcesContent":["/**\n * Auth Validation Service\n *\n * Provides validation schemas for authentication operations\n */\n\nimport { z } from 'zod'\nimport type { D1Database } from '@cloudflare/workers-types'\n\n// In-memory cache for admin existence check (lazy initialization pattern)\nlet adminExistsCache: boolean | null = null\n\nexport interface AuthSettings {\n enablePasswordLogin?: boolean\n enableOAuthLogin?: boolean\n requireEmailVerification?: boolean\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: any\n}\n\n/**\n * Check if user registration is enabled in the auth plugin settings\n * @param db - D1 database instance\n * @returns true if registration is enabled, false if disabled\n */\nexport async function isRegistrationEnabled(db: D1Database): Promise<boolean> {\n // Plugin settings live on the plugin's document (type_id='plugin', slug=pluginId) since the\n // document-model migration — the legacy `plugins` table no longer exists on greenfield. The\n // /admin/plugins/core-auth/settings write goes through PluginService.updatePluginSettings (doc model),\n // so the read must come from the same place or \"disable registration\" silently no-ops.\n try {\n const row = await db\n .prepare(\n \"SELECT data FROM documents WHERE slug = 'core-auth' AND type_id = 'plugin' AND tenant_id = 'default' AND is_current_draft = 1 AND deleted_at IS NULL\",\n )\n .first() as { data: string } | null\n if (row?.data) {\n const data = typeof row.data === 'string' ? JSON.parse(row.data) : row.data\n const enabled = data?.settings?.registration?.enabled\n return enabled !== false && enabled !== 0\n }\n } catch {\n // fall through to the legacy table for installs that still have it\n }\n\n // Legacy fallback: the dropped `plugins` table (guarded — absent on greenfield).\n try {\n const plugin = await db.prepare('SELECT settings FROM plugins WHERE id = ?')\n .bind('core-auth')\n .first() as { settings: string } | null\n if (plugin?.settings) {\n // SQLite stores booleans as 0/1, so check for both false and 0.\n const settings = JSON.parse(plugin.settings)\n const enabled = settings?.registration?.enabled\n return enabled !== false && enabled !== 0\n }\n } catch {\n // no legacy table either\n }\n\n return true // Default to enabled when no setting is found\n}\n\n/**\n * Check if this would be the first user registration (bootstrap scenario)\n * The first user should always be allowed to register even if registration is disabled\n * @param db - D1 database instance\n * @returns true if no users exist in the database\n */\nexport async function isFirstUserRegistration(db: D1Database): Promise<boolean> {\n try {\n const result = await db.prepare('SELECT COUNT(*) as count FROM auth_user').first() as { count: number } | null\n return result?.count === 0\n } catch {\n return false // Default to not first user on error\n }\n}\n\n/**\n * Check if an admin user exists in the database (with in-memory caching)\n * Uses lazy initialization - only queries DB on first call, then caches result\n * @param db - D1 database instance\n * @returns true if an admin user exists\n */\nexport async function checkAdminUserExists(db: D1Database): Promise<boolean> {\n // Return cached value if already checked\n if (adminExistsCache !== null) {\n return adminExistsCache\n }\n\n try {\n const result = await db.prepare('SELECT id FROM auth_user WHERE role = ?')\n .bind('admin')\n .first()\n adminExistsCache = !!result\n return adminExistsCache\n } catch {\n // On error (e.g., table doesn't exist yet), assume no admin exists\n return false\n }\n}\n\n/**\n * Set the admin exists cache to true\n * Call this after successfully creating the first admin user\n */\nexport function setAdminExists(): void {\n adminExistsCache = true\n}\n\n/**\n * Reset the admin exists cache (for testing purposes)\n */\nexport function resetAdminExistsCache(): void {\n adminExistsCache = null\n}\n\n/**\n * Auth Validation Service\n * Provides dynamic validation schemas for registration based on database settings\n */\n/**\n * Email schema. Zod's `.email()` already rejects the common malformed shapes\n * (spaces, double-quoted local parts, consecutive dots, leading dots, commas),\n * but it *accepts* domain labels that begin or end with a hyphen (e.g.\n * `user@example-.com`), which are invalid per RFC 1035. The refine closes that\n * gap so registration validation matches stricter CMS auth suites.\n */\nexport const emailSchema = z\n .string()\n .email('Valid email is required')\n .refine(\n (value) => {\n const at = value.lastIndexOf('@')\n if (at < 0) return false\n const domain = value.slice(at + 1)\n // No domain label may start or end with a hyphen.\n return domain.split('.').every((label) => label.length > 0 && !label.startsWith('-') && !label.endsWith('-'))\n },\n { message: 'Valid email is required' }\n )\n\nconst baseRegistrationSchema = z.object({\n email: emailSchema,\n password: z.string().min(8, 'Password must be at least 8 characters'),\n firstName: z.string().min(1, 'First name is required').optional(),\n lastName: z.string().min(1, 'Last name is required').optional()\n})\n\nexport type RegistrationSchema = typeof baseRegistrationSchema\nexport type RegistrationData = z.infer<RegistrationSchema>\n\nexport const authValidationService = {\n /**\n * Build registration schema dynamically based on auth settings\n * For now, returns a static schema with standard fields\n */\n async buildRegistrationSchema(_db: D1Database): Promise<RegistrationSchema> {\n // TODO: Load settings from database to make fields optional/required dynamically\n // For now, use a static schema with common registration fields\n return baseRegistrationSchema\n },\n\n /**\n * Generate default values for optional fields\n */\n generateDefaultValue(field: string, data: any): string {\n switch (field) {\n case 'firstName':\n return 'User'\n case 'lastName':\n return data.email ? data.email.split('@')[0] : 'Account'\n default:\n return ''\n }\n }\n}\n"]}
@@ -34,8 +34,17 @@ async function isFirstUserRegistration(db) {
34
34
  return false;
35
35
  }
36
36
  }
37
+ var emailSchema = zod.z.string().email("Valid email is required").refine(
38
+ (value) => {
39
+ const at = value.lastIndexOf("@");
40
+ if (at < 0) return false;
41
+ const domain = value.slice(at + 1);
42
+ return domain.split(".").every((label) => label.length > 0 && !label.startsWith("-") && !label.endsWith("-"));
43
+ },
44
+ { message: "Valid email is required" }
45
+ );
37
46
  var baseRegistrationSchema = zod.z.object({
38
- email: zod.z.string().email("Valid email is required"),
47
+ email: emailSchema,
39
48
  password: zod.z.string().min(8, "Password must be at least 8 characters"),
40
49
  firstName: zod.z.string().min(1, "First name is required").optional(),
41
50
  lastName: zod.z.string().min(1, "Last name is required").optional()
@@ -66,5 +75,5 @@ var authValidationService = {
66
75
  exports.authValidationService = authValidationService;
67
76
  exports.isFirstUserRegistration = isFirstUserRegistration;
68
77
  exports.isRegistrationEnabled = isRegistrationEnabled;
69
- //# sourceMappingURL=chunk-HIKBY7MS.cjs.map
70
- //# sourceMappingURL=chunk-HIKBY7MS.cjs.map
78
+ //# sourceMappingURL=chunk-XWVDSM2L.cjs.map
79
+ //# sourceMappingURL=chunk-XWVDSM2L.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/services/auth-validation.ts"],"names":["z"],"mappings":";;;;;AAyBA,eAAsB,sBAAsB,EAAA,EAAkC;AAK5E,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAM,EAAA,CACf,OAAA;AAAA,MACC;AAAA,MAED,KAAA,EAAM;AACT,IAAA,IAAI,KAAK,IAAA,EAAM;AACb,MAAA,MAAM,IAAA,GAAO,OAAO,GAAA,CAAI,IAAA,KAAS,QAAA,GAAW,KAAK,KAAA,CAAM,GAAA,CAAI,IAAI,CAAA,GAAI,GAAA,CAAI,IAAA;AACvE,MAAA,MAAM,OAAA,GAAU,IAAA,EAAM,QAAA,EAAU,YAAA,EAAc,OAAA;AAC9C,MAAA,OAAO,OAAA,KAAY,SAAS,OAAA,KAAY,CAAA;AAAA,IAC1C;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AAGA,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,MAAM,EAAA,CAAG,OAAA,CAAQ,2CAA2C,CAAA,CACxE,IAAA,CAAK,WAAW,CAAA,CAChB,KAAA,EAAM;AACT,IAAA,IAAI,QAAQ,QAAA,EAAU;AAEpB,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,QAAQ,CAAA;AAC3C,MAAA,MAAM,OAAA,GAAU,UAAU,YAAA,EAAc,OAAA;AACxC,MAAA,OAAO,OAAA,KAAY,SAAS,OAAA,KAAY,CAAA;AAAA,IAC1C;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AAEA,EAAA,OAAO,IAAA;AACT;AAQA,eAAsB,wBAAwB,EAAA,EAAkC;AAC9E,EAAA,IAAI;AACF,IAAA,MAAM,SAAS,MAAM,EAAA,CAAG,OAAA,CAAQ,yCAAyC,EAAE,KAAA,EAAM;AACjF,IAAA,OAAO,QAAQ,KAAA,KAAU,CAAA;AAAA,EAC3B,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAoDO,IAAM,cAAcA,KAAA,CACxB,MAAA,EAAO,CACP,KAAA,CAAM,yBAAyB,CAAA,CAC/B,MAAA;AAAA,EACC,CAAC,KAAA,KAAU;AACT,IAAA,MAAM,EAAA,GAAK,KAAA,CAAM,WAAA,CAAY,GAAG,CAAA;AAChC,IAAA,IAAI,EAAA,GAAK,GAAG,OAAO,KAAA;AACnB,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,KAAA,CAAM,EAAA,GAAK,CAAC,CAAA;AAEjC,IAAA,OAAO,OAAO,KAAA,CAAM,GAAG,EAAE,KAAA,CAAM,CAAC,UAAU,KAAA,CAAM,MAAA,GAAS,KAAK,CAAC,KAAA,CAAM,WAAW,GAAG,CAAA,IAAK,CAAC,KAAA,CAAM,QAAA,CAAS,GAAG,CAAC,CAAA;AAAA,EAC9G,CAAA;AAAA,EACA,EAAE,SAAS,yBAAA;AACb,CAAA;AAEF,IAAM,sBAAA,GAAyBA,MAAE,MAAA,CAAO;AAAA,EACtC,KAAA,EAAO,WAAA;AAAA,EACP,UAAUA,KAAA,CAAE,MAAA,EAAO,CAAE,GAAA,CAAI,GAAG,wCAAwC,CAAA;AAAA,EACpE,SAAA,EAAWA,MAAE,MAAA,EAAO,CAAE,IAAI,CAAA,EAAG,wBAAwB,EAAE,QAAA,EAAS;AAAA,EAChE,QAAA,EAAUA,MAAE,MAAA,EAAO,CAAE,IAAI,CAAA,EAAG,uBAAuB,EAAE,QAAA;AACvD,CAAC,CAAA;AAKM,IAAM,qBAAA,GAAwB;AAAA;AAAA;AAAA;AAAA;AAAA,EAKnC,MAAM,wBAAwB,GAAA,EAA8C;AAG1E,IAAA,OAAO,sBAAA;AAAA,EACT,CAAA;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAA,CAAqB,OAAe,IAAA,EAAmB;AACrD,IAAA,QAAQ,KAAA;AAAO,MACb,KAAK,WAAA;AACH,QAAA,OAAO,MAAA;AAAA,MACT,KAAK,UAAA;AACH,QAAA,OAAO,IAAA,CAAK,QAAQ,IAAA,CAAK,KAAA,CAAM,MAAM,GAAG,CAAA,CAAE,CAAC,CAAA,GAAI,SAAA;AAAA,MACjD;AACE,QAAA,OAAO,EAAA;AAAA;AACX,EACF;AACF","file":"chunk-XWVDSM2L.cjs","sourcesContent":["/**\n * Auth Validation Service\n *\n * Provides validation schemas for authentication operations\n */\n\nimport { z } from 'zod'\nimport type { D1Database } from '@cloudflare/workers-types'\n\n// In-memory cache for admin existence check (lazy initialization pattern)\nlet adminExistsCache: boolean | null = null\n\nexport interface AuthSettings {\n enablePasswordLogin?: boolean\n enableOAuthLogin?: boolean\n requireEmailVerification?: boolean\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: any\n}\n\n/**\n * Check if user registration is enabled in the auth plugin settings\n * @param db - D1 database instance\n * @returns true if registration is enabled, false if disabled\n */\nexport async function isRegistrationEnabled(db: D1Database): Promise<boolean> {\n // Plugin settings live on the plugin's document (type_id='plugin', slug=pluginId) since the\n // document-model migration — the legacy `plugins` table no longer exists on greenfield. The\n // /admin/plugins/core-auth/settings write goes through PluginService.updatePluginSettings (doc model),\n // so the read must come from the same place or \"disable registration\" silently no-ops.\n try {\n const row = await db\n .prepare(\n \"SELECT data FROM documents WHERE slug = 'core-auth' AND type_id = 'plugin' AND tenant_id = 'default' AND is_current_draft = 1 AND deleted_at IS NULL\",\n )\n .first() as { data: string } | null\n if (row?.data) {\n const data = typeof row.data === 'string' ? JSON.parse(row.data) : row.data\n const enabled = data?.settings?.registration?.enabled\n return enabled !== false && enabled !== 0\n }\n } catch {\n // fall through to the legacy table for installs that still have it\n }\n\n // Legacy fallback: the dropped `plugins` table (guarded — absent on greenfield).\n try {\n const plugin = await db.prepare('SELECT settings FROM plugins WHERE id = ?')\n .bind('core-auth')\n .first() as { settings: string } | null\n if (plugin?.settings) {\n // SQLite stores booleans as 0/1, so check for both false and 0.\n const settings = JSON.parse(plugin.settings)\n const enabled = settings?.registration?.enabled\n return enabled !== false && enabled !== 0\n }\n } catch {\n // no legacy table either\n }\n\n return true // Default to enabled when no setting is found\n}\n\n/**\n * Check if this would be the first user registration (bootstrap scenario)\n * The first user should always be allowed to register even if registration is disabled\n * @param db - D1 database instance\n * @returns true if no users exist in the database\n */\nexport async function isFirstUserRegistration(db: D1Database): Promise<boolean> {\n try {\n const result = await db.prepare('SELECT COUNT(*) as count FROM auth_user').first() as { count: number } | null\n return result?.count === 0\n } catch {\n return false // Default to not first user on error\n }\n}\n\n/**\n * Check if an admin user exists in the database (with in-memory caching)\n * Uses lazy initialization - only queries DB on first call, then caches result\n * @param db - D1 database instance\n * @returns true if an admin user exists\n */\nexport async function checkAdminUserExists(db: D1Database): Promise<boolean> {\n // Return cached value if already checked\n if (adminExistsCache !== null) {\n return adminExistsCache\n }\n\n try {\n const result = await db.prepare('SELECT id FROM auth_user WHERE role = ?')\n .bind('admin')\n .first()\n adminExistsCache = !!result\n return adminExistsCache\n } catch {\n // On error (e.g., table doesn't exist yet), assume no admin exists\n return false\n }\n}\n\n/**\n * Set the admin exists cache to true\n * Call this after successfully creating the first admin user\n */\nexport function setAdminExists(): void {\n adminExistsCache = true\n}\n\n/**\n * Reset the admin exists cache (for testing purposes)\n */\nexport function resetAdminExistsCache(): void {\n adminExistsCache = null\n}\n\n/**\n * Auth Validation Service\n * Provides dynamic validation schemas for registration based on database settings\n */\n/**\n * Email schema. Zod's `.email()` already rejects the common malformed shapes\n * (spaces, double-quoted local parts, consecutive dots, leading dots, commas),\n * but it *accepts* domain labels that begin or end with a hyphen (e.g.\n * `user@example-.com`), which are invalid per RFC 1035. The refine closes that\n * gap so registration validation matches stricter CMS auth suites.\n */\nexport const emailSchema = z\n .string()\n .email('Valid email is required')\n .refine(\n (value) => {\n const at = value.lastIndexOf('@')\n if (at < 0) return false\n const domain = value.slice(at + 1)\n // No domain label may start or end with a hyphen.\n return domain.split('.').every((label) => label.length > 0 && !label.startsWith('-') && !label.endsWith('-'))\n },\n { message: 'Valid email is required' }\n )\n\nconst baseRegistrationSchema = z.object({\n email: emailSchema,\n password: z.string().min(8, 'Password must be at least 8 characters'),\n firstName: z.string().min(1, 'First name is required').optional(),\n lastName: z.string().min(1, 'Last name is required').optional()\n})\n\nexport type RegistrationSchema = typeof baseRegistrationSchema\nexport type RegistrationData = z.infer<RegistrationSchema>\n\nexport const authValidationService = {\n /**\n * Build registration schema dynamically based on auth settings\n * For now, returns a static schema with standard fields\n */\n async buildRegistrationSchema(_db: D1Database): Promise<RegistrationSchema> {\n // TODO: Load settings from database to make fields optional/required dynamically\n // For now, use a static schema with common registration fields\n return baseRegistrationSchema\n },\n\n /**\n * Generate default values for optional fields\n */\n generateDefaultValue(field: string, data: any): string {\n switch (field) {\n case 'firstName':\n return 'User'\n case 'lastName':\n return data.email ? data.email.split('@')[0] : 'Account'\n default:\n return ''\n }\n }\n}\n"]}
@@ -0,0 +1,6 @@
1
+ export { createAuth, getDefaultAuthOptions } from './chunk-IQZA2OY5.js';
2
+ import './chunk-VVYVFCML.js';
3
+ import './chunk-AI663NBO.js';
4
+ import './chunk-V4OQ3NZ2.js';
5
+ //# sourceMappingURL=config-SM2UWSDN.js.map
6
+ //# sourceMappingURL=config-SM2UWSDN.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"config-PLJTDINX.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"config-SM2UWSDN.js"}
@@ -0,0 +1,19 @@
1
+ 'use strict';
2
+
3
+ var chunkKMCLNO4K_cjs = require('./chunk-KMCLNO4K.cjs');
4
+ require('./chunk-XWVDSM2L.cjs');
5
+ require('./chunk-YP7GW2G5.cjs');
6
+ require('./chunk-IGJUBJBW.cjs');
7
+
8
+
9
+
10
+ Object.defineProperty(exports, "createAuth", {
11
+ enumerable: true,
12
+ get: function () { return chunkKMCLNO4K_cjs.createAuth; }
13
+ });
14
+ Object.defineProperty(exports, "getDefaultAuthOptions", {
15
+ enumerable: true,
16
+ get: function () { return chunkKMCLNO4K_cjs.getDefaultAuthOptions; }
17
+ });
18
+ //# sourceMappingURL=config-YCRSU7ZP.cjs.map
19
+ //# sourceMappingURL=config-YCRSU7ZP.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"config-FLOUCYHH.cjs"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"config-YCRSU7ZP.cjs"}
@@ -1,4 +1,4 @@
1
- import { i as HookSystemLike, m as TypedHooks, E as EmailProvider, s as EmailLogRow, t as EmailMessage, q as SendResult, f as HookEventName, l as TypedHookHandler } from './types-Dea1eNxU.js';
1
+ import { i as HookSystemLike, m as TypedHooks, E as EmailProvider, q as EmailLogRow, s as EmailMessage, t as SendResult, f as HookEventName, l as TypedHookHandler } from './types-DT7XN5TX.js';
2
2
  import { Hono } from 'hono';
3
3
  import { d as HookSystem, b as HookHandler, k as PluginHook, v as PluginValidator$1, P as Plugin, u as PluginValidationResult, q as PluginRegistry, i as PluginConfig, t as PluginStatus, m as PluginManager$1, j as PluginContext } from './plugin-DDYetMF-.js';
4
4
 
@@ -1,4 +1,4 @@
1
- import { i as HookSystemLike, m as TypedHooks, E as EmailProvider, s as EmailLogRow, t as EmailMessage, q as SendResult, f as HookEventName, l as TypedHookHandler } from './types-Dea1eNxU.cjs';
1
+ import { i as HookSystemLike, m as TypedHooks, E as EmailProvider, q as EmailLogRow, s as EmailMessage, t as SendResult, f as HookEventName, l as TypedHookHandler } from './types-DT7XN5TX.cjs';
2
2
  import { Hono } from 'hono';
3
3
  import { d as HookSystem, b as HookHandler, k as PluginHook, v as PluginValidator$1, P as Plugin, u as PluginValidationResult, q as PluginRegistry, i as PluginConfig, t as PluginStatus, m as PluginManager$1, j as PluginContext } from './plugin-DDYetMF-.cjs';
4
4