@kyro-cms/core 0.9.0 → 0.9.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 (248) hide show
  1. package/README.md +57 -589
  2. package/dist/{WebhookService-118ZTFis.d.ts → WebhookService-CUTb9XOy.d.ts} +1 -1
  3. package/dist/{WebhookService-AefJfqX0.d.cts → WebhookService-Yg2UEOB4.d.cts} +1 -1
  4. package/dist/api-handler-graphql.cjs +44 -0
  5. package/dist/api-handler-graphql.cjs.map +1 -0
  6. package/dist/api-handler-graphql.d.cts +6 -0
  7. package/dist/api-handler-graphql.d.ts +6 -0
  8. package/dist/api-handler-graphql.js +41 -0
  9. package/dist/api-handler-graphql.js.map +1 -0
  10. package/dist/api-handler-trpc.cjs +38 -0
  11. package/dist/api-handler-trpc.cjs.map +1 -0
  12. package/dist/api-handler-trpc.d.cts +5 -0
  13. package/dist/api-handler-trpc.d.ts +5 -0
  14. package/dist/api-handler-trpc.js +36 -0
  15. package/dist/api-handler-trpc.js.map +1 -0
  16. package/dist/api-handler.cjs +31 -97
  17. package/dist/api-handler.cjs.map +1 -1
  18. package/dist/api-handler.d.cts +2 -1
  19. package/dist/api-handler.d.ts +2 -1
  20. package/dist/api-handler.js +19 -95
  21. package/dist/api-handler.js.map +1 -1
  22. package/dist/{tenant-B1YB0Jy8.d.ts → base-B71y_EAF.d.cts} +6 -12
  23. package/dist/{tenant-Cpeveji6.d.cts → base-DaqY2GhA.d.ts} +6 -12
  24. package/dist/bootstrap-5NLASFOG.cjs +32 -0
  25. package/dist/{bootstrap-AKAUP6F6.cjs.map → bootstrap-5NLASFOG.cjs.map} +1 -1
  26. package/dist/bootstrap-T5BK77LD.js +7 -0
  27. package/dist/{bootstrap-JCML6NFO.js.map → bootstrap-T5BK77LD.js.map} +1 -1
  28. package/dist/{chunk-35U3FROB.js → chunk-22M4O4ZJ.js} +607 -63
  29. package/dist/chunk-22M4O4ZJ.js.map +1 -0
  30. package/dist/chunk-2HZRBATX.cjs +253 -0
  31. package/dist/chunk-2HZRBATX.cjs.map +1 -0
  32. package/dist/{chunk-VJT6P4N6.cjs → chunk-3HR772HI.cjs} +199 -32
  33. package/dist/chunk-3HR772HI.cjs.map +1 -0
  34. package/dist/chunk-3KTWGODI.cjs +178 -0
  35. package/dist/chunk-3KTWGODI.cjs.map +1 -0
  36. package/dist/{chunk-QXIQWPAP.js → chunk-3UK5XBVJ.js} +4 -134
  37. package/dist/chunk-3UK5XBVJ.js.map +1 -0
  38. package/dist/{chunk-FXYP2HA6.js → chunk-4AO3A3JM.js} +48 -4
  39. package/dist/chunk-4AO3A3JM.js.map +1 -0
  40. package/dist/chunk-4M7X5HAB.cjs +173 -0
  41. package/dist/chunk-4M7X5HAB.cjs.map +1 -0
  42. package/dist/chunk-5EPFQUQD.js +3243 -0
  43. package/dist/chunk-5EPFQUQD.js.map +1 -0
  44. package/dist/{chunk-Y3N7UUDO.js → chunk-7OGPN7MP.js} +5 -2
  45. package/dist/chunk-7OGPN7MP.js.map +1 -0
  46. package/dist/{chunk-WOWUL7ZY.js → chunk-AL5KX63J.js} +4 -3
  47. package/dist/chunk-AL5KX63J.js.map +1 -0
  48. package/dist/{chunk-2OL4O2TH.cjs → chunk-C36TMDTY.cjs} +66 -61
  49. package/dist/chunk-C36TMDTY.cjs.map +1 -0
  50. package/dist/{chunk-ES5HNFFT.js → chunk-CF7OL6HR.js} +4 -2
  51. package/dist/chunk-CF7OL6HR.js.map +1 -0
  52. package/dist/chunk-CJONKRHJ.js +162 -0
  53. package/dist/chunk-CJONKRHJ.js.map +1 -0
  54. package/dist/{chunk-2KVHZE6O.cjs → chunk-COIASRDK.cjs} +202 -46
  55. package/dist/chunk-COIASRDK.cjs.map +1 -0
  56. package/dist/chunk-DEVFAKCQ.cjs +3291 -0
  57. package/dist/chunk-DEVFAKCQ.cjs.map +1 -0
  58. package/dist/{chunk-3ZFYL34R.js → chunk-DYTZ6FQ7.js} +12 -185
  59. package/dist/chunk-DYTZ6FQ7.js.map +1 -0
  60. package/dist/{chunk-QPPDLRNR.js → chunk-EJN2PAOE.js} +197 -41
  61. package/dist/chunk-EJN2PAOE.js.map +1 -0
  62. package/dist/chunk-FAXU7BMP.js +220 -0
  63. package/dist/chunk-FAXU7BMP.js.map +1 -0
  64. package/dist/{chunk-OHVB4AJ7.js → chunk-FOPGUM27.js} +22 -17
  65. package/dist/chunk-FOPGUM27.js.map +1 -0
  66. package/dist/chunk-GAOXD3XT.js +175 -0
  67. package/dist/chunk-GAOXD3XT.js.map +1 -0
  68. package/dist/{chunk-4DA7QPLA.cjs → chunk-GXFOGU7N.cjs} +5 -2
  69. package/dist/chunk-GXFOGU7N.cjs.map +1 -0
  70. package/dist/{chunk-I7HHI6QV.cjs → chunk-IDVRRRAK.cjs} +17 -9
  71. package/dist/chunk-IDVRRRAK.cjs.map +1 -0
  72. package/dist/{chunk-WQBRWOQT.cjs → chunk-JOPVMWTM.cjs} +3 -2
  73. package/dist/chunk-JOPVMWTM.cjs.map +1 -0
  74. package/dist/chunk-KC2GDBLS.cjs +84 -0
  75. package/dist/chunk-KC2GDBLS.cjs.map +1 -0
  76. package/dist/{chunk-K7JPTH3G.cjs → chunk-KNRSROWB.cjs} +132 -74
  77. package/dist/chunk-KNRSROWB.cjs.map +1 -0
  78. package/dist/{chunk-3AJE4SEG.js → chunk-KPA4AN4R.js} +125 -67
  79. package/dist/chunk-KPA4AN4R.js.map +1 -0
  80. package/dist/{chunk-QUW2RZTM.cjs → chunk-L46ROHUS.cjs} +51 -7
  81. package/dist/chunk-L46ROHUS.cjs.map +1 -0
  82. package/dist/chunk-L4EZKIEX.js +185 -0
  83. package/dist/chunk-L4EZKIEX.js.map +1 -0
  84. package/dist/{chunk-REK7AYOC.js → chunk-L5UKKZQN.js} +199 -32
  85. package/dist/chunk-L5UKKZQN.js.map +1 -0
  86. package/dist/chunk-NKPKR5BW.cjs +188 -0
  87. package/dist/chunk-NKPKR5BW.cjs.map +1 -0
  88. package/dist/{chunk-Y3QQN7PN.js → chunk-P2HKJ7P5.js} +13 -4
  89. package/dist/chunk-P2HKJ7P5.js.map +1 -0
  90. package/dist/{chunk-SA7NSSIQ.cjs → chunk-PI73NNOK.cjs} +13 -187
  91. package/dist/chunk-PI73NNOK.cjs.map +1 -0
  92. package/dist/{chunk-HXRD4B37.js → chunk-PU2Z5VWF.js} +1279 -556
  93. package/dist/chunk-PU2Z5VWF.js.map +1 -0
  94. package/dist/{chunk-H727JIG7.js → chunk-Q72BOAPK.js} +16 -8
  95. package/dist/chunk-Q72BOAPK.js.map +1 -0
  96. package/dist/{chunk-IBG6V56E.cjs → chunk-QFLB4EIJ.cjs} +2 -139
  97. package/dist/chunk-QFLB4EIJ.cjs.map +1 -0
  98. package/dist/{chunk-YVUJBEXE.cjs → chunk-RAMGUDJN.cjs} +16 -7
  99. package/dist/chunk-RAMGUDJN.cjs.map +1 -0
  100. package/dist/{chunk-LINKCEG4.cjs → chunk-ROJHKAQ4.cjs} +617 -73
  101. package/dist/chunk-ROJHKAQ4.cjs.map +1 -0
  102. package/dist/{chunk-5KVM3WEY.cjs → chunk-RSF3UU7H.cjs} +1330 -602
  103. package/dist/chunk-RSF3UU7H.cjs.map +1 -0
  104. package/dist/{chunk-V3LKPM3O.cjs → chunk-SHTTJMLT.cjs} +4 -2
  105. package/dist/chunk-SHTTJMLT.cjs.map +1 -0
  106. package/dist/chunk-SPBTLUN6.js +92 -0
  107. package/dist/chunk-SPBTLUN6.js.map +1 -0
  108. package/dist/{chunk-57P6MJKC.js → chunk-TXSZFA4G.js} +3 -3
  109. package/dist/chunk-TXSZFA4G.js.map +1 -0
  110. package/dist/chunk-UERVXYVK.cjs +99 -0
  111. package/dist/chunk-UERVXYVK.cjs.map +1 -0
  112. package/dist/{chunk-PDYFVNUX.cjs → chunk-V2TVSCV5.cjs} +16 -23
  113. package/dist/chunk-V2TVSCV5.cjs.map +1 -0
  114. package/dist/{chunk-DXHRBMGB.js → chunk-VO35MNPH.js} +12 -19
  115. package/dist/chunk-VO35MNPH.js.map +1 -0
  116. package/dist/{chunk-IA6AU5PI.cjs → chunk-WNCYAKF3.cjs} +3 -3
  117. package/dist/chunk-WNCYAKF3.cjs.map +1 -0
  118. package/dist/chunk-XEB7PH2E.js +81 -0
  119. package/dist/chunk-XEB7PH2E.js.map +1 -0
  120. package/dist/cli/index.cjs +5 -5
  121. package/dist/cli/index.cjs.map +1 -1
  122. package/dist/cli/index.js +5 -5
  123. package/dist/cli/index.js.map +1 -1
  124. package/dist/client.cjs +3 -3
  125. package/dist/client.d.cts +3 -3
  126. package/dist/client.d.ts +3 -3
  127. package/dist/client.js +1 -1
  128. package/dist/drizzle/index.cjs +14 -13
  129. package/dist/drizzle/index.d.cts +9 -7
  130. package/dist/drizzle/index.d.ts +9 -7
  131. package/dist/drizzle/index.js +5 -4
  132. package/dist/fields/index.cjs +21 -37
  133. package/dist/fields/index.d.cts +2 -22
  134. package/dist/fields/index.d.ts +2 -22
  135. package/dist/fields/index.js +1 -1
  136. package/dist/graphql/index.cjs +5 -4
  137. package/dist/graphql/index.d.cts +5 -3
  138. package/dist/graphql/index.d.ts +5 -3
  139. package/dist/graphql/index.js +3 -2
  140. package/dist/index-CJXPB_ot.d.ts +276 -0
  141. package/dist/index-CaTNnLGd.d.cts +276 -0
  142. package/dist/index.cjs +304 -162
  143. package/dist/index.cjs.map +1 -1
  144. package/dist/index.d.cts +129 -205
  145. package/dist/index.d.ts +129 -205
  146. package/dist/index.js +172 -33
  147. package/dist/index.js.map +1 -1
  148. package/dist/integration.cjs +2 -2
  149. package/dist/integration.js +1 -1
  150. package/dist/mongo-auth-adapter-ISOM7FSS.cjs +17 -0
  151. package/dist/{mongo-auth-adapter-NHHUJHVH.cjs.map → mongo-auth-adapter-ISOM7FSS.cjs.map} +1 -1
  152. package/dist/mongo-auth-adapter-MO6STCV3.js +4 -0
  153. package/dist/{mongo-auth-adapter-NJQUUCTP.js.map → mongo-auth-adapter-MO6STCV3.js.map} +1 -1
  154. package/dist/mongodb/index.cjs +8 -7
  155. package/dist/mongodb/index.d.cts +5 -7
  156. package/dist/mongodb/index.d.ts +5 -7
  157. package/dist/mongodb/index.js +4 -3
  158. package/dist/postgres-auth-adapter-DWDR7P5G.js +5 -0
  159. package/dist/{postgres-auth-adapter-3T2NKTSE.js.map → postgres-auth-adapter-DWDR7P5G.js.map} +1 -1
  160. package/dist/postgres-auth-adapter-WRWSJD4E.cjs +14 -0
  161. package/dist/{postgres-auth-adapter-7IEENCKQ.cjs.map → postgres-auth-adapter-WRWSJD4E.cjs.map} +1 -1
  162. package/dist/redis-adapter-HGTPWIGV.js +4 -0
  163. package/dist/{redis-adapter-VQXD7ESY.js.map → redis-adapter-HGTPWIGV.js.map} +1 -1
  164. package/dist/redis-adapter-KJ3YOOT6.cjs +13 -0
  165. package/dist/{redis-adapter-D2E2S3GB.cjs.map → redis-adapter-KJ3YOOT6.cjs.map} +1 -1
  166. package/dist/rest/index.cjs +15 -14
  167. package/dist/rest/index.d.cts +4 -4
  168. package/dist/rest/index.d.ts +4 -4
  169. package/dist/rest/index.js +13 -12
  170. package/dist/{schema-5PHL5IVB.js → schema-6I5OFR4Z.js} +3 -3
  171. package/dist/{schema-5PHL5IVB.js.map → schema-6I5OFR4Z.js.map} +1 -1
  172. package/dist/{schema-37SE2F4B.cjs → schema-TTFE4467.cjs} +14 -14
  173. package/dist/{schema-37SE2F4B.cjs.map → schema-TTFE4467.cjs.map} +1 -1
  174. package/dist/sqlite-adapter-6GEUSVXQ.js +4 -0
  175. package/dist/{sqlite-adapter-TR3U3W6Q.js.map → sqlite-adapter-6GEUSVXQ.js.map} +1 -1
  176. package/dist/sqlite-adapter-CSIZE5SX.cjs +13 -0
  177. package/dist/{sqlite-adapter-LVK5PS4T.cjs.map → sqlite-adapter-CSIZE5SX.cjs.map} +1 -1
  178. package/dist/templates/index.cjs +133 -31
  179. package/dist/templates/index.d.cts +52 -9
  180. package/dist/templates/index.d.ts +52 -9
  181. package/dist/templates/index.js +3 -1
  182. package/dist/trpc/index.cjs +13 -12
  183. package/dist/trpc/index.d.cts +55 -49
  184. package/dist/trpc/index.d.ts +55 -49
  185. package/dist/trpc/index.js +4 -3
  186. package/dist/{types-D6ZLRGbH.d.cts → types-CpjuXbe7.d.cts} +2 -0
  187. package/dist/{types-D6ZLRGbH.d.ts → types-CpjuXbe7.d.ts} +2 -0
  188. package/dist/{types-Bs1up4yP.d.ts → types-CyCQ6SAI.d.ts} +28 -2
  189. package/dist/{types-J3R9nVsZ.d.cts → types-DJxD9394.d.cts} +28 -2
  190. package/dist/{types-VtjUxIMp.d.cts → types-Z6FBiqa2.d.cts} +35 -14
  191. package/dist/{types-VtjUxIMp.d.ts → types-Z6FBiqa2.d.ts} +35 -14
  192. package/package.json +22 -4
  193. package/dist/bootstrap-AKAUP6F6.cjs +0 -32
  194. package/dist/bootstrap-JCML6NFO.js +0 -7
  195. package/dist/chunk-2KVHZE6O.cjs.map +0 -1
  196. package/dist/chunk-2OL4O2TH.cjs.map +0 -1
  197. package/dist/chunk-35U3FROB.js.map +0 -1
  198. package/dist/chunk-3AJE4SEG.js.map +0 -1
  199. package/dist/chunk-3J4MFTI3.js +0 -3872
  200. package/dist/chunk-3J4MFTI3.js.map +0 -1
  201. package/dist/chunk-3ZFYL34R.js.map +0 -1
  202. package/dist/chunk-4DA7QPLA.cjs.map +0 -1
  203. package/dist/chunk-57P6MJKC.js.map +0 -1
  204. package/dist/chunk-5KVM3WEY.cjs.map +0 -1
  205. package/dist/chunk-6IMPH6WV.cjs +0 -3897
  206. package/dist/chunk-6IMPH6WV.cjs.map +0 -1
  207. package/dist/chunk-ATBOUGQP.cjs +0 -513
  208. package/dist/chunk-ATBOUGQP.cjs.map +0 -1
  209. package/dist/chunk-DXHRBMGB.js.map +0 -1
  210. package/dist/chunk-ES5HNFFT.js.map +0 -1
  211. package/dist/chunk-FXYP2HA6.js.map +0 -1
  212. package/dist/chunk-H727JIG7.js.map +0 -1
  213. package/dist/chunk-HXRD4B37.js.map +0 -1
  214. package/dist/chunk-I7HHI6QV.cjs.map +0 -1
  215. package/dist/chunk-IA6AU5PI.cjs.map +0 -1
  216. package/dist/chunk-IBG6V56E.cjs.map +0 -1
  217. package/dist/chunk-K7JPTH3G.cjs.map +0 -1
  218. package/dist/chunk-LINKCEG4.cjs.map +0 -1
  219. package/dist/chunk-OHVB4AJ7.js.map +0 -1
  220. package/dist/chunk-PDYFVNUX.cjs.map +0 -1
  221. package/dist/chunk-Q23JB3KL.js +0 -488
  222. package/dist/chunk-Q23JB3KL.js.map +0 -1
  223. package/dist/chunk-QPPDLRNR.js.map +0 -1
  224. package/dist/chunk-QUW2RZTM.cjs.map +0 -1
  225. package/dist/chunk-QXIQWPAP.js.map +0 -1
  226. package/dist/chunk-R3XIBBAW.cjs +0 -34
  227. package/dist/chunk-R3XIBBAW.cjs.map +0 -1
  228. package/dist/chunk-REK7AYOC.js.map +0 -1
  229. package/dist/chunk-SA7NSSIQ.cjs.map +0 -1
  230. package/dist/chunk-SDMNUYVU.js +0 -30
  231. package/dist/chunk-SDMNUYVU.js.map +0 -1
  232. package/dist/chunk-V3LKPM3O.cjs.map +0 -1
  233. package/dist/chunk-VJT6P4N6.cjs.map +0 -1
  234. package/dist/chunk-WOWUL7ZY.js.map +0 -1
  235. package/dist/chunk-WQBRWOQT.cjs.map +0 -1
  236. package/dist/chunk-Y3N7UUDO.js.map +0 -1
  237. package/dist/chunk-Y3QQN7PN.js.map +0 -1
  238. package/dist/chunk-YVUJBEXE.cjs.map +0 -1
  239. package/dist/index-CLp-DRKA.d.ts +0 -64
  240. package/dist/index-DfO7G4kN.d.cts +0 -64
  241. package/dist/mongo-auth-adapter-NHHUJHVH.cjs +0 -17
  242. package/dist/mongo-auth-adapter-NJQUUCTP.js +0 -4
  243. package/dist/postgres-auth-adapter-3T2NKTSE.js +0 -5
  244. package/dist/postgres-auth-adapter-7IEENCKQ.cjs +0 -14
  245. package/dist/redis-adapter-D2E2S3GB.cjs +0 -13
  246. package/dist/redis-adapter-VQXD7ESY.js +0 -4
  247. package/dist/sqlite-adapter-LVK5PS4T.cjs +0 -13
  248. package/dist/sqlite-adapter-TR3U3W6Q.js +0 -4
@@ -222,6 +222,7 @@ var RedisAuthAdapter = class {
222
222
  createdAt: user.createdAt,
223
223
  updatedAt: user.updatedAt
224
224
  };
225
+ if (user.avatar) hash.avatar = user.avatar;
225
226
  if (user.tenantId) hash.tenantId = user.tenantId;
226
227
  if (user.emailVerified !== void 0)
227
228
  hash.emailVerified = String(user.emailVerified);
@@ -238,6 +239,7 @@ var RedisAuthAdapter = class {
238
239
  passwordHash: hash.passwordHash,
239
240
  role: hash.role,
240
241
  tenantId: hash.tenantId,
242
+ avatar: hash.avatar,
241
243
  createdAt: hash.createdAt,
242
244
  updatedAt: hash.updatedAt,
243
245
  emailVerified: hash.emailVerified === "true",
@@ -355,5 +357,5 @@ var RedisAuthAdapter = class {
355
357
  };
356
358
 
357
359
  exports.RedisAuthAdapter = RedisAuthAdapter;
358
- //# sourceMappingURL=chunk-V3LKPM3O.cjs.map
359
- //# sourceMappingURL=chunk-V3LKPM3O.cjs.map
360
+ //# sourceMappingURL=chunk-SHTTJMLT.cjs.map
361
+ //# sourceMappingURL=chunk-SHTTJMLT.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/auth/redis-adapter.ts"],"names":["randomBytes","bcrypt"],"mappings":"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","file":"chunk-SHTTJMLT.cjs","sourcesContent":["import type { Redis } from \"ioredis\";\nimport type { AuthAdapter, AuthUser, Session, UserRole } from \"./types.js\";\nimport bcrypt from \"bcryptjs\";\nimport { randomBytes } from \"crypto\";\n\nexport interface RedisAuthAdapterOptions {\n url?: string;\n host?: string;\n port?: number;\n password?: string;\n db?: number;\n keyPrefix?: string;\n tokenExpiration?: number;\n refreshTokenExpiration?: number;\n tls?: boolean;\n}\n\nconst DEFAULT_PREFIX = \"kyro:auth:\";\nconst DEFAULT_TOKEN_EXPIRATION = 86400;\nconst DEFAULT_REFRESH_EXPIRATION = 604800;\n\nexport class RedisAuthAdapter implements AuthAdapter {\n private _redis: Redis | null = null;\n private prefix: string;\n private tokenExpiration: number;\n private refreshExpiration: number;\n private options: RedisAuthAdapterOptions;\n\n constructor(options: RedisAuthAdapterOptions = {}) {\n this.options = options;\n this.prefix = options.keyPrefix || DEFAULT_PREFIX;\n this.tokenExpiration = options.tokenExpiration || DEFAULT_TOKEN_EXPIRATION;\n this.refreshExpiration =\n options.refreshTokenExpiration || DEFAULT_REFRESH_EXPIRATION;\n }\n\n private async getRedis(): Promise<Redis> {\n if (!this._redis) {\n const { Redis: RedisClass } = await import(\"ioredis\");\n const url =\n this.options.url ||\n `redis://${this.options.host || \"localhost\"}:${this.options.port || 6379}`;\n this._redis = new RedisClass(url, {\n password: this.options.password,\n db: this.options.db,\n lazyConnect: true,\n tls: this.options.tls ? {} : undefined,\n });\n }\n return this._redis;\n }\n\n async connect(): Promise<void> {\n await this.getRedis();\n }\n\n async disconnect(): Promise<void> {\n await (await this.getRedis()).quit();\n }\n\n private userKey(userId: string): string {\n return `${this.prefix}users:${userId}`;\n }\n\n private sessionKey(sessionId: string): string {\n return `${this.prefix}sessions:${sessionId}`;\n }\n\n private refreshKey(token: string): string {\n return `${this.prefix}refresh:${token}`;\n }\n\n private userByEmailKey(email: string): string {\n return `${this.prefix}users:email:${email.toLowerCase()}`;\n }\n\n private passwordHistoryKey(userId: string): string {\n return `${this.prefix}users:${userId}:password_history`;\n }\n\n async createUser(data: {\n email: string;\n password: string;\n role?: UserRole;\n tenantId?: string;\n }): Promise<AuthUser> {\n const userId = randomBytes(16).toString(\"hex\");\n const now = new Date().toISOString();\n const passwordHash = await this.hashPassword(data.password);\n\n const user: AuthUser = {\n id: userId,\n email: data.email.toLowerCase(),\n passwordHash,\n role: (data.role || \"customer\") as UserRole,\n tenantId: data.tenantId,\n createdAt: now,\n updatedAt: now,\n };\n\n const pipeline = (await this.getRedis()).pipeline();\n\n pipeline.hset(this.userKey(userId), this.userToHash(user));\n pipeline.set(this.userByEmailKey(data.email), userId);\n\n await pipeline.exec();\n\n return user;\n }\n\n async findUserByEmail(email: string): Promise<AuthUser | null> {\n const userId = await (\n await this.getRedis()\n ).get(this.userByEmailKey(email.toLowerCase()));\n if (!userId) return null;\n return this.findUserById(userId);\n }\n\n async findUserById(userId: string): Promise<AuthUser | null> {\n const data = await (await this.getRedis()).hgetall(this.userKey(userId));\n if (!data || Object.keys(data).length === 0) return null;\n return this.hashToUser(data);\n }\n\n async updateUser(\n userId: string,\n data: Partial<AuthUser>,\n ): Promise<AuthUser | null> {\n const existing = await this.findUserById(userId);\n if (!existing) return null;\n\n const updated: AuthUser = {\n ...existing,\n ...data,\n id: userId,\n updatedAt: new Date().toISOString(),\n };\n\n if (data.email && data.email !== existing.email) {\n const pipeline = (await this.getRedis()).pipeline();\n pipeline.del(this.userByEmailKey(existing.email));\n pipeline.set(this.userByEmailKey(data.email), userId);\n await pipeline.exec();\n }\n\n await (\n await this.getRedis()\n ).hset(this.userKey(userId), this.userToHash(updated));\n return updated;\n }\n\n async deleteUser(userId: string): Promise<boolean> {\n const user = await this.findUserById(userId);\n if (!user) return false;\n\n const pipeline = (await this.getRedis()).pipeline();\n pipeline.del(this.userKey(userId));\n pipeline.del(this.userByEmailKey(user.email));\n pipeline.del(this.passwordHistoryKey(userId));\n await pipeline.exec();\n\n return true;\n }\n\n async hashPassword(password: string): Promise<string> {\n return bcrypt.hash(password, 12);\n }\n\n async verifyPassword(\n email: string,\n password: string,\n ): Promise<AuthUser | null> {\n const userId = await (\n await this.getRedis()\n ).get(this.userByEmailKey(email));\n if (!userId) return null;\n const user = await this.findUserById(userId);\n if (!user || !user.passwordHash) return null;\n const valid = await bcrypt.compare(password, user.passwordHash);\n return valid ? user : null;\n }\n\n async createSession(\n userId: string,\n data: {\n ipAddress?: string;\n userAgent?: string;\n } = {},\n ): Promise<Session> {\n const sessionId = randomBytes(32).toString(\"hex\");\n const token = randomBytes(32).toString(\"base64url\");\n const refreshToken = randomBytes(32).toString(\"base64url\");\n const now = new Date();\n\n const session: Session = {\n id: sessionId,\n userId,\n token,\n refreshToken,\n expiresAt: new Date(\n now.getTime() + this.tokenExpiration * 1000,\n ).toISOString(),\n createdAt: now.toISOString(),\n ipAddress: data.ipAddress,\n userAgent: data.userAgent,\n };\n\n const pipeline = (await this.getRedis()).pipeline();\n\n pipeline.hset(this.sessionKey(sessionId), this.sessionToHash(session));\n pipeline.setex(\n this.refreshKey(refreshToken),\n this.refreshExpiration,\n sessionId,\n );\n\n await pipeline.exec();\n\n return session;\n }\n\n async findSessionByToken(token: string): Promise<Session | null> {\n const data = await (await this.getRedis()).hgetall(this.sessionKey(token));\n if (!data || Object.keys(data).length === 0) return null;\n return this.hashToSession(data);\n }\n\n async findSessionByRefreshToken(\n refreshToken: string,\n ): Promise<Session | null> {\n const sessionId = await (\n await this.getRedis()\n ).get(this.refreshKey(refreshToken));\n if (!sessionId) return null;\n const data = await (\n await this.getRedis()\n ).hgetall(this.sessionKey(sessionId));\n if (!data || Object.keys(data).length === 0) return null;\n return this.hashToSession(data);\n }\n\n async deleteSession(sessionId: string): Promise<boolean> {\n const session = await (\n await this.getRedis()\n ).hgetall(this.sessionKey(sessionId));\n if (!session || Object.keys(session).length === 0) return false;\n\n const pipeline = (await this.getRedis()).pipeline();\n pipeline.del(this.sessionKey(sessionId));\n if (session.refreshToken) {\n pipeline.del(this.refreshKey(session.refreshToken));\n }\n await pipeline.exec();\n\n return true;\n }\n\n async deleteUserSessions(userId: string): Promise<number> {\n const pattern = `${this.prefix}sessions:*`;\n let cursor = \"0\";\n let deleted = 0;\n\n do {\n const [nextCursor, keys] = await (\n await this.getRedis()\n ).scan(cursor, \"MATCH\", pattern, \"COUNT\", 100);\n cursor = nextCursor;\n\n for (const key of keys) {\n const sessionData = await (await this.getRedis()).hgetall(key);\n if (sessionData.userId === userId) {\n const sessionId = key.replace(`${this.prefix}sessions:`, \"\");\n await this.deleteSession(sessionId);\n deleted++;\n }\n }\n } while (cursor !== \"0\");\n\n return deleted;\n }\n\n async addPasswordToHistory(\n userId: string,\n passwordHash: string,\n ): Promise<void> {\n await (\n await this.getRedis()\n ).lpush(this.passwordHistoryKey(userId), passwordHash);\n await (await this.getRedis()).ltrim(this.passwordHistoryKey(userId), 0, 4);\n }\n\n async getPasswordHistory(\n userId: string,\n count: number = 5,\n ): Promise<string[]> {\n return (await this.getRedis()).lrange(\n this.passwordHistoryKey(userId),\n 0,\n count - 1,\n );\n }\n\n async isPasswordInHistory(\n password: string,\n userId: string,\n historyCount: number = 5,\n ): Promise<boolean> {\n const history = await this.getPasswordHistory(userId, historyCount);\n\n for (const hash of history) {\n if (await bcrypt.compare(password, hash)) {\n return true;\n }\n }\n\n return false;\n }\n\n private userToHash(user: AuthUser): Record<string, string> {\n const hash: Record<string, string> = {\n id: user.id,\n email: user.email,\n passwordHash: user.passwordHash || \"\",\n role: user.role,\n createdAt: user.createdAt,\n updatedAt: user.updatedAt,\n };\n\n if (user.avatar) hash.avatar = user.avatar;\n if (user.tenantId) hash.tenantId = user.tenantId;\n if (user.emailVerified !== undefined)\n hash.emailVerified = String(user.emailVerified);\n if (user.locked !== undefined) hash.locked = String(user.locked);\n if (user.lastLogin) hash.lastLogin = user.lastLogin;\n if (user.failedLoginAttempts !== undefined)\n hash.failedLoginAttempts = String(user.failedLoginAttempts);\n\n return hash;\n }\n\n private hashToUser(hash: Record<string, string>): AuthUser {\n return {\n id: hash.id,\n email: hash.email,\n passwordHash: hash.passwordHash,\n role: hash.role as UserRole,\n tenantId: hash.tenantId,\n avatar: hash.avatar,\n createdAt: hash.createdAt,\n updatedAt: hash.updatedAt,\n emailVerified: hash.emailVerified === \"true\",\n locked: hash.locked === \"true\",\n lastLogin: hash.lastLogin,\n failedLoginAttempts: hash.failedLoginAttempts\n ? parseInt(hash.failedLoginAttempts, 10)\n : 0,\n };\n }\n\n private sessionToHash(session: Session): Record<string, string> {\n const hash: Record<string, string> = {\n id: session.id,\n userId: session.userId,\n token: session.token,\n expiresAt: session.expiresAt,\n createdAt: session.createdAt,\n };\n\n if (session.refreshToken) hash.refreshToken = session.refreshToken;\n if (session.ipAddress) hash.ipAddress = session.ipAddress;\n if (session.userAgent) hash.userAgent = session.userAgent;\n\n return hash;\n }\n\n private hashToSession(hash: Record<string, string>): Session {\n return {\n id: hash.id,\n userId: hash.userId,\n token: hash.token,\n refreshToken: hash.refreshToken,\n expiresAt: hash.expiresAt,\n createdAt: hash.createdAt,\n ipAddress: hash.ipAddress,\n userAgent: hash.userAgent,\n };\n }\n\n private tokenKey(tokenType: string, token: string): string {\n return `${this.prefix}tokens:${tokenType}:${token}`;\n }\n\n async createEmailVerificationToken(userId: string): Promise<{ token: string; expiresAt: Date }> {\n const token = randomBytes(32).toString(\"hex\");\n const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1000); // 24 hours\n const redis = await this.getRedis();\n await redis.setex(this.tokenKey(\"email-verify\", token), 86400, userId);\n return { token, expiresAt };\n }\n\n async verifyEmailToken(token: string): Promise<{ success: boolean; userId?: string; error?: string }> {\n const redis = await this.getRedis();\n const userId = await redis.get(this.tokenKey(\"email-verify\", token));\n if (!userId) {\n return { success: false, error: \"Invalid or expired token\" };\n }\n await redis.del(this.tokenKey(\"email-verify\", token));\n return { success: true, userId };\n }\n\n async createPasswordResetToken(email: string): Promise<{ token: string; expiresAt: Date; error?: string }> {\n const user = await this.findUserByEmail(email);\n if (!user) {\n return { token: \"\", expiresAt: new Date(), error: \"User not found\" };\n }\n const token = randomBytes(32).toString(\"hex\");\n const expiresAt = new Date(Date.now() + 60 * 60 * 1000); // 1 hour\n const redis = await this.getRedis();\n await redis.setex(this.tokenKey(\"password-reset\", token), 3600, user.id);\n return { token, expiresAt };\n }\n\n async resetPasswordWithToken(token: string, newPassword: string): Promise<{ success: boolean; error?: string }> {\n const redis = await this.getRedis();\n const userId = await redis.get(this.tokenKey(\"password-reset\", token));\n if (!userId) {\n return { success: false, error: \"Invalid or expired token\" };\n }\n const passwordHash = await this.hashPassword(newPassword);\n await this.updateUser(userId, { passwordHash });\n await redis.del(this.tokenKey(\"password-reset\", token));\n return { success: true };\n }\n\n private auditLogKey(id: string): string {\n return `${this.prefix}audit:logs:${id}`;\n }\n\n private auditLogIndexKey(): string {\n return `${this.prefix}audit:index`;\n }\n\n async findAuditLogs(filter: {\n userId?: string;\n action?: string | string[];\n resource?: string;\n success?: boolean;\n limit?: number;\n offset?: number;\n }): Promise<{ logs: any[]; total: number }> {\n const { limit = 50, offset = 0 } = filter;\n const indexKey = this.auditLogIndexKey();\n const allIds = await (await this.getRedis()).zrevrange(indexKey, 0, -1);\n const total = allIds.length;\n\n const pagedIds = allIds.slice(offset, offset + limit);\n const logs: any[] = [];\n\n for (const id of pagedIds) {\n const logData = await (await this.getRedis()).get(this.auditLogKey(id));\n if (logData) {\n const log = JSON.parse(logData);\n if (\n (!filter.userId || log.userId === filter.userId) &&\n (!filter.action ||\n (Array.isArray(filter.action)\n ? filter.action.includes(log.action)\n : log.action === filter.action)) &&\n (!filter.resource || log.resource === filter.resource) &&\n (filter.success === undefined || log.success === filter.success)\n ) {\n logs.push({ ...log, timestamp: new Date(log.timestamp) });\n }\n }\n }\n\n return { logs, total };\n }\n\n async createAuditLog(data: any): Promise<any> {\n const id = randomBytes(16).toString(\"hex\");\n const timestamp = new Date();\n const log = { ...data, id, timestamp };\n await (\n await this.getRedis()\n ).set(this.auditLogKey(id), JSON.stringify(log));\n await (await this.getRedis()).zadd(this.auditLogIndexKey(), Date.now(), id);\n const count = await (await this.getRedis()).zcard(this.auditLogIndexKey());\n if (count > 10000) {\n const oldIds = await (\n await this.getRedis()\n ).zrange(this.auditLogIndexKey(), 0, count - 10001);\n for (const oldId of oldIds) {\n await (await this.getRedis()).del(this.auditLogKey(oldId));\n await (await this.getRedis()).zrem(this.auditLogIndexKey(), oldId);\n }\n }\n return log;\n }\n}\n"]}
@@ -0,0 +1,92 @@
1
+ import { createKyro, LocalAdapter } from './chunk-22M4O4ZJ.js';
2
+ import { autoBootstrap } from './chunk-P2HKJ7P5.js';
3
+ import { SQLiteAuthAdapter } from './chunk-Q72BOAPK.js';
4
+ import { DrizzleAdapter } from './chunk-EJN2PAOE.js';
5
+ import { PostgresAuthAdapter } from './chunk-FOPGUM27.js';
6
+ import { MongoDBAdapter } from './chunk-VO35MNPH.js';
7
+ import { MongoDBAuthAdapter } from './chunk-7OGPN7MP.js';
8
+ import projectConfig from 'kyro:config';
9
+
10
+ var kyroInstance = null;
11
+ var initPromise = null;
12
+ async function doInit() {
13
+ if (kyroInstance) return;
14
+ try {
15
+ const config = projectConfig.default || projectConfig;
16
+ kyroInstance = createKyro(config);
17
+ await kyroInstance.init();
18
+ await kyroInstance.loadSettings();
19
+ const db = kyroInstance.db;
20
+ let bootstrapAuthAdapter = void 0;
21
+ if (db instanceof DrizzleAdapter) {
22
+ if (db.dialect === "postgres") {
23
+ bootstrapAuthAdapter = new PostgresAuthAdapter({ db: db.client });
24
+ } else if (db.dialect === "sqlite") {
25
+ const authDbPath = process.env.KYRO_AUTH_DB_PATH || "./data/auth.db";
26
+ bootstrapAuthAdapter = new SQLiteAuthAdapter({ path: authDbPath });
27
+ }
28
+ } else if (db instanceof LocalAdapter) {
29
+ const authDbPath = process.env.KYRO_AUTH_DB_PATH || "./data/auth.db";
30
+ bootstrapAuthAdapter = new SQLiteAuthAdapter({ path: authDbPath });
31
+ } else if (db instanceof MongoDBAdapter) {
32
+ bootstrapAuthAdapter = new MongoDBAuthAdapter({ db: db.db });
33
+ }
34
+ if (bootstrapAuthAdapter?.connect) {
35
+ await bootstrapAuthAdapter.connect();
36
+ }
37
+ const result = await autoBootstrap(bootstrapAuthAdapter);
38
+ if (result?.success) {
39
+ console.log(`[Kyro] Admin user auto-created from env: ${result.user?.email}`);
40
+ }
41
+ if (typeof kyroInstance.startWebSocket === "function") {
42
+ kyroInstance.startWebSocket().catch((err) => {
43
+ console.error("[Kyro] WebSocket auto-start failed:", err);
44
+ });
45
+ }
46
+ globalThis.__KYRO_INSTANCE__ = kyroInstance;
47
+ console.log("[Kyro API] Backend initialized via Astro Integration");
48
+ } catch (err) {
49
+ kyroInstance = null;
50
+ initPromise = null;
51
+ console.error("[Kyro API] Init failed, will retry:", err);
52
+ throw err;
53
+ }
54
+ }
55
+ async function warmKyroInstance() {
56
+ if (!initPromise) {
57
+ initPromise = doInit();
58
+ }
59
+ await initPromise;
60
+ }
61
+ var ALL = async (context) => {
62
+ if (!kyroInstance) {
63
+ if (!initPromise) {
64
+ initPromise = doInit();
65
+ }
66
+ try {
67
+ await Promise.race([
68
+ initPromise,
69
+ new Promise(
70
+ (_, reject) => setTimeout(() => reject(new Error("Initialization timeout")), 3e4)
71
+ )
72
+ ]);
73
+ } catch {
74
+ return new Response(JSON.stringify({
75
+ error: "Service Unavailable",
76
+ message: "Kyro CMS is still starting up. Please try again in a moment."
77
+ }), {
78
+ status: 503,
79
+ headers: {
80
+ "Content-Type": "application/json",
81
+ "Retry-After": "5"
82
+ }
83
+ });
84
+ }
85
+ }
86
+ const app = kyroInstance.getREST();
87
+ return app.fetch(context.request, context.locals);
88
+ };
89
+
90
+ export { ALL, kyroInstance, warmKyroInstance };
91
+ //# sourceMappingURL=chunk-SPBTLUN6.js.map
92
+ //# sourceMappingURL=chunk-SPBTLUN6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/api-handler.ts"],"names":[],"mappings":"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","file":"chunk-SPBTLUN6.js","sourcesContent":["import type { APIRoute } from \"astro\";\nimport { createKyro } from \"./createKyro.js\";\nimport { autoBootstrap } from \"./auth/bootstrap.js\";\nimport { DrizzleAdapter } from \"./database/drizzle/adapter.js\";\nimport { PostgresAuthAdapter } from \"./database/drizzle/postgres-auth-adapter.js\";\nimport { LocalAdapter } from \"./database/local/adapter.js\";\nimport { SQLiteAuthAdapter } from \"./auth/sqlite-adapter.js\";\nimport { MongoDBAdapter } from \"./database/mongodb/adapter.js\";\nimport { MongoDBAuthAdapter } from \"./database/mongodb/mongo-auth-adapter.js\";\n// @ts-ignore - handled by vite alias\nimport projectConfig from \"kyro:config\";\n\nexport let kyroInstance: any = null;\nlet initPromise: Promise<void> | null = null;\n\nasync function doInit(): Promise<void> {\n if (kyroInstance) return;\n\n try {\n const config = projectConfig.default || projectConfig;\n kyroInstance = createKyro(config);\n await kyroInstance.init();\n await kyroInstance.loadSettings();\n\n const db = kyroInstance.db;\n let bootstrapAuthAdapter: any = undefined;\n \n if (db instanceof DrizzleAdapter) {\n if (db.dialect === \"postgres\") {\n bootstrapAuthAdapter = new PostgresAuthAdapter({ db: db.client });\n } else if (db.dialect === \"sqlite\") {\n const authDbPath = process.env.KYRO_AUTH_DB_PATH || \"./data/auth.db\";\n bootstrapAuthAdapter = new SQLiteAuthAdapter({ path: authDbPath });\n }\n } else if (db instanceof LocalAdapter) {\n const authDbPath = process.env.KYRO_AUTH_DB_PATH || \"./data/auth.db\";\n bootstrapAuthAdapter = new SQLiteAuthAdapter({ path: authDbPath });\n } else if (db instanceof MongoDBAdapter) {\n bootstrapAuthAdapter = new MongoDBAuthAdapter({ db: db.db });\n }\n\n if (bootstrapAuthAdapter?.connect) {\n await bootstrapAuthAdapter.connect();\n }\n\n const result = await autoBootstrap(bootstrapAuthAdapter);\n if (result?.success) {\n console.log(`[Kyro] Admin user auto-created from env: ${result.user?.email}`);\n }\n\n // Auto-start WebSocket (checks settings.access.apiAccess.wsEnabled internally)\n if (typeof kyroInstance.startWebSocket === \"function\") {\n kyroInstance.startWebSocket().catch((err: any) => {\n console.error(\"[Kyro] WebSocket auto-start failed:\", err);\n });\n }\n\n // Expose instance globally so admin SSR can read DB directly\n (globalThis as any).__KYRO_INSTANCE__ = kyroInstance;\n\n console.log(\"[Kyro API] Backend initialized via Astro Integration\");\n } catch (err) {\n kyroInstance = null;\n initPromise = null;\n console.error(\"[Kyro API] Init failed, will retry:\", err);\n throw err;\n }\n}\n\nexport async function warmKyroInstance(): Promise<void> {\n if (!initPromise) {\n initPromise = doInit();\n }\n await initPromise;\n}\n\nexport const ALL: APIRoute = async (context) => {\n if (!kyroInstance) {\n if (!initPromise) {\n initPromise = doInit();\n }\n\n try {\n await Promise.race([\n initPromise,\n new Promise<void>((_, reject) =>\n setTimeout(() => reject(new Error(\"Initialization timeout\")), 30000)\n ),\n ]);\n } catch {\n return new Response(JSON.stringify({\n error: \"Service Unavailable\",\n message: \"Kyro CMS is still starting up. Please try again in a moment.\",\n }), {\n status: 503,\n headers: {\n \"Content-Type\": \"application/json\",\n \"Retry-After\": \"5\",\n },\n });\n }\n }\n\n const app = kyroInstance.getREST();\n return app.fetch(context.request, context.locals);\n};\n"]}
@@ -270,7 +270,7 @@ var ConfigService = class _ConfigService {
270
270
  signKey: this.get("storage.imgix.sign_key", "IMGIX_SIGN_KEY")
271
271
  },
272
272
  local: {
273
- uploadDir: this.get("storage.local.dir", "STORAGE_LOCAL_DIR"),
273
+ uploadDir: this.get("storage.local.dir", "STORAGE_LOCAL_DIR", "./public/uploads"),
274
274
  baseUrl: this.get("storage.local.url", "STORAGE_LOCAL_URL", "/uploads")
275
275
  }
276
276
  };
@@ -1056,5 +1056,5 @@ var PasswordPolicy = class {
1056
1056
  };
1057
1057
 
1058
1058
  export { ConfigService, EmailTransport, PasswordPolicy };
1059
- //# sourceMappingURL=chunk-57P6MJKC.js.map
1060
- //# sourceMappingURL=chunk-57P6MJKC.js.map
1059
+ //# sourceMappingURL=chunk-TXSZFA4G.js.map
1060
+ //# sourceMappingURL=chunk-TXSZFA4G.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config/ConfigService.ts","../src/auth/nodemailer-transport.ts","../src/auth/security/password-policy.ts"],"names":[],"mappings":"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","file":"chunk-TXSZFA4G.js","sourcesContent":["import { eq } from \"drizzle-orm\";\nimport { settings as settingsSchema } from \"../database/drizzle/schema/settings.js\";\n\nlet _settingsTableEnsured = false;\nlet _loaded = false;\n\nexport interface S3CompatibleConfig {\n bucket?: string;\n region?: string;\n accessKeyId?: string;\n secretAccessKey?: string;\n endpoint?: string;\n cdnUrl?: string;\n prefix?: string;\n}\n\nexport interface R2Config {\n accountId?: string;\n accessKeyId?: string;\n secretAccessKey?: string;\n bucket?: string;\n cdnUrl?: string;\n prefix?: string;\n publicDevUrl?: string;\n}\n\nexport interface GCSConfig {\n bucket?: string;\n projectId?: string;\n clientEmail?: string;\n privateKey?: string;\n cdnUrl?: string;\n prefix?: string;\n}\n\nexport interface BackblazeConfig {\n bucket?: string;\n accountId?: string;\n applicationKeyId?: string;\n applicationKey?: string;\n cdnUrl?: string;\n prefix?: string;\n}\n\nexport interface BunnyConfig {\n storageZone?: string;\n apiKey?: string;\n cdnUrl?: string;\n prefix?: string;\n}\n\nexport interface FTPConfig {\n host?: string;\n port?: number;\n user?: string;\n password?: string;\n secure?: boolean;\n baseUrl?: string;\n prefix?: string;\n}\n\nexport interface StorageConfig {\n type: string;\n s3: S3CompatibleConfig;\n r2: R2Config;\n gcs: GCSConfig;\n digitalocean: S3CompatibleConfig;\n backblaze: BackblazeConfig;\n wasabi: S3CompatibleConfig;\n bunny: BunnyConfig;\n ftp: FTPConfig;\n cloudinary: {\n cloudName?: string;\n apiKey?: string;\n apiSecret?: string;\n folder?: string;\n };\n imgix: {\n domain?: string;\n signKey?: string;\n };\n local: {\n uploadDir?: string;\n baseUrl?: string;\n };\n}\n\nexport interface EmailConfig {\n provider?: string;\n host?: string;\n port?: number;\n secure?: boolean;\n user?: string;\n pass?: string;\n from?: string;\n fromName?: string;\n replyTo?: string;\n}\n\nexport class ConfigService {\n private db: any;\n private cache: Record<string, string> = {};\n private static readonly SENSITIVE_KEYS = [\n \"storage.s3.secret_access_key\",\n \"storage.r2.secret_access_key\",\n \"storage.gcs.private_key\",\n \"storage.backblaze.application_key\",\n \"storage.wasabi.secret_access_key\",\n \"storage.ftp.password\",\n \"storage.bunny.api_key\",\n \"storage.cloudinary.api_secret\",\n \"storage.imgix.sign_key\",\n \"email.smtp.pass\",\n \"auth.jwt_secret\",\n \"auth.github_secret\",\n \"auth.google_secret\",\n \"auth.app_secret\",\n \"database.url\",\n \"redis.url\",\n \"auth.admin_password\",\n ];\n\n constructor(db: any) {\n this.db = db;\n }\n\n /**\n * Initialize the service by loading all settings from the database\n */\n async load(): Promise<void> {\n if (_loaded) return;\n\n await this.ensureSettingsTable();\n\n try {\n if (typeof this.db?.select === \"function\") {\n const allSettings = await this.db.select().from(settingsSchema);\n this.cache = allSettings.reduce((acc: any, row: any) => {\n acc[row.key] = row.value;\n return acc;\n }, {});\n } else {\n await this.loadFromGlobals();\n }\n } catch (error) {\n console.warn(\n \"ConfigService: Could not load settings from database, using environment fallbacks.\",\n );\n }\n\n _loaded = true;\n }\n\n private async ensureSettingsTable(): Promise<void> {\n if (_settingsTableEnsured) return;\n\n try {\n if (typeof this.db?.execute === \"function\") {\n const { sql } = await import(\"drizzle-orm\");\n await this.db.execute(sql`\n CREATE TABLE IF NOT EXISTS \"settings\" (\n \"key\" VARCHAR(255) PRIMARY KEY,\n \"value\" TEXT NOT NULL,\n \"description\" TEXT,\n \"updated_at\" TIMESTAMP DEFAULT NOW()\n )\n `);\n _settingsTableEnsured = true;\n } else if (typeof this.db?.exec === \"function\") {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS settings (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL,\n description TEXT,\n updated_at TEXT\n )\n `);\n _settingsTableEnsured = true;\n }\n } catch {\n // Table creation failed — will fall back to env vars\n }\n }\n\n /**\n * Load settings from the _globals_storage-settings table (SQLite fallback)\n * Maps nested global structure to flat key-value cache\n */\n private async loadFromGlobals(): Promise<void> {\n try {\n const row = this.db\n .prepare(`SELECT * FROM \"_globals_storage-settings\" LIMIT 1`)\n .get() as any;\n\n if (!row) return;\n\n const parseJSON = (val: any) => {\n if (!val) return null;\n if (typeof val === \"string\") {\n try {\n return JSON.parse(val);\n } catch {\n return null;\n }\n }\n return val;\n };\n\n const provider = row.provider || \"local\";\n this.cache[\"storage.type\"] = provider === \"aws\" ? \"s3\" : provider;\n\n if (provider === \"local\") {\n const local = parseJSON(row.local);\n this.cache[\"storage.local.dir\"] =\n local?.uploadDir || \"./public/uploads\";\n this.cache[\"storage.local.url\"] = local?.baseUrl || \"/uploads\";\n }\n\n if (provider === \"aws\") {\n const aws = parseJSON(row.aws);\n this.cache[\"storage.s3.bucket\"] = aws?.bucket || \"\";\n this.cache[\"storage.s3.region\"] = aws?.region || \"us-east-1\";\n this.cache[\"storage.s3.access_key_id\"] = aws?.accessKeyId || \"\";\n this.cache[\"storage.s3.secret_access_key\"] = aws?.secretAccessKey || \"\";\n this.cache[\"storage.s3.endpoint\"] = aws?.endpoint || \"\";\n this.cache[\"storage.s3.cdn_url\"] = aws?.cdnUrl || \"\";\n this.cache[\"storage.s3.prefix\"] = aws?.prefix || \"\";\n }\n\n if (provider === \"r2\") {\n const r2 = parseJSON(row.r2);\n this.cache[\"storage.r2.account_id\"] = r2?.accountId || \"\";\n this.cache[\"storage.r2.access_key_id\"] = r2?.accessKeyId || \"\";\n this.cache[\"storage.r2.secret_access_key\"] = r2?.secretAccessKey || \"\";\n this.cache[\"storage.r2.bucket\"] = r2?.bucket || \"\";\n this.cache[\"storage.r2.cdn_url\"] = r2?.cdnUrl || \"\";\n this.cache[\"storage.r2.prefix\"] = r2?.prefix || \"\";\n }\n\n if (provider === \"cloudinary\") {\n const cloudinary = parseJSON(row.cloudinary);\n this.cache[\"storage.cloudinary.cloud_name\"] =\n cloudinary?.cloudName || \"\";\n this.cache[\"storage.cloudinary.api_key\"] = cloudinary?.apiKey || \"\";\n this.cache[\"storage.cloudinary.api_secret\"] =\n cloudinary?.apiSecret || \"\";\n this.cache[\"storage.cloudinary.folder\"] = cloudinary?.folder || \"\";\n }\n\n if (provider === \"ftp\") {\n const ftp = parseJSON(row.ftp);\n this.cache[\"storage.ftp.host\"] = ftp?.host || \"\";\n this.cache[\"storage.ftp.port\"] = String(ftp?.port || \"21\");\n this.cache[\"storage.ftp.user\"] = ftp?.user || \"\";\n this.cache[\"storage.ftp.password\"] = ftp?.password || \"\";\n this.cache[\"storage.ftp.secure\"] = ftp?.secure ? \"true\" : \"false\";\n this.cache[\"storage.ftp.base_url\"] = ftp?.baseUrl || \"\";\n this.cache[\"storage.ftp.prefix\"] = ftp?.prefix || \"\";\n }\n } catch (error) {\n console.warn(\"ConfigService: Could not load from globals table:\", error);\n }\n }\n\n /**\n * Get a settings value with environment fallback\n */\n get(key: string, envKey?: string, defaultValue?: string): string | undefined {\n // 1. Check database cache\n if (this.cache[key]) return this.cache[key];\n\n // 2. Check environment variable\n if (envKey && process.env[envKey]) return process.env[envKey];\n\n // 3. Return default\n return defaultValue;\n }\n\n /**\n * Get storage configuration\n */\n getStorageConfig(): StorageConfig {\n return {\n type: this.get(\"storage.type\", \"STORAGE_TYPE\", \"local\")!,\n s3: {\n bucket: this.get(\"storage.s3.bucket\", \"STORAGE_BUCKET\"),\n region: this.get(\"storage.s3.region\", \"STORAGE_REGION\", \"us-east-1\"),\n accessKeyId: this.get(\n \"storage.s3.access_key_id\",\n \"STORAGE_ACCESS_KEY_ID\",\n ),\n secretAccessKey: this.get(\n \"storage.s3.secret_access_key\",\n \"STORAGE_SECRET_ACCESS_KEY\",\n ),\n endpoint: this.get(\"storage.s3.endpoint\", \"STORAGE_ENDPOINT\"),\n cdnUrl: this.get(\"storage.s3.cdn_url\", \"STORAGE_CDN_URL\"),\n prefix: this.get(\"storage.s3.prefix\", \"STORAGE_PREFIX\"),\n },\n r2: {\n accountId: this.get(\"storage.r2.account_id\", \"R2_ACCOUNT_ID\"),\n accessKeyId: this.get(\"storage.r2.access_key_id\", \"R2_ACCESS_KEY_ID\"),\n secretAccessKey: this.get(\n \"storage.r2.secret_access_key\",\n \"R2_SECRET_ACCESS_KEY\",\n ),\n bucket: this.get(\"storage.r2.bucket\", \"R2_BUCKET\"),\n cdnUrl: this.get(\"storage.r2.cdn_url\", \"R2_CDN_URL\"),\n prefix: this.get(\"storage.r2.prefix\", \"R2_PREFIX\"),\n },\n gcs: {\n bucket: this.get(\"storage.gcs.bucket\", \"GCS_BUCKET\"),\n projectId: this.get(\"storage.gcs.project_id\", \"GCS_PROJECT_ID\"),\n clientEmail: this.get(\"storage.gcs.client_email\", \"GCS_CLIENT_EMAIL\"),\n privateKey: this.get(\"storage.gcs.private_key\", \"GCS_PRIVATE_KEY\"),\n cdnUrl: this.get(\"storage.gcs.cdn_url\", \"GCS_CDN_URL\"),\n prefix: this.get(\"storage.gcs.prefix\", \"GCS_PREFIX\"),\n },\n digitalocean: {\n bucket: this.get(\"storage.digitalocean.bucket\", \"DO_BUCKET\"),\n region: this.get(\"storage.digitalocean.region\", \"DO_REGION\", \"nyc3\"),\n accessKeyId: this.get(\n \"storage.digitalocean.access_key_id\",\n \"DO_ACCESS_KEY_ID\",\n ),\n secretAccessKey: this.get(\n \"storage.digitalocean.secret_access_key\",\n \"DO_SECRET_ACCESS_KEY\",\n ),\n cdnUrl: this.get(\"storage.digitalocean.cdn_url\", \"DO_CDN_URL\"),\n prefix: this.get(\"storage.digitalocean.prefix\", \"DO_PREFIX\"),\n },\n backblaze: {\n bucket: this.get(\"storage.backblaze.bucket\", \"BB_BUCKET\"),\n accountId: this.get(\"storage.backblaze.account_id\", \"BB_ACCOUNT_ID\"),\n applicationKeyId: this.get(\n \"storage.backblaze.application_key_id\",\n \"BB_APPLICATION_KEY_ID\",\n ),\n applicationKey: this.get(\n \"storage.backblaze.application_key\",\n \"BB_APPLICATION_KEY\",\n ),\n cdnUrl: this.get(\"storage.backblaze.cdn_url\", \"BB_CDN_URL\"),\n prefix: this.get(\"storage.backblaze.prefix\", \"BB_PREFIX\"),\n },\n wasabi: {\n bucket: this.get(\"storage.wasabi.bucket\", \"WASABI_BUCKET\"),\n region: this.get(\"storage.wasabi.region\", \"WASABI_REGION\", \"us-east-1\"),\n accessKeyId: this.get(\n \"storage.wasabi.access_key_id\",\n \"WASABI_ACCESS_KEY_ID\",\n ),\n secretAccessKey: this.get(\n \"storage.wasabi.secret_access_key\",\n \"WASABI_SECRET_ACCESS_KEY\",\n ),\n cdnUrl: this.get(\"storage.wasabi.cdn_url\", \"WASABI_CDN_URL\"),\n prefix: this.get(\"storage.wasabi.prefix\", \"WASABI_PREFIX\"),\n },\n bunny: {\n storageZone: this.get(\n \"storage.bunny.storage_zone\",\n \"BUNNY_STORAGE_ZONE\",\n ),\n apiKey: this.get(\"storage.bunny.api_key\", \"BUNNY_API_KEY\"),\n cdnUrl: this.get(\"storage.bunny.cdn_url\", \"BUNNY_CDN_URL\"),\n prefix: this.get(\"storage.bunny.prefix\", \"BUNNY_PREFIX\"),\n },\n ftp: {\n host: this.get(\"storage.ftp.host\", \"FTP_HOST\"),\n port: parseInt(this.get(\"storage.ftp.port\", \"FTP_PORT\", \"21\")!, 10),\n user: this.get(\"storage.ftp.user\", \"FTP_USER\"),\n password: this.get(\"storage.ftp.password\", \"FTP_PASSWORD\"),\n secure: this.get(\"storage.ftp.secure\", \"FTP_SECURE\") === \"true\",\n baseUrl: this.get(\"storage.ftp.base_url\", \"FTP_BASE_URL\"),\n prefix: this.get(\"storage.ftp.prefix\", \"FTP_PREFIX\"),\n },\n cloudinary: {\n cloudName: this.get(\n \"storage.cloudinary.cloud_name\",\n \"CLOUDINARY_CLOUD_NAME\",\n ),\n apiKey: this.get(\"storage.cloudinary.api_key\", \"CLOUDINARY_API_KEY\"),\n apiSecret: this.get(\n \"storage.cloudinary.api_secret\",\n \"CLOUDINARY_API_SECRET\",\n ),\n folder: this.get(\"storage.cloudinary.folder\", \"CLOUDINARY_FOLDER\"),\n },\n imgix: {\n domain: this.get(\"storage.imgix.domain\", \"IMGIX_DOMAIN\"),\n signKey: this.get(\"storage.imgix.sign_key\", \"IMGIX_SIGN_KEY\"),\n },\n local: {\n uploadDir: this.get(\"storage.local.dir\", \"STORAGE_LOCAL_DIR\", \"./public/uploads\"),\n baseUrl: this.get(\"storage.local.url\", \"STORAGE_LOCAL_URL\", \"/uploads\"),\n },\n };\n }\n\n /**\n * Get email configuration\n */\n getEmailConfig(): EmailConfig {\n return {\n provider: this.get(\"email.provider\", \"EMAIL_PROVIDER\", \"smtp\"),\n host: this.get(\"email.smtp.host\", \"SMTP_HOST\"),\n port: parseInt(this.get(\"email.smtp.port\", \"SMTP_PORT\", \"587\")!, 10),\n secure: this.get(\"email.smtp.secure\", \"SMTP_SECURE\") === \"true\",\n user: this.get(\"email.smtp.user\", \"SMTP_USER\"),\n pass: this.get(\"email.smtp.pass\", \"SMTP_PASS\"),\n from: this.get(\"email.smtp.from\", \"SMTP_FROM\", \"noreply@example.com\"),\n fromName: this.get(\"email.smtp.from_name\", \"SMTP_FROM_NAME\", \"Kyro CMS\"),\n replyTo: this.get(\"email.smtp.reply_to\", \"SMTP_REPLY_TO\"),\n };\n }\n\n /**\n * Mask sensitive values for display\n */\n maskSensitive(key: string, value: string | undefined): string | undefined {\n if (!value) return value;\n if (ConfigService.SENSITIVE_KEYS.includes(key)) {\n return \"********\";\n }\n return value;\n }\n\n /**\n * Update a setting in the database\n */\n async set(key: string, value: string, description?: string): Promise<void> {\n await this.db\n .insert(settingsSchema)\n .values({\n key,\n value,\n description,\n updatedAt: new Date(),\n })\n .onConflictDoUpdate({\n target: [settingsSchema.key],\n set: { value, description, updatedAt: new Date() },\n });\n this.cache[key] = value;\n }\n}\n","import type { Transporter, SentMessageInfo } from \"nodemailer\";\n\nexport interface EmailConfig {\n provider: \"smtp\" | \"resend\" | \"sendgrid\" | \"mailgun\" | \"ses\";\n from: string;\n fromName?: string;\n replyTo?: string;\n smtp?: {\n host: string;\n port: number;\n secure: boolean;\n auth: {\n user: string;\n pass: string;\n };\n };\n resend?: {\n apiKey: string;\n };\n sendgrid?: {\n apiKey: string;\n };\n mailgun?: {\n apiKey: string;\n domain: string;\n region?: \"us\" | \"eu\";\n };\n ses?: {\n accessKeyId: string;\n secretAccessKey: string;\n region: string;\n };\n}\n\nexport interface EmailOptions {\n to: string | string[];\n subject: string;\n html: string;\n text?: string;\n replyTo?: string;\n}\n\nexport interface EmailTemplates {\n verifyEmail: (\n link: string,\n userName?: string,\n ) => { subject: string; html: string; text: string };\n resetPassword: (\n link: string,\n userName?: string,\n ) => { subject: string; html: string; text: string };\n welcome: (userName?: string) => {\n subject: string;\n html: string;\n text: string;\n };\n accountLocked: (\n attempts: number,\n duration: number,\n userName?: string,\n ) => { subject: string; html: string; text: string };\n passwordChanged: (userName?: string) => {\n subject: string;\n html: string;\n text: string;\n };\n newLogin: (\n location: string,\n time: string,\n userName?: string,\n ) => { subject: string; html: string; text: string };\n}\n\nconst defaultTemplates: EmailTemplates = {\n verifyEmail: (link, userName = \"User\") => ({\n subject: \"Verify your email address\",\n html: `\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>Verify Email</title>\n <style>\n body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; }\n .container { max-width: 600px; margin: 0 auto; padding: 20px; }\n .button { display: inline-block; padding: 12px 24px; background: #0b1222; color: white; text-decoration: none; border-radius: 6px; font-weight: 600; }\n .footer { margin-top: 30px; font-size: 12px; color: #666; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>Welcome, ${userName}!</h1>\n <p>Please verify your email address by clicking the button below:</p>\n <p style=\"text-align: center; margin: 30px 0;\">\n <a href=\"${link}\" class=\"button\">Verify Email</a>\n </p>\n <p>Or copy and paste this link into your browser:</p>\n <p style=\"word-break: break-all; color: #666;\">${link}</p>\n <p>This link will expire in 24 hours.</p>\n <div class=\"footer\">\n <p>If you didn't create an account, you can safely ignore this email.</p>\n </div>\n </div>\n </body>\n </html>\n `,\n text: `Welcome ${userName}!\\n\\nPlease verify your email by clicking this link: ${link}\\n\\nThis link will expire in 24 hours.\\n\\nIf you didn't create an account, you can safely ignore this email.`,\n }),\n\n resetPassword: (link, userName = \"User\") => ({\n subject: \"Reset your password\",\n html: `\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>Reset Password</title>\n <style>\n body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; }\n .container { max-width: 600px; margin: 0 auto; padding: 20px; }\n .button { display: inline-block; padding: 12px 24px; background: #dc2626; color: white; text-decoration: none; border-radius: 6px; font-weight: 600; }\n .warning { background: #fef3c7; border: 1px solid #f59e0b; padding: 12px; border-radius: 6px; margin: 20px 0; }\n .footer { margin-top: 30px; font-size: 12px; color: #666; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>Password Reset Request</h1>\n <p>Hello ${userName},</p>\n <p>We received a request to reset your password. Click the button below to create a new password:</p>\n <p style=\"text-align: center; margin: 30px 0;\">\n <a href=\"${link}\" class=\"button\">Reset Password</a>\n </p>\n <p>Or copy and paste this link into your browser:</p>\n <p style=\"word-break: break-all; color: #666;\">${link}</p>\n <div class=\"warning\">\n <strong>⚠️ Important:</strong> This link will expire in 1 hour. If you didn't request a password reset, please ignore this email or contact support if you have concerns.\n </div>\n <div class=\"footer\">\n <p>For security reasons, please don't share this email with anyone.</p>\n </div>\n </div>\n </body>\n </html>\n `,\n text: `Password Reset Request\\n\\nHello ${userName},\\n\\nWe received a request to reset your password. Click this link to create a new password: ${link}\\n\\nThis link will expire in 1 hour.\\n\\nIf you didn't request a password reset, please ignore this email.`,\n }),\n\n welcome: (userName = \"User\") => ({\n subject: \"Welcome to Kyro CMS\",\n html: `\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>Welcome</title>\n <style>\n body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; }\n .container { max-width: 600px; margin: 0 auto; padding: 20px; }\n .button { display: inline-block; padding: 12px 24px; background: #0b1222; color: white; text-decoration: none; border-radius: 6px; font-weight: 600; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>Welcome to Kyro CMS, ${userName}!</h1>\n <p>Your account has been created successfully.</p>\n <p>You can now:</p>\n <ul>\n <li>Manage your content collections</li>\n <li>Upload and organize media</li>\n <li>Configure settings</li>\n <li>And much more...</li>\n </ul>\n <p style=\"text-align: center; margin: 30px 0;\">\n <a href=\"#\" class=\"button\">Get Started</a>\n </p>\n <p>If you have any questions, feel free to reach out to our support team.</p>\n </div>\n </body>\n </html>\n `,\n text: `Welcome to Kyro CMS, ${userName}!\\n\\nYour account has been created successfully.\\n\\nYou can now:\\n- Manage your content collections\\n- Upload and organize media\\n- Configure settings\\n- And much more...\\n\\nGet started by logging into your dashboard.`,\n }),\n\n accountLocked: (attempts, duration, userName = \"User\") => ({\n subject: \"Account Security Alert - Account Locked\",\n html: `\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>Account Locked</title>\n <style>\n body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; }\n .container { max-width: 600px; margin: 0 auto; padding: 20px; }\n .alert { background: #fef2f2; border: 1px solid #ef4444; padding: 16px; border-radius: 8px; margin: 20px 0; }\n .footer { margin-top: 30px; font-size: 12px; color: #666; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>Account Security Alert</h1>\n <p>Hello ${userName},</p>\n <div class=\"alert\">\n <p><strong>⚠️ Your account has been temporarily locked due to multiple failed login attempts.</strong></p>\n <p>Failed attempts: ${attempts}</p>\n <p>Lockout duration: ${Math.round(duration / 60000)} minutes</p>\n </div>\n <p>Your account will automatically unlock after the lockout period expires.</p>\n <p>If this wasn't you, we recommend:</p>\n <ul>\n <li>Using a strong, unique password</li>\n <li>Enabling two-factor authentication (coming soon)</li>\n <li>Reviewing your recent account activity</li>\n </ul>\n <div class=\"footer\">\n <p>If you need immediate assistance, please contact support.</p>\n </div>\n </div>\n </body>\n </html>\n `,\n text: `Account Security Alert\\n\\nHello ${userName},\\n\\nYour account has been temporarily locked due to multiple failed login attempts (${attempts}).\\n\\nLockout duration: ${Math.round(duration / 60000)} minutes\\n\\nYour account will automatically unlock after this period.\\n\\nIf this wasn't you, we recommend using a strong, unique password.`,\n }),\n\n passwordChanged: (userName = \"User\") => ({\n subject: \"Your password has been changed\",\n html: `\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>Password Changed</title>\n <style>\n body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; }\n .container { max-width: 600px; margin: 0 auto; padding: 20px; }\n .info { background: #f0fdf4; border: 1px solid #22c55e; padding: 12px; border-radius: 6px; margin: 20px 0; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>Password Changed</h1>\n <p>Hello ${userName},</p>\n <div class=\"info\">\n <p>Your password was recently changed.</p>\n </div>\n <p>If you did this, you can safely ignore this email.</p>\n <p><strong>If you didn't change your password</strong>, please contact our support team immediately as your account may have been compromised.</p>\n </div>\n </body>\n </html>\n `,\n text: `Password Changed\\n\\nHello ${userName},\\n\\nYour password was recently changed.\\n\\nIf you did this, you can safely ignore this email.\\n\\nIf you didn't change your password, please contact support immediately.`,\n }),\n\n newLogin: (location, time, userName = \"User\") => ({\n subject: \"New login to your account\",\n html: `\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>New Login</title>\n <style>\n body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; }\n .container { max-width: 600px; margin: 0 auto; padding: 20px; }\n .info-box { background: #f8fafc; border: 1px solid #e2e8f0; padding: 16px; border-radius: 8px; margin: 20px 0; }\n .footer { margin-top: 30px; font-size: 12px; color: #666; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>New Login Detected</h1>\n <p>Hello ${userName},</p>\n <p>We detected a new login to your account:</p>\n <div class=\"info-box\">\n <p><strong>Location:</strong> ${location}</p>\n <p><strong>Time:</strong> ${time}</p>\n </div>\n <p><strong>If this was you</strong>, no action is needed.</p>\n <p><strong>If this wasn't you</strong>, your account may be compromised. Please:</p>\n <ol>\n <li>Change your password immediately</li>\n <li>Review your recent account activity</li>\n <li>Contact support if needed</li>\n </ol>\n <div class=\"footer\">\n <p>This is an automated security notification.</p>\n </div>\n </div>\n </body>\n </html>\n `,\n text: `New Login Detected\\n\\nHello ${userName},\\n\\nWe detected a new login to your account:\\n\\nLocation: ${location}\\nTime: ${time}\\n\\nIf this wasn't you, please change your password immediately and contact support.`,\n }),\n};\n\nimport { ConfigService } from \"../config/ConfigService.js\";\n\nexport class EmailTransport {\n private transporter?: Transporter<SentMessageInfo>;\n private config: EmailConfig;\n private templates: EmailTemplates;\n private transporterInitialized: boolean = false;\n\n constructor(config: EmailConfig, templates?: Partial<EmailTemplates>) {\n this.config = config;\n this.templates = { ...defaultTemplates, ...templates };\n }\n\n private async ensureTransporter(): Promise<Transporter<SentMessageInfo>> {\n if (this.transporterInitialized) {\n return this.transporter!;\n }\n\n const { default: nodemailer } = await import(\"nodemailer\");\n\n if (this.config.provider === \"smtp\" && this.config.smtp) {\n this.transporter = nodemailer.createTransport({\n host: this.config.smtp.host,\n port: this.config.smtp.port,\n secure: this.config.smtp.secure,\n auth: this.config.smtp.auth,\n });\n } else if (this.config.provider === \"ses\" && this.config.ses) {\n this.transporter = nodemailer.createTransport({\n host: `email-smtp.${this.config.ses.region}.amazonaws.com`,\n port: 587,\n secure: false,\n auth: {\n user: this.config.ses.accessKeyId,\n pass: this.config.ses.secretAccessKey,\n },\n });\n }\n\n this.transporterInitialized = true;\n return this.transporter!;\n }\n\n async send(options: EmailOptions): Promise<any> {\n const { provider, from, fromName, replyTo: configReplyTo } = this.config;\n const fromFull = `\"${fromName || \"Kyro CMS\"}\" <${from}>`;\n const replyTo = options.replyTo || configReplyTo;\n\n console.log(`[EmailTransport] Sending email via ${provider}...`);\n console.log(\n `[EmailTransport] To: ${Array.isArray(options.to) ? options.to.join(\", \") : options.to}`,\n );\n console.log(`[EmailTransport] Subject: ${options.subject}`);\n\n try {\n let result;\n switch (provider) {\n case \"smtp\":\n case \"ses\":\n {\n const transporter = await this.ensureTransporter();\n if (!transporter)\n throw new Error(`${provider} transporter not initialized`);\n result = await transporter.sendMail({\n from: fromFull,\n to: Array.isArray(options.to)\n ? options.to.join(\", \")\n : options.to,\n subject: options.subject,\n html: options.html,\n text: options.text,\n replyTo,\n });\n }\n break;\n\n case \"resend\":\n result = await this.sendViaResend(fromFull, options, replyTo);\n break;\n\n case \"sendgrid\":\n result = await this.sendViaSendGrid(fromFull, options, replyTo);\n break;\n\n case \"mailgun\":\n result = await this.sendViaMailgun(fromFull, options, replyTo);\n break;\n\n default:\n throw new Error(`Unsupported email provider: ${provider}`);\n }\n console.log(`[EmailTransport] Success! Provider response received.`);\n return result;\n } catch (error: any) {\n console.error(`[EmailTransport] FAILED to send email:`, error.message);\n if (error.response) {\n console.error(\n `[EmailTransport] Provider Error Detail:`,\n JSON.stringify(error.response, null, 2),\n );\n }\n throw error;\n }\n }\n\n private async sendViaResend(\n from: string,\n options: EmailOptions,\n replyTo?: string,\n ) {\n const apiKey = this.config.resend?.apiKey;\n if (!apiKey) throw new Error(\"Resend API Key missing\");\n\n const body = {\n from,\n to: options.to,\n subject: options.subject,\n html: options.html,\n text: options.text,\n reply_to: replyTo,\n };\n\n console.log(`[EmailTransport] Calling Resend API...`);\n const resp = await fetch(\"https://api.resend.com/emails\", {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n });\n\n if (!resp.ok) {\n const error = await resp.json();\n throw new Error(`Resend Error: ${JSON.stringify(error)}`);\n }\n return resp.json();\n }\n\n private async sendViaSendGrid(\n from: string,\n options: EmailOptions,\n replyTo?: string,\n ) {\n const apiKey = this.config.sendgrid?.apiKey;\n if (!apiKey) throw new Error(\"SendGrid API Key missing\");\n\n const body = {\n personalizations: [\n {\n to: Array.isArray(options.to)\n ? options.to.map((email) => ({ email }))\n : [{ email: options.to }],\n },\n ],\n from: {\n email: from.match(/<(.+)>/)?.[1] || from,\n name: from.match(/\"(.+)\"/)?.[1],\n },\n subject: options.subject,\n content: [\n { type: \"text/plain\", value: options.text || \"\" },\n { type: \"text/html\", value: options.html },\n ],\n reply_to: replyTo ? { email: replyTo } : undefined,\n };\n\n console.log(`[EmailTransport] Calling SendGrid API...`);\n const resp = await fetch(\"https://api.sendgrid.com/v3/mail/send\", {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n });\n\n if (!resp.ok) {\n const error = await resp.json();\n throw new Error(`SendGrid Error: ${JSON.stringify(error)}`);\n }\n return { success: true };\n }\n\n private async sendViaMailgun(\n from: string,\n options: EmailOptions,\n replyTo?: string,\n ) {\n const { apiKey, domain, region } = this.config.mailgun || {};\n if (!apiKey || !domain) throw new Error(\"Mailgun config missing\");\n\n const base = region === \"eu\" ? \"api.eu.mailgun.net\" : \"api.mailgun.net\";\n const auth = btoa(`api:${apiKey}`);\n\n const formData = new URLSearchParams();\n formData.append(\"from\", from);\n const to = Array.isArray(options.to) ? options.to.join(\", \") : options.to;\n formData.append(\"to\", to);\n formData.append(\"subject\", options.subject);\n formData.append(\"html\", options.html);\n if (options.text) formData.append(\"text\", options.text);\n if (replyTo) formData.append(\"h:Reply-To\", replyTo);\n\n console.log(`[EmailTransport] Calling Mailgun API (${region || \"us\"})...`);\n const resp = await fetch(`https://${base}/v3/${domain}/messages`, {\n method: \"POST\",\n headers: {\n Authorization: `Basic ${auth}`,\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n body: formData,\n });\n\n if (!resp.ok) {\n const error = await resp.json();\n throw new Error(`Mailgun Error: ${JSON.stringify(error)}`);\n }\n return resp.json();\n }\n\n getTemplates(): EmailTemplates {\n return this.templates;\n }\n\n async verifyConnection(): Promise<boolean> {\n if (this.config.provider === \"smtp\" || this.config.provider === \"ses\") {\n try {\n const transporter = await this.ensureTransporter();\n if (transporter) {\n await transporter.verify();\n return true;\n }\n } catch {\n return false;\n }\n }\n return !!(\n this.config.resend?.apiKey ||\n this.config.sendgrid?.apiKey ||\n this.config.mailgun?.apiKey\n );\n }\n\n static async fromConfig(db: any): Promise<EmailTransport | null> {\n const configService = new ConfigService(db);\n await configService.load();\n const config = configService.getEmailConfig();\n\n if (!config.provider) {\n return this.fromEnv();\n }\n\n const transformed: EmailConfig = {\n provider: (config.provider as any) || \"smtp\",\n from: config.from || \"noreply@example.com\",\n fromName: config.fromName,\n replyTo: config.replyTo,\n smtp:\n config.provider === \"smtp\"\n ? {\n host: config.host || \"\",\n port: config.port || 587,\n secure: config.secure || false,\n auth: { user: config.user || \"\", pass: config.pass || \"\" },\n }\n : undefined,\n resend:\n config.provider === \"resend\"\n ? { apiKey: config.pass || \"\" }\n : undefined,\n sendgrid:\n config.provider === \"sendgrid\"\n ? { apiKey: config.pass || \"\" }\n : undefined,\n mailgun:\n config.provider === \"mailgun\"\n ? {\n apiKey: config.pass || \"\",\n domain: config.host || \"\",\n region: (config.secure ? \"eu\" : \"us\") as any,\n }\n : undefined,\n ses:\n config.provider === \"ses\"\n ? {\n accessKeyId: config.user || \"\",\n secretAccessKey: config.pass || \"\",\n region: config.host || \"us-east-1\",\n }\n : undefined,\n };\n\n return new EmailTransport(transformed);\n }\n\n static fromEnv(): EmailTransport | null {\n const provider = (process.env.EMAIL_PROVIDER as any) || \"smtp\";\n const from =\n process.env.SMTP_FROM ||\n process.env.DEFAULT_FROM ||\n \"noreply@example.com\";\n const fromName = process.env.SMTP_FROM_NAME || \"Kyro CMS\";\n const replyTo = process.env.SMTP_REPLY_TO;\n\n if (provider === \"smtp\") {\n const host = process.env.SMTP_HOST;\n const user = process.env.SMTP_USER;\n const pass = process.env.SMTP_PASS;\n if (!host || !user || !pass) return null;\n\n return new EmailTransport({\n provider: \"smtp\",\n from,\n fromName,\n replyTo,\n smtp: {\n host,\n port: parseInt(process.env.SMTP_PORT || \"587\", 10),\n secure: process.env.SMTP_SECURE === \"true\",\n auth: { user, pass },\n },\n });\n }\n\n if (provider === \"resend\") {\n const apiKey = process.env.RESEND_API_KEY || process.env.SMTP_PASS;\n if (!apiKey) return null;\n return new EmailTransport({\n provider: \"resend\",\n from,\n fromName,\n replyTo,\n resend: { apiKey },\n });\n }\n\n if (provider === \"sendgrid\") {\n const apiKey = process.env.SENDGRID_API_KEY || process.env.SMTP_PASS;\n if (!apiKey) return null;\n return new EmailTransport({\n provider: \"sendgrid\",\n from,\n fromName,\n replyTo,\n sendgrid: { apiKey },\n });\n }\n\n if (provider === \"mailgun\") {\n const apiKey = process.env.MAILGUN_API_KEY || process.env.SMTP_PASS;\n const domain = process.env.MAILGUN_DOMAIN || process.env.SMTP_HOST;\n if (!apiKey || !domain) return null;\n return new EmailTransport({\n provider: \"mailgun\",\n from,\n fromName,\n replyTo,\n mailgun: {\n apiKey,\n domain,\n region: (process.env.MAILGUN_REGION ||\n (process.env.SMTP_SECURE === \"true\" ? \"eu\" : \"us\")) as any,\n },\n });\n }\n\n if (provider === \"ses\") {\n const accessKeyId =\n process.env.AWS_ACCESS_KEY_ID || process.env.SMTP_USER;\n const secretAccessKey =\n process.env.AWS_SECRET_ACCESS_KEY || process.env.SMTP_PASS;\n const region =\n process.env.AWS_REGION || process.env.SMTP_HOST || \"us-east-1\";\n if (!accessKeyId || !secretAccessKey) return null;\n return new EmailTransport({\n provider: \"ses\",\n from,\n fromName,\n replyTo,\n ses: { accessKeyId, secretAccessKey, region },\n });\n }\n\n return null;\n }\n}\n","export interface PasswordPolicyConfig {\n minLength: number;\n requireUppercase: boolean;\n requireLowercase: boolean;\n requireNumbers: boolean;\n requireSpecialChars: boolean;\n preventReuse: number;\n maxLength?: number;\n}\n\nexport interface ValidationResult {\n valid: boolean;\n errors: string[];\n}\n\nexport const DEFAULT_PASSWORD_POLICY: PasswordPolicyConfig = {\n minLength: 12,\n requireUppercase: true,\n requireLowercase: true,\n requireNumbers: true,\n requireSpecialChars: true,\n preventReuse: 5,\n maxLength: 128,\n};\n\nexport class PasswordPolicy {\n private config: PasswordPolicyConfig;\n\n constructor(config: Partial<PasswordPolicyConfig> = {}) {\n this.config = { ...DEFAULT_PASSWORD_POLICY, ...config };\n }\n\n validate(password: string): ValidationResult {\n const errors: string[] = [];\n\n if (this.config.maxLength && password.length > this.config.maxLength) {\n errors.push(\n `Password must not exceed ${this.config.maxLength} characters`,\n );\n }\n\n if (password.length < this.config.minLength) {\n errors.push(\n `Password must be at least ${this.config.minLength} characters`,\n );\n }\n\n if (this.config.requireUppercase && !/[A-Z]/.test(password)) {\n errors.push(\"Password must contain at least one uppercase letter\");\n }\n\n if (this.config.requireLowercase && !/[a-z]/.test(password)) {\n errors.push(\"Password must contain at least one lowercase letter\");\n }\n\n if (this.config.requireNumbers && !/[0-9]/.test(password)) {\n errors.push(\"Password must contain at least one number\");\n }\n\n if (\n this.config.requireSpecialChars &&\n !/[!@#$%^&*()_+\\-=\\[\\]{};':\"\\\\|,.<>\\/?]/.test(password)\n ) {\n errors.push(\"Password must contain at least one special character\");\n }\n\n const commonPasswords = [\n \"password\",\n \"123456\",\n \"12345678\",\n \"qwerty\",\n \"abc123\",\n \"monkey\",\n \"1234567\",\n \"letmein\",\n \"trustno1\",\n \"dragon\",\n \"baseball\",\n \"iloveyou\",\n \"master\",\n \"sunshine\",\n \"ashley\",\n \"football\",\n \"password1\",\n \"shadow\",\n \"123123\",\n \"654321\",\n ];\n\n if (commonPasswords.includes(password.toLowerCase())) {\n errors.push(\n \"This password is too common. Please choose a more secure password\",\n );\n }\n\n if (/^[a-zA-Z]+$/.test(password) || /^[0-9]+$/.test(password)) {\n errors.push(\n \"Password must contain a mix of letters, numbers, and/or special characters\",\n );\n }\n\n if (/(.)\\1{2,}/.test(password)) {\n errors.push(\n \"Password must not contain more than 2 consecutive identical characters\",\n );\n }\n\n if (\n /^(012|123|234|345|456|567|678|789|890|098|987|876|765|654|543|432|321|210)+$/i.test(\n password,\n )\n ) {\n errors.push(\"Password must not contain sequential numbers or letters\");\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n }\n\n async checkReuse(\n passwordHash: string,\n history: string[],\n verifyFn: (password: string, hash: string) => Promise<boolean>,\n ): Promise<ValidationResult> {\n return {\n valid: true,\n errors: [],\n };\n }\n\n async isInHistory(\n password: string,\n history: string[],\n verifyFn: (password: string, hash: string) => Promise<boolean>,\n ): Promise<boolean> {\n for (const hash of history) {\n if (await verifyFn(password, hash)) {\n return true;\n }\n }\n return false;\n }\n\n generatePassword(length: number = 16): string {\n const uppercase = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n const lowercase = \"abcdefghijklmnopqrstuvwxyz\";\n const numbers = \"0123456789\";\n const special = \"!@#$%^&*()_+-=[]{}|;:,.<>?\";\n\n let password = \"\";\n\n password += uppercase[Math.floor(Math.random() * uppercase.length)];\n password += lowercase[Math.floor(Math.random() * lowercase.length)];\n password += numbers[Math.floor(Math.random() * numbers.length)];\n password += special[Math.floor(Math.random() * special.length)];\n\n const allChars = uppercase + lowercase + numbers + special;\n for (let i = password.length; i < length; i++) {\n password += allChars[Math.floor(Math.random() * allChars.length)];\n }\n\n return password\n .split(\"\")\n .sort(() => Math.random() - 0.5)\n .join(\"\");\n }\n\n getStrength(password: string): {\n score: number;\n label: string;\n feedback: string[];\n } {\n let score = 0;\n const feedback: string[] = [];\n\n if (password.length >= 8) score += 1;\n if (password.length >= 12) score += 1;\n if (password.length >= 16) score += 1;\n\n if (/[a-z]/.test(password)) score += 1;\n if (/[A-Z]/.test(password)) score += 1;\n if (/[0-9]/.test(password)) score += 1;\n if (/[!@#$%^&*()_+\\-=\\[\\]{}|;:,.<>?]/.test(password)) score += 1;\n\n if (password.length > 8) score += 1;\n if (password.length > 12) score += 1;\n\n const uniqueChars = new Set(password).size;\n if (uniqueChars > 6) score += 1;\n if (uniqueChars > 10) score += 1;\n\n let label: string;\n if (score <= 3) {\n label = \"Weak\";\n feedback.push(\"Add more characters\");\n feedback.push(\"Include uppercase and lowercase letters\");\n } else if (score <= 5) {\n label = \"Fair\";\n feedback.push(\"Add special characters\");\n feedback.push(\"Consider making it longer\");\n } else if (score <= 7) {\n label = \"Good\";\n feedback.push(\"Consider making it longer for extra security\");\n } else {\n label = \"Strong\";\n }\n\n return { score, label, feedback };\n }\n\n setConfig(config: Partial<PasswordPolicyConfig>): void {\n this.config = { ...this.config, ...config };\n }\n\n getConfig(): PasswordPolicyConfig {\n return { ...this.config };\n }\n}\n"]}
@@ -0,0 +1,99 @@
1
+ 'use strict';
2
+
3
+ var chunkROJHKAQ4_cjs = require('./chunk-ROJHKAQ4.cjs');
4
+ var chunkRAMGUDJN_cjs = require('./chunk-RAMGUDJN.cjs');
5
+ var chunkIDVRRRAK_cjs = require('./chunk-IDVRRRAK.cjs');
6
+ var chunkCOIASRDK_cjs = require('./chunk-COIASRDK.cjs');
7
+ var chunkC36TMDTY_cjs = require('./chunk-C36TMDTY.cjs');
8
+ var chunkV2TVSCV5_cjs = require('./chunk-V2TVSCV5.cjs');
9
+ var chunkGXFOGU7N_cjs = require('./chunk-GXFOGU7N.cjs');
10
+ var projectConfig = require('kyro:config');
11
+
12
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
13
+
14
+ var projectConfig__default = /*#__PURE__*/_interopDefault(projectConfig);
15
+
16
+ exports.kyroInstance = null;
17
+ var initPromise = null;
18
+ async function doInit() {
19
+ if (exports.kyroInstance) return;
20
+ try {
21
+ const config = projectConfig__default.default.default || projectConfig__default.default;
22
+ exports.kyroInstance = chunkROJHKAQ4_cjs.createKyro(config);
23
+ await exports.kyroInstance.init();
24
+ await exports.kyroInstance.loadSettings();
25
+ const db = exports.kyroInstance.db;
26
+ let bootstrapAuthAdapter = void 0;
27
+ if (db instanceof chunkCOIASRDK_cjs.DrizzleAdapter) {
28
+ if (db.dialect === "postgres") {
29
+ bootstrapAuthAdapter = new chunkC36TMDTY_cjs.PostgresAuthAdapter({ db: db.client });
30
+ } else if (db.dialect === "sqlite") {
31
+ const authDbPath = process.env.KYRO_AUTH_DB_PATH || "./data/auth.db";
32
+ bootstrapAuthAdapter = new chunkIDVRRRAK_cjs.SQLiteAuthAdapter({ path: authDbPath });
33
+ }
34
+ } else if (db instanceof chunkROJHKAQ4_cjs.LocalAdapter) {
35
+ const authDbPath = process.env.KYRO_AUTH_DB_PATH || "./data/auth.db";
36
+ bootstrapAuthAdapter = new chunkIDVRRRAK_cjs.SQLiteAuthAdapter({ path: authDbPath });
37
+ } else if (db instanceof chunkV2TVSCV5_cjs.MongoDBAdapter) {
38
+ bootstrapAuthAdapter = new chunkGXFOGU7N_cjs.MongoDBAuthAdapter({ db: db.db });
39
+ }
40
+ if (bootstrapAuthAdapter?.connect) {
41
+ await bootstrapAuthAdapter.connect();
42
+ }
43
+ const result = await chunkRAMGUDJN_cjs.autoBootstrap(bootstrapAuthAdapter);
44
+ if (result?.success) {
45
+ console.log(`[Kyro] Admin user auto-created from env: ${result.user?.email}`);
46
+ }
47
+ if (typeof exports.kyroInstance.startWebSocket === "function") {
48
+ exports.kyroInstance.startWebSocket().catch((err) => {
49
+ console.error("[Kyro] WebSocket auto-start failed:", err);
50
+ });
51
+ }
52
+ globalThis.__KYRO_INSTANCE__ = exports.kyroInstance;
53
+ console.log("[Kyro API] Backend initialized via Astro Integration");
54
+ } catch (err) {
55
+ exports.kyroInstance = null;
56
+ initPromise = null;
57
+ console.error("[Kyro API] Init failed, will retry:", err);
58
+ throw err;
59
+ }
60
+ }
61
+ async function warmKyroInstance() {
62
+ if (!initPromise) {
63
+ initPromise = doInit();
64
+ }
65
+ await initPromise;
66
+ }
67
+ var ALL = async (context) => {
68
+ if (!exports.kyroInstance) {
69
+ if (!initPromise) {
70
+ initPromise = doInit();
71
+ }
72
+ try {
73
+ await Promise.race([
74
+ initPromise,
75
+ new Promise(
76
+ (_, reject) => setTimeout(() => reject(new Error("Initialization timeout")), 3e4)
77
+ )
78
+ ]);
79
+ } catch {
80
+ return new Response(JSON.stringify({
81
+ error: "Service Unavailable",
82
+ message: "Kyro CMS is still starting up. Please try again in a moment."
83
+ }), {
84
+ status: 503,
85
+ headers: {
86
+ "Content-Type": "application/json",
87
+ "Retry-After": "5"
88
+ }
89
+ });
90
+ }
91
+ }
92
+ const app = exports.kyroInstance.getREST();
93
+ return app.fetch(context.request, context.locals);
94
+ };
95
+
96
+ exports.ALL = ALL;
97
+ exports.warmKyroInstance = warmKyroInstance;
98
+ //# sourceMappingURL=chunk-UERVXYVK.cjs.map
99
+ //# sourceMappingURL=chunk-UERVXYVK.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/api-handler.ts"],"names":["kyroInstance","projectConfig","createKyro","DrizzleAdapter","PostgresAuthAdapter","SQLiteAuthAdapter","LocalAdapter","MongoDBAdapter","MongoDBAuthAdapter","autoBootstrap"],"mappings":"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","file":"chunk-UERVXYVK.cjs","sourcesContent":["import type { APIRoute } from \"astro\";\nimport { createKyro } from \"./createKyro.js\";\nimport { autoBootstrap } from \"./auth/bootstrap.js\";\nimport { DrizzleAdapter } from \"./database/drizzle/adapter.js\";\nimport { PostgresAuthAdapter } from \"./database/drizzle/postgres-auth-adapter.js\";\nimport { LocalAdapter } from \"./database/local/adapter.js\";\nimport { SQLiteAuthAdapter } from \"./auth/sqlite-adapter.js\";\nimport { MongoDBAdapter } from \"./database/mongodb/adapter.js\";\nimport { MongoDBAuthAdapter } from \"./database/mongodb/mongo-auth-adapter.js\";\n// @ts-ignore - handled by vite alias\nimport projectConfig from \"kyro:config\";\n\nexport let kyroInstance: any = null;\nlet initPromise: Promise<void> | null = null;\n\nasync function doInit(): Promise<void> {\n if (kyroInstance) return;\n\n try {\n const config = projectConfig.default || projectConfig;\n kyroInstance = createKyro(config);\n await kyroInstance.init();\n await kyroInstance.loadSettings();\n\n const db = kyroInstance.db;\n let bootstrapAuthAdapter: any = undefined;\n \n if (db instanceof DrizzleAdapter) {\n if (db.dialect === \"postgres\") {\n bootstrapAuthAdapter = new PostgresAuthAdapter({ db: db.client });\n } else if (db.dialect === \"sqlite\") {\n const authDbPath = process.env.KYRO_AUTH_DB_PATH || \"./data/auth.db\";\n bootstrapAuthAdapter = new SQLiteAuthAdapter({ path: authDbPath });\n }\n } else if (db instanceof LocalAdapter) {\n const authDbPath = process.env.KYRO_AUTH_DB_PATH || \"./data/auth.db\";\n bootstrapAuthAdapter = new SQLiteAuthAdapter({ path: authDbPath });\n } else if (db instanceof MongoDBAdapter) {\n bootstrapAuthAdapter = new MongoDBAuthAdapter({ db: db.db });\n }\n\n if (bootstrapAuthAdapter?.connect) {\n await bootstrapAuthAdapter.connect();\n }\n\n const result = await autoBootstrap(bootstrapAuthAdapter);\n if (result?.success) {\n console.log(`[Kyro] Admin user auto-created from env: ${result.user?.email}`);\n }\n\n // Auto-start WebSocket (checks settings.access.apiAccess.wsEnabled internally)\n if (typeof kyroInstance.startWebSocket === \"function\") {\n kyroInstance.startWebSocket().catch((err: any) => {\n console.error(\"[Kyro] WebSocket auto-start failed:\", err);\n });\n }\n\n // Expose instance globally so admin SSR can read DB directly\n (globalThis as any).__KYRO_INSTANCE__ = kyroInstance;\n\n console.log(\"[Kyro API] Backend initialized via Astro Integration\");\n } catch (err) {\n kyroInstance = null;\n initPromise = null;\n console.error(\"[Kyro API] Init failed, will retry:\", err);\n throw err;\n }\n}\n\nexport async function warmKyroInstance(): Promise<void> {\n if (!initPromise) {\n initPromise = doInit();\n }\n await initPromise;\n}\n\nexport const ALL: APIRoute = async (context) => {\n if (!kyroInstance) {\n if (!initPromise) {\n initPromise = doInit();\n }\n\n try {\n await Promise.race([\n initPromise,\n new Promise<void>((_, reject) =>\n setTimeout(() => reject(new Error(\"Initialization timeout\")), 30000)\n ),\n ]);\n } catch {\n return new Response(JSON.stringify({\n error: \"Service Unavailable\",\n message: \"Kyro CMS is still starting up. Please try again in a moment.\",\n }), {\n status: 503,\n headers: {\n \"Content-Type\": \"application/json\",\n \"Retry-After\": \"5\",\n },\n });\n }\n }\n\n const app = kyroInstance.getREST();\n return app.fetch(context.request, context.locals);\n};\n"]}