@kyro-cms/core 0.10.3 → 0.10.5

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 (301) hide show
  1. package/dist/api-handler-graphql.cjs +1 -49
  2. package/dist/api-handler-graphql.js +1 -46
  3. package/dist/api-handler-trpc.cjs +1 -38
  4. package/dist/api-handler-trpc.js +1 -36
  5. package/dist/api-handler.cjs +1 -44
  6. package/dist/api-handler.js +1 -27
  7. package/dist/bootstrap-IVQWSJXZ.js +1 -0
  8. package/dist/bootstrap-OHGQGMRV.cjs +1 -0
  9. package/dist/chunk-2BTRHVT3.cjs +20 -0
  10. package/dist/chunk-2W4FK6CJ.js +122 -0
  11. package/dist/chunk-4ORJMSJU.cjs +1 -0
  12. package/dist/chunk-5J6HXUF6.js +1 -0
  13. package/dist/chunk-65G73T7Z.cjs +2 -0
  14. package/dist/chunk-6CLRVJPP.cjs +133 -0
  15. package/dist/chunk-7N6NKCRT.js +1 -0
  16. package/dist/chunk-7WOX27LK.js +259 -0
  17. package/dist/chunk-AE6GXUT7.js +1 -0
  18. package/dist/chunk-AHSFSERC.cjs +1 -0
  19. package/dist/chunk-AJAZ7D3W.cjs +259 -0
  20. package/dist/chunk-ATLSIYRH.cjs +1 -0
  21. package/dist/chunk-AU6IWTBO.js +2 -0
  22. package/dist/chunk-CIE3XMLH.cjs +2 -0
  23. package/dist/chunk-CVVW4LXZ.cjs +1 -0
  24. package/dist/chunk-DV4LFLPL.cjs +1 -0
  25. package/dist/chunk-ELICKLFM.cjs +3 -0
  26. package/dist/chunk-EQUQJBPP.cjs +2 -0
  27. package/dist/chunk-ET6NN2V2.cjs +122 -0
  28. package/dist/chunk-F3Z67QWS.cjs +86 -0
  29. package/dist/chunk-F7SR5IDT.cjs +1 -0
  30. package/dist/chunk-FO3HLBC7.js +1 -0
  31. package/dist/chunk-G6A7OSIG.js +2 -0
  32. package/dist/chunk-GFU7AOI3.cjs +1 -0
  33. package/dist/chunk-GYQMNXXW.cjs +114 -0
  34. package/dist/chunk-HLSB2MCK.js +1 -0
  35. package/dist/chunk-HVXO3OFB.cjs +1 -0
  36. package/dist/chunk-ISWMETHJ.cjs +1 -0
  37. package/dist/chunk-K6WUOU6P.js +1 -0
  38. package/dist/chunk-KDNYHLD2.js +1 -0
  39. package/dist/chunk-L6CZYN3L.cjs +20 -0
  40. package/dist/chunk-LZ6YFYQM.js +20 -0
  41. package/dist/chunk-MIOMMB23.cjs +1 -0
  42. package/dist/chunk-MSSRVZH6.js +1 -0
  43. package/dist/chunk-NGBJKZMT.js +90 -0
  44. package/dist/chunk-NRLIGDYF.js +1 -0
  45. package/dist/chunk-NY47CFVP.cjs +1 -0
  46. package/dist/chunk-NZ35PV5R.js +2 -0
  47. package/dist/chunk-OG7CNQGU.js +1 -0
  48. package/dist/chunk-P7CESLDJ.js +1 -0
  49. package/dist/chunk-POWTSLKC.js +21 -0
  50. package/dist/chunk-PP5S2UBV.js +0 -0
  51. package/dist/chunk-PWGS2GPI.js +86 -0
  52. package/dist/chunk-Q3Q7BJVQ.cjs +1 -0
  53. package/dist/chunk-Q4CSLXCO.cjs +90 -0
  54. package/dist/chunk-QRXDCV6K.js +0 -0
  55. package/dist/chunk-R6UUTH3T.js +2 -0
  56. package/dist/chunk-RHCWCG3O.js +114 -0
  57. package/dist/chunk-SL3LZQCF.js +1 -0
  58. package/dist/chunk-TD6RULJU.cjs +21 -0
  59. package/dist/chunk-UBHFUFD4.cjs +1 -0
  60. package/dist/chunk-UBRYJP2G.js +1 -0
  61. package/dist/chunk-UDSJGML2.cjs +2 -0
  62. package/dist/chunk-UHFDH3PG.js +20 -0
  63. package/dist/chunk-UJNSOOYZ.cjs +1 -0
  64. package/dist/chunk-UVTS2IWM.js +1 -0
  65. package/dist/chunk-V65NPSR5.cjs +1 -0
  66. package/dist/chunk-VKXQUYYV.js +133 -0
  67. package/dist/chunk-WIZ6C5QZ.cjs +1 -0
  68. package/dist/chunk-Y7K26TBA.cjs +1 -0
  69. package/dist/chunk-ZAQOSRP6.js +1 -0
  70. package/dist/chunk-ZELCS7IC.js +3 -0
  71. package/dist/cli/index.cjs +35 -405
  72. package/dist/cli/index.js +35 -402
  73. package/dist/client.cjs +1 -55
  74. package/dist/client.js +1 -6
  75. package/dist/drizzle/index.cjs +1 -50
  76. package/dist/drizzle/index.d.cts +1 -2
  77. package/dist/drizzle/index.d.ts +1 -2
  78. package/dist/drizzle/index.js +1 -9
  79. package/dist/fields/index.cjs +1 -89
  80. package/dist/fields/index.js +1 -4
  81. package/dist/graphql/index.cjs +1 -31
  82. package/dist/graphql/index.d.cts +1 -1
  83. package/dist/graphql/index.d.ts +1 -1
  84. package/dist/graphql/index.js +1 -6
  85. package/dist/{index-jLs0zlft.d.ts → index-DXr33e0x.d.ts} +1 -1
  86. package/dist/{index-DHbywDs-.d.cts → index-DuuUzWBq.d.cts} +1 -1
  87. package/dist/index.cjs +29 -2464
  88. package/dist/index.d.cts +2 -2
  89. package/dist/index.d.ts +2 -2
  90. package/dist/index.js +29 -1929
  91. package/dist/integration.cjs +1 -10
  92. package/dist/integration.js +1 -4
  93. package/dist/media-L5XDD47D.js +1 -0
  94. package/dist/media-OUBQTIQP.cjs +1 -0
  95. package/dist/mongo-auth-adapter-LG5O4LIH.js +1 -0
  96. package/dist/mongo-auth-adapter-YPONSOCY.cjs +1 -0
  97. package/dist/mongodb/index.cjs +1 -29
  98. package/dist/mongodb/index.d.cts +1 -2
  99. package/dist/mongodb/index.d.ts +1 -2
  100. package/dist/mongodb/index.js +1 -8
  101. package/dist/postgres-auth-adapter-33QOIRXT.js +1 -0
  102. package/dist/postgres-auth-adapter-JKDYYULH.cjs +1 -0
  103. package/dist/redis-adapter-KECGVSVX.cjs +1 -0
  104. package/dist/redis-adapter-VAXP43GR.js +1 -0
  105. package/dist/rest/index.cjs +1 -31
  106. package/dist/rest/index.d.cts +1 -1
  107. package/dist/rest/index.d.ts +1 -1
  108. package/dist/rest/index.js +1 -18
  109. package/dist/schema-HIUSHSUI.cjs +1 -0
  110. package/dist/schema-KFYUM674.js +1 -0
  111. package/dist/sqlite-adapter-FP45QCYK.js +1 -0
  112. package/dist/sqlite-adapter-Z3IBBI4X.cjs +1 -0
  113. package/dist/templates/index.cjs +1 -207
  114. package/dist/templates/index.js +1 -6
  115. package/dist/trpc/index.cjs +1 -48
  116. package/dist/trpc/index.js +1 -7
  117. package/dist/ws/index.cjs +1 -25
  118. package/dist/ws/index.js +1 -4
  119. package/package.json +49 -12
  120. package/dist/api-handler-graphql.cjs.map +0 -1
  121. package/dist/api-handler-graphql.js.map +0 -1
  122. package/dist/api-handler-trpc.cjs.map +0 -1
  123. package/dist/api-handler-trpc.js.map +0 -1
  124. package/dist/api-handler.cjs.map +0 -1
  125. package/dist/api-handler.js.map +0 -1
  126. package/dist/bootstrap-FUAPY2OF.cjs +0 -32
  127. package/dist/bootstrap-FUAPY2OF.cjs.map +0 -1
  128. package/dist/bootstrap-OXNVM7FP.js +0 -7
  129. package/dist/bootstrap-OXNVM7FP.js.map +0 -1
  130. package/dist/chunk-2HFJUUFZ.js +0 -250
  131. package/dist/chunk-2HFJUUFZ.js.map +0 -1
  132. package/dist/chunk-354ISGA4.js +0 -6457
  133. package/dist/chunk-354ISGA4.js.map +0 -1
  134. package/dist/chunk-3AKCVYDB.js +0 -162
  135. package/dist/chunk-3AKCVYDB.js.map +0 -1
  136. package/dist/chunk-3KTWGODI.cjs +0 -178
  137. package/dist/chunk-3KTWGODI.cjs.map +0 -1
  138. package/dist/chunk-3P5AHK2U.cjs +0 -2749
  139. package/dist/chunk-3P5AHK2U.cjs.map +0 -1
  140. package/dist/chunk-3YELQL7Z.cjs +0 -4
  141. package/dist/chunk-3YELQL7Z.cjs.map +0 -1
  142. package/dist/chunk-4CV4JOE5.js +0 -24
  143. package/dist/chunk-4CV4JOE5.js.map +0 -1
  144. package/dist/chunk-4OCMVGEY.cjs +0 -173
  145. package/dist/chunk-4OCMVGEY.cjs.map +0 -1
  146. package/dist/chunk-4PWRCMTQ.cjs +0 -15
  147. package/dist/chunk-4PWRCMTQ.cjs.map +0 -1
  148. package/dist/chunk-526M5MOA.js +0 -103
  149. package/dist/chunk-526M5MOA.js.map +0 -1
  150. package/dist/chunk-53NYVYVX.js +0 -3243
  151. package/dist/chunk-53NYVYVX.js.map +0 -1
  152. package/dist/chunk-5GFQPHGT.cjs +0 -156
  153. package/dist/chunk-5GFQPHGT.cjs.map +0 -1
  154. package/dist/chunk-5RPRLTTN.js +0 -861
  155. package/dist/chunk-5RPRLTTN.js.map +0 -1
  156. package/dist/chunk-7OGPN7MP.js +0 -352
  157. package/dist/chunk-7OGPN7MP.js.map +0 -1
  158. package/dist/chunk-7OS7TX2Q.cjs +0 -495
  159. package/dist/chunk-7OS7TX2Q.cjs.map +0 -1
  160. package/dist/chunk-ADLJSJSN.cjs +0 -13
  161. package/dist/chunk-ADLJSJSN.cjs.map +0 -1
  162. package/dist/chunk-AN2L2CJZ.js +0 -2728
  163. package/dist/chunk-AN2L2CJZ.js.map +0 -1
  164. package/dist/chunk-BYBMTIMT.js +0 -419
  165. package/dist/chunk-BYBMTIMT.js.map +0 -1
  166. package/dist/chunk-CF7OL6HR.js +0 -355
  167. package/dist/chunk-CF7OL6HR.js.map +0 -1
  168. package/dist/chunk-CJX74IYK.js +0 -489
  169. package/dist/chunk-CJX74IYK.js.map +0 -1
  170. package/dist/chunk-CKVOU6MX.cjs +0 -52
  171. package/dist/chunk-CKVOU6MX.cjs.map +0 -1
  172. package/dist/chunk-CZLDE2OZ.cjs +0 -28
  173. package/dist/chunk-CZLDE2OZ.cjs.map +0 -1
  174. package/dist/chunk-DPA3KWPY.cjs +0 -205
  175. package/dist/chunk-DPA3KWPY.cjs.map +0 -1
  176. package/dist/chunk-EEJUFDMF.cjs +0 -424
  177. package/dist/chunk-EEJUFDMF.cjs.map +0 -1
  178. package/dist/chunk-FIAMXNTH.js +0 -220
  179. package/dist/chunk-FIAMXNTH.js.map +0 -1
  180. package/dist/chunk-GAOXD3XT.js +0 -175
  181. package/dist/chunk-GAOXD3XT.js.map +0 -1
  182. package/dist/chunk-GTGRLD4Y.js +0 -3
  183. package/dist/chunk-GTGRLD4Y.js.map +0 -1
  184. package/dist/chunk-GUUB5EAG.cjs +0 -223
  185. package/dist/chunk-GUUB5EAG.cjs.map +0 -1
  186. package/dist/chunk-GXFOGU7N.cjs +0 -359
  187. package/dist/chunk-GXFOGU7N.cjs.map +0 -1
  188. package/dist/chunk-GYIJ3JJM.cjs +0 -1069
  189. package/dist/chunk-GYIJ3JJM.cjs.map +0 -1
  190. package/dist/chunk-GZS4LMR7.js +0 -422
  191. package/dist/chunk-GZS4LMR7.js.map +0 -1
  192. package/dist/chunk-HY6B7B5A.js +0 -150
  193. package/dist/chunk-HY6B7B5A.js.map +0 -1
  194. package/dist/chunk-IDVRRRAK.cjs +0 -824
  195. package/dist/chunk-IDVRRRAK.cjs.map +0 -1
  196. package/dist/chunk-ISKYUUP4.cjs +0 -6486
  197. package/dist/chunk-ISKYUUP4.cjs.map +0 -1
  198. package/dist/chunk-KC2GDBLS.cjs +0 -84
  199. package/dist/chunk-KC2GDBLS.cjs.map +0 -1
  200. package/dist/chunk-L4EZKIEX.js +0 -185
  201. package/dist/chunk-L4EZKIEX.js.map +0 -1
  202. package/dist/chunk-LNTFRAHF.cjs +0 -473
  203. package/dist/chunk-LNTFRAHF.cjs.map +0 -1
  204. package/dist/chunk-MTIRYI7F.cjs +0 -4
  205. package/dist/chunk-MTIRYI7F.cjs.map +0 -1
  206. package/dist/chunk-N4GN6Q3V.cjs +0 -869
  207. package/dist/chunk-N4GN6Q3V.cjs.map +0 -1
  208. package/dist/chunk-N4H37VN4.cjs +0 -259
  209. package/dist/chunk-N4H37VN4.cjs.map +0 -1
  210. package/dist/chunk-N5QSHUA6.js +0 -1135
  211. package/dist/chunk-N5QSHUA6.js.map +0 -1
  212. package/dist/chunk-NKPKR5BW.cjs +0 -188
  213. package/dist/chunk-NKPKR5BW.cjs.map +0 -1
  214. package/dist/chunk-NQJJYRLP.cjs +0 -110
  215. package/dist/chunk-NQJJYRLP.cjs.map +0 -1
  216. package/dist/chunk-OJ2AM75W.cjs +0 -253
  217. package/dist/chunk-OJ2AM75W.cjs.map +0 -1
  218. package/dist/chunk-OX6GOIPH.js +0 -516
  219. package/dist/chunk-OX6GOIPH.js.map +0 -1
  220. package/dist/chunk-P2YW545G.js +0 -11
  221. package/dist/chunk-P2YW545G.js.map +0 -1
  222. package/dist/chunk-PHJRNPHY.cjs +0 -3291
  223. package/dist/chunk-PHJRNPHY.cjs.map +0 -1
  224. package/dist/chunk-Q72BOAPK.js +0 -817
  225. package/dist/chunk-Q72BOAPK.js.map +0 -1
  226. package/dist/chunk-QU2RFFH4.js +0 -3
  227. package/dist/chunk-QU2RFFH4.js.map +0 -1
  228. package/dist/chunk-RP7VZUEL.js +0 -49
  229. package/dist/chunk-RP7VZUEL.js.map +0 -1
  230. package/dist/chunk-SHTTJMLT.cjs +0 -361
  231. package/dist/chunk-SHTTJMLT.cjs.map +0 -1
  232. package/dist/chunk-THBQG64D.cjs +0 -425
  233. package/dist/chunk-THBQG64D.cjs.map +0 -1
  234. package/dist/chunk-TQG7G7YI.cjs +0 -526
  235. package/dist/chunk-TQG7G7YI.cjs.map +0 -1
  236. package/dist/chunk-U3VVLYXG.cjs +0 -189
  237. package/dist/chunk-U3VVLYXG.cjs.map +0 -1
  238. package/dist/chunk-UUDTPZX6.js +0 -193
  239. package/dist/chunk-UUDTPZX6.js.map +0 -1
  240. package/dist/chunk-VKREAIBA.cjs +0 -1139
  241. package/dist/chunk-VKREAIBA.cjs.map +0 -1
  242. package/dist/chunk-WDTTHKDS.js +0 -458
  243. package/dist/chunk-WDTTHKDS.js.map +0 -1
  244. package/dist/chunk-WXVB364T.js +0 -218
  245. package/dist/chunk-WXVB364T.js.map +0 -1
  246. package/dist/chunk-X4BPPD6K.js +0 -181
  247. package/dist/chunk-X4BPPD6K.js.map +0 -1
  248. package/dist/chunk-XEB7PH2E.js +0 -81
  249. package/dist/chunk-XEB7PH2E.js.map +0 -1
  250. package/dist/chunk-XHAAAEXX.js +0 -1055
  251. package/dist/chunk-XHAAAEXX.js.map +0 -1
  252. package/dist/chunk-YT7HXXVN.js +0 -13
  253. package/dist/chunk-YT7HXXVN.js.map +0 -1
  254. package/dist/cli/index.cjs.map +0 -1
  255. package/dist/cli/index.js.map +0 -1
  256. package/dist/client.cjs.map +0 -1
  257. package/dist/client.js.map +0 -1
  258. package/dist/drizzle/index.cjs.map +0 -1
  259. package/dist/drizzle/index.js.map +0 -1
  260. package/dist/fields/index.cjs.map +0 -1
  261. package/dist/fields/index.js.map +0 -1
  262. package/dist/graphql/index.cjs.map +0 -1
  263. package/dist/graphql/index.js.map +0 -1
  264. package/dist/index.cjs.map +0 -1
  265. package/dist/index.js.map +0 -1
  266. package/dist/integration.cjs.map +0 -1
  267. package/dist/integration.js.map +0 -1
  268. package/dist/media-7WDX4BDJ.js +0 -4
  269. package/dist/media-7WDX4BDJ.js.map +0 -1
  270. package/dist/media-TUSLVRQ6.cjs +0 -17
  271. package/dist/media-TUSLVRQ6.cjs.map +0 -1
  272. package/dist/mongo-auth-adapter-GT4S7SCU.cjs +0 -17
  273. package/dist/mongo-auth-adapter-GT4S7SCU.cjs.map +0 -1
  274. package/dist/mongo-auth-adapter-M7VV4LNB.js +0 -4
  275. package/dist/mongo-auth-adapter-M7VV4LNB.js.map +0 -1
  276. package/dist/mongodb/index.cjs.map +0 -1
  277. package/dist/mongodb/index.js.map +0 -1
  278. package/dist/postgres-auth-adapter-AFAPISH7.js +0 -5
  279. package/dist/postgres-auth-adapter-AFAPISH7.js.map +0 -1
  280. package/dist/postgres-auth-adapter-SFDTLONT.cjs +0 -14
  281. package/dist/postgres-auth-adapter-SFDTLONT.cjs.map +0 -1
  282. package/dist/redis-adapter-UQX4EE3B.cjs +0 -13
  283. package/dist/redis-adapter-UQX4EE3B.cjs.map +0 -1
  284. package/dist/redis-adapter-XALOGWY3.js +0 -4
  285. package/dist/redis-adapter-XALOGWY3.js.map +0 -1
  286. package/dist/rest/index.cjs.map +0 -1
  287. package/dist/rest/index.js.map +0 -1
  288. package/dist/schema-6QL3USNB.cjs +0 -67
  289. package/dist/schema-6QL3USNB.cjs.map +0 -1
  290. package/dist/schema-FNNWEAAW.js +0 -6
  291. package/dist/schema-FNNWEAAW.js.map +0 -1
  292. package/dist/sqlite-adapter-AQB5TCGV.cjs +0 -13
  293. package/dist/sqlite-adapter-AQB5TCGV.cjs.map +0 -1
  294. package/dist/sqlite-adapter-N5H6IM2X.js +0 -4
  295. package/dist/sqlite-adapter-N5H6IM2X.js.map +0 -1
  296. package/dist/templates/index.cjs.map +0 -1
  297. package/dist/templates/index.js.map +0 -1
  298. package/dist/trpc/index.cjs.map +0 -1
  299. package/dist/trpc/index.js.map +0 -1
  300. package/dist/ws/index.cjs.map +0 -1
  301. package/dist/ws/index.js.map +0 -1
@@ -1,817 +0,0 @@
1
- import bcrypt from 'bcryptjs';
2
- import { randomBytes } from 'crypto';
3
- import { mkdirSync } from 'fs';
4
- import { dirname } from 'path';
5
- import { createRequire } from 'module';
6
-
7
- // src/auth/sqlite-adapter.ts
8
- var _require = createRequire(import.meta.url);
9
- var modPath = "node:sqlite";
10
- var { DatabaseSync } = _require(modPath);
11
- var DEFAULT_BUSY_TIMEOUT = 5e3;
12
- var DEFAULT_WAL_CHECKPOINT = 1e3;
13
- var DEFAULT_CACHE_SIZE = -64e3;
14
- var DEFAULT_MMAP_SIZE = 268435456;
15
- var SQLiteAuthAdapter = class {
16
- db = null;
17
- path;
18
- saltRounds;
19
- externalDb;
20
- busyTimeout;
21
- walAutoCheckpoint;
22
- cacheSize;
23
- mmapSize;
24
- preparedStatements = /* @__PURE__ */ new Map();
25
- constructor(options = {}) {
26
- this.path = options.path || "./data/auth.db";
27
- this.saltRounds = options.saltRounds || 12;
28
- this.externalDb = !!options.db;
29
- this.busyTimeout = options.busyTimeout ?? DEFAULT_BUSY_TIMEOUT;
30
- this.walAutoCheckpoint = options.walAutoCheckpoint ?? DEFAULT_WAL_CHECKPOINT;
31
- this.cacheSize = options.cacheSize ?? DEFAULT_CACHE_SIZE;
32
- this.mmapSize = options.mmapSize ?? DEFAULT_MMAP_SIZE;
33
- if (options.db) {
34
- this.db = options.db;
35
- }
36
- }
37
- async connect() {
38
- if (this.db) return;
39
- const dir = dirname(this.path);
40
- if (dir && dir !== ".") {
41
- mkdirSync(dir, { recursive: true });
42
- }
43
- this.db = new DatabaseSync(this.path);
44
- this.db.exec(`PRAGMA busy_timeout = ${this.busyTimeout}`);
45
- this.db.exec("PRAGMA journal_mode = WAL");
46
- this.db.exec("PRAGMA synchronous = NORMAL");
47
- this.db.exec("PRAGMA cache_size = " + this.cacheSize);
48
- this.db.exec("PRAGMA mmap_size = " + this.mmapSize);
49
- this.db.exec("PRAGMA wal_autocheckpoint = " + this.walAutoCheckpoint);
50
- this.db.exec("PRAGMA foreign_keys = ON");
51
- this.db.exec("PRAGMA temp_store = MEMORY");
52
- this.ensureTables();
53
- this.prepareStatements();
54
- }
55
- async disconnect() {
56
- if (this.db && !this.externalDb) {
57
- this.db.exec("PRAGMA wal_checkpoint(TRUNCATE)");
58
- this.db.close();
59
- this.db = null;
60
- this.preparedStatements.clear();
61
- }
62
- }
63
- async ensureConnected() {
64
- if (!this.db) {
65
- await this.connect();
66
- }
67
- if (!this.db) {
68
- throw new Error("Failed to connect to SQLite database");
69
- }
70
- return this.db;
71
- }
72
- ensureTables() {
73
- if (!this.db) return;
74
- this.db.exec(`
75
- CREATE TABLE IF NOT EXISTS kyro_users (
76
- id TEXT PRIMARY KEY,
77
- name TEXT,
78
- email TEXT UNIQUE NOT NULL,
79
- password_hash TEXT NOT NULL,
80
- role TEXT NOT NULL DEFAULT 'customer',
81
- tenant_id TEXT,
82
- email_verified INTEGER DEFAULT 0,
83
- locked INTEGER DEFAULT 0,
84
- last_login TEXT,
85
- failed_login_attempts INTEGER DEFAULT 0,
86
- locked_until TEXT,
87
- avatar TEXT,
88
- created_at TEXT NOT NULL,
89
- updated_at TEXT NOT NULL
90
- );
91
-
92
- CREATE TABLE IF NOT EXISTS kyro_sessions (
93
- id TEXT PRIMARY KEY,
94
- user_id TEXT NOT NULL,
95
- token TEXT NOT NULL,
96
- refresh_token TEXT,
97
- expires_at TEXT NOT NULL,
98
- created_at TEXT NOT NULL,
99
- ip_address TEXT,
100
- user_agent TEXT,
101
- FOREIGN KEY (user_id) REFERENCES kyro_users(id) ON DELETE CASCADE
102
- );
103
-
104
- CREATE TABLE IF NOT EXISTS kyro_password_history (
105
- id INTEGER PRIMARY KEY AUTOINCREMENT,
106
- user_id TEXT NOT NULL,
107
- password_hash TEXT NOT NULL,
108
- created_at TEXT NOT NULL,
109
- FOREIGN KEY (user_id) REFERENCES kyro_users(id) ON DELETE CASCADE
110
- );
111
-
112
- CREATE TABLE IF NOT EXISTS kyro_rate_limits (
113
- id INTEGER PRIMARY KEY AUTOINCREMENT,
114
- key TEXT NOT NULL,
115
- window_start INTEGER NOT NULL,
116
- count INTEGER NOT NULL DEFAULT 1,
117
- UNIQUE(key, window_start)
118
- );
119
-
120
- CREATE TABLE IF NOT EXISTS kyro_lockouts (
121
- user_id TEXT PRIMARY KEY,
122
- attempts INTEGER NOT NULL DEFAULT 0,
123
- last_attempt INTEGER,
124
- locked_at INTEGER,
125
- locked_until INTEGER
126
- );
127
-
128
- CREATE TABLE IF NOT EXISTS kyro_audit_logs (
129
- id TEXT PRIMARY KEY,
130
- timestamp TEXT NOT NULL,
131
- action TEXT NOT NULL,
132
- user_id TEXT,
133
- user_email TEXT,
134
- role TEXT,
135
- resource TEXT NOT NULL,
136
- resource_id TEXT,
137
- ip_address TEXT,
138
- user_agent TEXT,
139
- success INTEGER NOT NULL,
140
- error TEXT,
141
- metadata TEXT,
142
- created_at TEXT NOT NULL DEFAULT (datetime('now'))
143
- );
144
-
145
- CREATE INDEX IF NOT EXISTS idx_kyro_users_email ON kyro_users(email);
146
- CREATE INDEX IF NOT EXISTS idx_kyro_sessions_user_id ON kyro_sessions(user_id);
147
- CREATE INDEX IF NOT EXISTS idx_kyro_sessions_token ON kyro_sessions(token);
148
- CREATE INDEX IF NOT EXISTS idx_kyro_sessions_refresh_token ON kyro_sessions(refresh_token);
149
- CREATE INDEX IF NOT EXISTS idx_kyro_sessions_expires ON kyro_sessions(expires_at);
150
- CREATE INDEX IF NOT EXISTS idx_kyro_password_history_user_id ON kyro_password_history(user_id);
151
- CREATE INDEX IF NOT EXISTS idx_kyro_rate_limits_key ON kyro_rate_limits(key);
152
- CREATE INDEX IF NOT EXISTS idx_kyro_rate_limits_window ON kyro_rate_limits(window_start);
153
- CREATE INDEX IF NOT EXISTS idx_kyro_lockouts_locked_until ON kyro_lockouts(locked_until);
154
- CREATE INDEX IF NOT EXISTS idx_kyro_audit_logs_timestamp ON kyro_audit_logs(timestamp);
155
- CREATE INDEX IF NOT EXISTS idx_kyro_audit_logs_action ON kyro_audit_logs(action);
156
- CREATE INDEX IF NOT EXISTS idx_kyro_audit_logs_user_id ON kyro_audit_logs(user_id);
157
- CREATE INDEX IF NOT EXISTS idx_kyro_audit_logs_resource ON kyro_audit_logs(resource);
158
-
159
- CREATE TABLE IF NOT EXISTS kyro_email_verifications (
160
- id TEXT PRIMARY KEY,
161
- user_id TEXT NOT NULL,
162
- token TEXT UNIQUE NOT NULL,
163
- expires_at TEXT NOT NULL,
164
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
165
- FOREIGN KEY (user_id) REFERENCES kyro_users(id) ON DELETE CASCADE
166
- );
167
-
168
- CREATE TABLE IF NOT EXISTS kyro_password_resets (
169
- id TEXT PRIMARY KEY,
170
- user_id TEXT NOT NULL,
171
- token TEXT UNIQUE NOT NULL,
172
- expires_at TEXT NOT NULL,
173
- used_at TEXT,
174
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
175
- FOREIGN KEY (user_id) REFERENCES kyro_users(id) ON DELETE CASCADE
176
- );
177
-
178
- CREATE INDEX IF NOT EXISTS idx_kyro_email_verifications_token ON kyro_email_verifications(token);
179
- CREATE INDEX IF NOT EXISTS idx_kyro_password_resets_token ON kyro_password_resets(token);
180
- `);
181
- try {
182
- this.db.exec(`ALTER TABLE kyro_users ADD COLUMN name TEXT`);
183
- } catch {
184
- }
185
- }
186
- prepareStatements() {
187
- if (!this.db) return;
188
- this.preparedStatements.set(
189
- "findUserByEmail",
190
- this.db.prepare("SELECT * FROM kyro_users WHERE email = ?")
191
- );
192
- this.preparedStatements.set(
193
- "findUserById",
194
- this.db.prepare("SELECT * FROM kyro_users WHERE id = ?")
195
- );
196
- this.preparedStatements.set(
197
- "findSessionByToken",
198
- this.db.prepare("SELECT * FROM kyro_sessions WHERE token = ?")
199
- );
200
- this.preparedStatements.set(
201
- "findSessionByRefreshToken",
202
- this.db.prepare("SELECT * FROM kyro_sessions WHERE refresh_token = ?")
203
- );
204
- this.preparedStatements.set(
205
- "deleteSession",
206
- this.db.prepare("DELETE FROM kyro_sessions WHERE id = ? OR token = ?")
207
- );
208
- this.preparedStatements.set(
209
- "deleteUserSessions",
210
- this.db.prepare("DELETE FROM kyro_sessions WHERE user_id = ?")
211
- );
212
- this.preparedStatements.set(
213
- "countUsers",
214
- this.db.prepare("SELECT COUNT(*) as count FROM kyro_users")
215
- );
216
- this.preparedStatements.set(
217
- "deleteUser",
218
- this.db.prepare("DELETE FROM kyro_users WHERE id = ?")
219
- );
220
- this.preparedStatements.set(
221
- "findUsersPaginated",
222
- this.db.prepare(
223
- "SELECT * FROM kyro_users ORDER BY created_at DESC LIMIT ? OFFSET ?"
224
- )
225
- );
226
- this.preparedStatements.set(
227
- "findUsersWithSearch",
228
- this.db.prepare(
229
- "SELECT * FROM kyro_users WHERE email LIKE ? ORDER BY created_at DESC LIMIT ? OFFSET ?"
230
- )
231
- );
232
- this.preparedStatements.set(
233
- "countUsersWithSearch",
234
- this.db.prepare(
235
- "SELECT COUNT(*) as count FROM kyro_users WHERE email LIKE ?"
236
- )
237
- );
238
- this.preparedStatements.set(
239
- "getPasswordHistory",
240
- this.db.prepare(
241
- "SELECT password_hash FROM kyro_password_history WHERE user_id = ? ORDER BY created_at DESC LIMIT ?"
242
- )
243
- );
244
- this.preparedStatements.set(
245
- "addPasswordHistory",
246
- this.db.prepare(
247
- "INSERT INTO kyro_password_history (user_id, password_hash, created_at) VALUES (?, ?, ?)"
248
- )
249
- );
250
- this.preparedStatements.set(
251
- "trimPasswordHistory",
252
- this.db.prepare(
253
- `DELETE FROM kyro_password_history WHERE id IN (
254
- SELECT id FROM kyro_password_history WHERE user_id = ? ORDER BY created_at DESC LIMIT -1 OFFSET 5
255
- )`
256
- )
257
- );
258
- this.preparedStatements.set(
259
- "deleteExpiredSessions",
260
- this.db.prepare("DELETE FROM kyro_sessions WHERE expires_at < ?")
261
- );
262
- this.preparedStatements.set(
263
- "cleanupOldAuditLogs",
264
- this.db.prepare("DELETE FROM kyro_audit_logs WHERE timestamp < ?")
265
- );
266
- this.preparedStatements.set(
267
- "cleanupExpiredLockouts",
268
- this.db.prepare(
269
- "UPDATE kyro_lockouts SET attempts = 0, locked_at = NULL, locked_until = NULL WHERE locked_until < ?"
270
- )
271
- );
272
- this.preparedStatements.set(
273
- "getLockout",
274
- this.db.prepare("SELECT * FROM kyro_lockouts WHERE user_id = ?")
275
- );
276
- this.preparedStatements.set(
277
- "upsertLockout",
278
- this.db.prepare(`
279
- INSERT INTO kyro_lockouts (user_id, attempts, last_attempt, locked_at, locked_until)
280
- VALUES (?, ?, ?, ?, ?)
281
- ON CONFLICT(user_id) DO UPDATE SET
282
- attempts = excluded.attempts,
283
- last_attempt = excluded.last_attempt,
284
- locked_at = excluded.locked_at,
285
- locked_until = excluded.locked_until
286
- `)
287
- );
288
- this.preparedStatements.set(
289
- "resetLockout",
290
- this.db.prepare(
291
- "UPDATE kyro_lockouts SET attempts = 0, locked_at = NULL, locked_until = NULL WHERE user_id = ?"
292
- )
293
- );
294
- }
295
- stmt(name) {
296
- const stmt = this.preparedStatements.get(name);
297
- if (!stmt) throw new Error(`Prepared statement not found: ${name}`);
298
- return stmt;
299
- }
300
- async cleanupExpiredSessions() {
301
- await this.ensureConnected();
302
- const result = this.stmt("deleteExpiredSessions").run(
303
- (/* @__PURE__ */ new Date()).toISOString()
304
- );
305
- return result.changes;
306
- }
307
- async cleanupOldAuditLogs(retentionDays = 30) {
308
- await this.ensureConnected();
309
- const cutoff = new Date(
310
- Date.now() - retentionDays * 24 * 60 * 60 * 1e3
311
- ).toISOString();
312
- const result = this.stmt("cleanupOldAuditLogs").run(cutoff);
313
- return result.changes;
314
- }
315
- async getStats() {
316
- await this.ensureConnected();
317
- const userCount = this.stmt("countUsers").get().count;
318
- const activeSessionCount = this.db.prepare(
319
- "SELECT COUNT(*) as count FROM kyro_sessions WHERE expires_at > ?"
320
- ).get((/* @__PURE__ */ new Date()).toISOString()).count;
321
- const auditLogCount = this.db.prepare(
322
- "SELECT COUNT(*) as count FROM kyro_audit_logs"
323
- ).get().count;
324
- return { userCount, activeSessionCount, auditLogCount };
325
- }
326
- async createUser(data) {
327
- await this.ensureConnected();
328
- const id = randomBytes(16).toString("hex");
329
- const now = (/* @__PURE__ */ new Date()).toISOString();
330
- const passwordHash = await this.hashPassword(data.password);
331
- const user = {
332
- id,
333
- name: data.name,
334
- email: data.email.toLowerCase(),
335
- passwordHash,
336
- role: data.role || "customer",
337
- avatar: data.avatar,
338
- tenantId: data.tenantId,
339
- createdAt: now,
340
- updatedAt: now
341
- };
342
- this.db.prepare(
343
- `INSERT INTO kyro_users (id, name, email, password_hash, role, avatar, tenant_id, created_at, updated_at)
344
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`
345
- ).run(
346
- id,
347
- user.name || null,
348
- user.email,
349
- user.passwordHash,
350
- user.role,
351
- user.avatar || null,
352
- user.tenantId || null,
353
- now,
354
- now
355
- );
356
- return user;
357
- }
358
- async findUserByEmail(email) {
359
- await this.ensureConnected();
360
- const row = this.stmt("findUserByEmail").get(email.toLowerCase());
361
- if (!row) return null;
362
- return this.rowToUser(row);
363
- }
364
- async findUserById(userId) {
365
- await this.ensureConnected();
366
- const row = this.stmt("findUserById").get(userId);
367
- if (!row) return null;
368
- return this.rowToUser(row);
369
- }
370
- async updateUser(userId, data) {
371
- await this.ensureConnected();
372
- const existing = await this.findUserById(userId);
373
- if (!existing) return null;
374
- const updates = [];
375
- const values = [];
376
- if (data.email !== void 0) {
377
- updates.push("email = ?");
378
- values.push(data.email.toLowerCase());
379
- }
380
- if (data.name !== void 0) {
381
- updates.push("name = ?");
382
- values.push(data.name);
383
- }
384
- if (data.passwordHash !== void 0) {
385
- updates.push("password_hash = ?");
386
- values.push(data.passwordHash);
387
- }
388
- if (data.role !== void 0) {
389
- updates.push("role = ?");
390
- values.push(data.role);
391
- }
392
- if (data.avatar !== void 0) {
393
- updates.push("avatar = ?");
394
- values.push(data.avatar);
395
- }
396
- if (data.tenantId !== void 0) {
397
- updates.push("tenant_id = ?");
398
- values.push(data.tenantId);
399
- }
400
- if (data.emailVerified !== void 0) {
401
- updates.push("email_verified = ?");
402
- values.push(data.emailVerified ? 1 : 0);
403
- }
404
- if (data.locked !== void 0) {
405
- updates.push("locked = ?");
406
- values.push(data.locked ? 1 : 0);
407
- }
408
- if (data.lastLogin !== void 0) {
409
- updates.push("last_login = ?");
410
- values.push(data.lastLogin);
411
- }
412
- if (data.failedLoginAttempts !== void 0) {
413
- updates.push("failed_login_attempts = ?");
414
- values.push(data.failedLoginAttempts);
415
- }
416
- updates.push("updated_at = ?");
417
- values.push((/* @__PURE__ */ new Date()).toISOString());
418
- values.push(userId);
419
- this.db.prepare(
420
- `UPDATE kyro_users SET ${updates.join(", ")} WHERE id = ?`
421
- ).run(...values);
422
- return this.findUserById(userId);
423
- }
424
- async deleteUser(userId) {
425
- await this.ensureConnected();
426
- const result = this.stmt("deleteUser").run(userId);
427
- return result.changes > 0;
428
- }
429
- async hashPassword(password) {
430
- return bcrypt.hash(password, this.saltRounds);
431
- }
432
- async verifyPassword(email, password) {
433
- await this.ensureConnected();
434
- const user = await this.findUserByEmail(email);
435
- if (!user) return null;
436
- const stored = this.db.prepare(
437
- "SELECT password_hash FROM kyro_users WHERE id = ?"
438
- ).get(user.id);
439
- if (!stored?.password_hash) return null;
440
- const valid = await bcrypt.compare(password, stored.password_hash);
441
- return valid ? user : null;
442
- }
443
- async createSession(userId, data = {}) {
444
- await this.ensureConnected();
445
- const id = randomBytes(32).toString("hex");
446
- const token = randomBytes(32).toString("base64url");
447
- const refreshToken = randomBytes(32).toString("base64url");
448
- const now = /* @__PURE__ */ new Date();
449
- const expiresAt = new Date(now.getTime() + 864e5).toISOString();
450
- const session = {
451
- id,
452
- userId,
453
- token,
454
- refreshToken,
455
- expiresAt,
456
- createdAt: now.toISOString(),
457
- ipAddress: data.ipAddress,
458
- userAgent: data.userAgent
459
- };
460
- this.db.prepare(
461
- `INSERT INTO kyro_sessions (id, user_id, token, refresh_token, expires_at, created_at, ip_address, user_agent)
462
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)`
463
- ).run(
464
- session.id,
465
- session.userId,
466
- session.token,
467
- session.refreshToken ?? null,
468
- session.expiresAt,
469
- session.createdAt,
470
- session.ipAddress ?? null,
471
- session.userAgent ?? null
472
- );
473
- return session;
474
- }
475
- async findSessionByToken(token) {
476
- await this.ensureConnected();
477
- const row = this.stmt("findSessionByToken").get(token);
478
- if (!row) return null;
479
- return this.rowToSession(row);
480
- }
481
- async findSessionByRefreshToken(refreshToken) {
482
- await this.ensureConnected();
483
- const row = this.stmt("findSessionByRefreshToken").get(refreshToken);
484
- if (!row) return null;
485
- return this.rowToSession(row);
486
- }
487
- async deleteSession(sessionId) {
488
- await this.ensureConnected();
489
- const result = this.stmt("deleteSession").run(sessionId, sessionId);
490
- return result.changes > 0;
491
- }
492
- async deleteUserSessions(userId) {
493
- await this.ensureConnected();
494
- const result = this.stmt("deleteUserSessions").run(userId);
495
- return result.changes;
496
- }
497
- async hasAnyUsers() {
498
- await this.ensureConnected();
499
- const row = this.stmt("countUsers").get();
500
- return row.count > 0;
501
- }
502
- async findUsers(options = {}) {
503
- await this.ensureConnected();
504
- const page = options.page ?? 1;
505
- const limit = options.limit ?? 10;
506
- const offset = (page - 1) * limit;
507
- const search = options.search;
508
- let total;
509
- let rows;
510
- if (search) {
511
- const searchPattern = `%${search}%`;
512
- total = this.stmt("countUsersWithSearch").get(searchPattern).count;
513
- rows = this.stmt("findUsersWithSearch").all(
514
- searchPattern,
515
- limit,
516
- offset
517
- );
518
- } else {
519
- total = this.stmt("countUsers").get().count;
520
- rows = this.stmt("findUsersPaginated").all(limit, offset);
521
- }
522
- return {
523
- users: rows.map((row) => this.rowToUser(row)),
524
- total
525
- };
526
- }
527
- async addPasswordToHistory(userId, passwordHash) {
528
- await this.ensureConnected();
529
- this.stmt("addPasswordHistory").run(
530
- userId,
531
- passwordHash,
532
- (/* @__PURE__ */ new Date()).toISOString()
533
- );
534
- this.stmt("trimPasswordHistory").run(userId);
535
- }
536
- async getPasswordHistory(userId, count = 5) {
537
- await this.ensureConnected();
538
- const rows = this.stmt("getPasswordHistory").all(userId, count);
539
- return rows.map((r) => r.password_hash);
540
- }
541
- async isPasswordInHistory(password, userId, historyCount = 5) {
542
- const history = await this.getPasswordHistory(userId, historyCount);
543
- for (const hash of history) {
544
- if (await bcrypt.compare(password, hash)) {
545
- return true;
546
- }
547
- }
548
- return false;
549
- }
550
- async recordFailedAttempt(userId) {
551
- await this.ensureConnected();
552
- const now = Date.now();
553
- const lockout = this.stmt("getLockout").get(userId);
554
- const attempts = (lockout?.attempts || 0) + 1;
555
- const lockedUntil = attempts >= 5 ? now + 15 * 60 * 1e3 : lockout?.locked_until || null;
556
- this.stmt("upsertLockout").run(
557
- userId,
558
- attempts,
559
- now,
560
- lockedUntil !== null ? now : null,
561
- lockedUntil
562
- );
563
- }
564
- async resetAttempts(userId) {
565
- await this.ensureConnected();
566
- this.stmt("resetLockout").run(userId);
567
- }
568
- async checkLockout(userId) {
569
- await this.ensureConnected();
570
- this.stmt("cleanupExpiredLockouts").run(Date.now());
571
- const lockout = this.stmt("getLockout").get(userId);
572
- if (!lockout) {
573
- return {
574
- locked: false,
575
- attemptsRemaining: 5,
576
- totalAttempts: 0
577
- };
578
- }
579
- if (lockout.locked_until !== null && lockout.locked_until > Date.now()) {
580
- return {
581
- locked: true,
582
- attemptsRemaining: 0,
583
- lockedUntil: new Date(lockout.locked_until),
584
- totalAttempts: lockout.attempts
585
- };
586
- }
587
- return {
588
- locked: false,
589
- attemptsRemaining: Math.max(0, 5 - lockout.attempts),
590
- totalAttempts: lockout.attempts
591
- };
592
- }
593
- async logAudit(data) {
594
- await this.ensureConnected();
595
- const id = randomBytes(16).toString("hex");
596
- const timestamp = (/* @__PURE__ */ new Date()).toISOString();
597
- this.db.prepare(
598
- `INSERT INTO kyro_audit_logs (
599
- id, timestamp, action, user_id, user_email, role, resource, resource_id,
600
- ip_address, user_agent, success, error, metadata, created_at
601
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
602
- ).run(
603
- id,
604
- timestamp,
605
- data.action,
606
- data.userId || null,
607
- data.userEmail || null,
608
- data.role || null,
609
- data.resource,
610
- data.resourceId || null,
611
- data.ipAddress || null,
612
- data.userAgent || null,
613
- data.success ? 1 : 0,
614
- data.error || null,
615
- data.metadata ? JSON.stringify(data.metadata) : null,
616
- (/* @__PURE__ */ new Date()).toISOString()
617
- );
618
- return id;
619
- }
620
- async queryAuditLogs(options = {}) {
621
- await this.ensureConnected();
622
- const conditions = [];
623
- const params = [];
624
- if (options.action) {
625
- conditions.push("action = ?");
626
- params.push(options.action);
627
- }
628
- if (options.userId) {
629
- conditions.push("user_id = ?");
630
- params.push(options.userId);
631
- }
632
- if (options.resource) {
633
- conditions.push("resource = ?");
634
- params.push(options.resource);
635
- }
636
- if (options.success !== void 0) {
637
- conditions.push("success = ?");
638
- params.push(options.success ? 1 : 0);
639
- }
640
- if (options.startDate) {
641
- conditions.push("timestamp >= ?");
642
- params.push(options.startDate.toISOString());
643
- }
644
- if (options.endDate) {
645
- conditions.push("timestamp <= ?");
646
- params.push(options.endDate.toISOString());
647
- }
648
- const where = conditions.length > 0 ? "WHERE " + conditions.join(" AND ") : "";
649
- const limit = options.limit || 50;
650
- const offset = options.offset || 0;
651
- const totalResult = this.db.prepare(
652
- `SELECT COUNT(*) as count FROM kyro_audit_logs ${where}`
653
- ).get(...params);
654
- const rows = this.db.prepare(
655
- `SELECT * FROM kyro_audit_logs ${where} ORDER BY timestamp DESC LIMIT ? OFFSET ?`
656
- ).all(...params, limit, offset);
657
- return {
658
- total: totalResult.count,
659
- logs: rows.map((row) => ({
660
- id: row.id,
661
- timestamp: new Date(row.timestamp),
662
- action: row.action,
663
- userId: row.user_id || void 0,
664
- userEmail: row.user_email || void 0,
665
- resource: row.resource,
666
- resourceId: row.resource_id || void 0,
667
- ipAddress: row.ip_address || void 0,
668
- userAgent: row.user_agent || void 0,
669
- success: row.success === 1,
670
- error: row.error || void 0,
671
- metadata: row.metadata ? JSON.parse(row.metadata) : void 0
672
- }))
673
- };
674
- }
675
- rowToUser(row) {
676
- return {
677
- id: row.id,
678
- name: row.name || void 0,
679
- email: row.email,
680
- passwordHash: row.password_hash,
681
- role: row.role,
682
- tenantId: row.tenant_id,
683
- avatar: row.avatar,
684
- emailVerified: row.email_verified === 1,
685
- locked: row.locked === 1,
686
- lastLogin: row.last_login,
687
- failedLoginAttempts: row.failed_login_attempts || 0,
688
- createdAt: row.created_at,
689
- updatedAt: row.updated_at
690
- };
691
- }
692
- rowToSession(row) {
693
- return {
694
- id: row.id,
695
- userId: row.user_id,
696
- token: row.token,
697
- refreshToken: row.refresh_token,
698
- expiresAt: row.expires_at,
699
- createdAt: row.created_at,
700
- ipAddress: row.ip_address,
701
- userAgent: row.user_agent
702
- };
703
- }
704
- async findAuditLogs(filter) {
705
- const result = await this.queryAuditLogs({
706
- action: filter.action,
707
- userId: filter.userId,
708
- resource: filter.resource,
709
- success: filter.success,
710
- startDate: filter.startDate,
711
- endDate: filter.endDate,
712
- limit: filter.limit,
713
- offset: filter.offset
714
- });
715
- return {
716
- logs: result.logs.map((log) => ({
717
- ...log,
718
- action: log.action
719
- })),
720
- total: result.total
721
- };
722
- }
723
- async createAuditLog(data) {
724
- const id = await this.logAudit({
725
- action: data.action,
726
- userId: data.userId,
727
- userEmail: data.userEmail,
728
- role: data.role,
729
- resource: data.resource,
730
- resourceId: data.resourceId,
731
- ipAddress: data.ipAddress,
732
- userAgent: data.userAgent,
733
- success: data.success,
734
- error: data.error,
735
- metadata: data.metadata
736
- });
737
- const row = this.db?.prepare("SELECT * FROM kyro_audit_logs WHERE id = ?").get(id);
738
- return {
739
- ...data,
740
- id,
741
- timestamp: row ? new Date(row.timestamp) : /* @__PURE__ */ new Date()
742
- };
743
- }
744
- async createEmailVerificationToken(userId) {
745
- await this.ensureConnected();
746
- const id = randomBytes(16).toString("hex");
747
- const token = randomBytes(32).toString("hex");
748
- const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1e3);
749
- this.db.prepare(
750
- "INSERT INTO kyro_email_verifications (id, user_id, token, expires_at, created_at) VALUES (?, ?, ?, ?, ?)"
751
- ).run(id, userId, token, expiresAt.toISOString(), (/* @__PURE__ */ new Date()).toISOString());
752
- return { token, expiresAt };
753
- }
754
- async verifyEmailToken(token) {
755
- await this.ensureConnected();
756
- const row = this.db.prepare(
757
- "SELECT * FROM kyro_email_verifications WHERE token = ?"
758
- ).get(token);
759
- if (!row) {
760
- return { success: false, error: "Invalid verification token" };
761
- }
762
- if (new Date(row.expires_at) < /* @__PURE__ */ new Date()) {
763
- return { success: false, error: "Verification token has expired" };
764
- }
765
- this.db.prepare(
766
- "UPDATE kyro_users SET email_verified = 1 WHERE id = ?"
767
- ).run(row.user_id);
768
- this.db.prepare(
769
- "DELETE FROM kyro_email_verifications WHERE id = ?"
770
- ).run(row.id);
771
- return { success: true, userId: row.user_id };
772
- }
773
- async createPasswordResetToken(email) {
774
- await this.ensureConnected();
775
- const user = await this.findUserByEmail(email);
776
- if (!user) {
777
- return { token: "", expiresAt: /* @__PURE__ */ new Date(), error: "User not found" };
778
- }
779
- const id = randomBytes(16).toString("hex");
780
- const token = randomBytes(32).toString("hex");
781
- const expiresAt = new Date(Date.now() + 60 * 60 * 1e3);
782
- this.db.prepare(
783
- "INSERT INTO kyro_password_resets (id, user_id, token, expires_at, created_at) VALUES (?, ?, ?, ?, ?)"
784
- ).run(id, user.id, token, expiresAt.toISOString(), (/* @__PURE__ */ new Date()).toISOString());
785
- return { token, expiresAt };
786
- }
787
- async resetPasswordWithToken(token, newPassword) {
788
- await this.ensureConnected();
789
- const row = this.db.prepare(
790
- "SELECT * FROM kyro_password_resets WHERE token = ?"
791
- ).get(token);
792
- if (!row) {
793
- return { success: false, error: "Invalid reset token" };
794
- }
795
- if (new Date(row.expires_at) < /* @__PURE__ */ new Date()) {
796
- return { success: false, error: "Reset token has expired" };
797
- }
798
- if (row.used_at) {
799
- return { success: false, error: "Reset token has already been used" };
800
- }
801
- const passwordHash = await this.hashPassword(newPassword);
802
- this.db.prepare(
803
- "UPDATE kyro_users SET password_hash = ?, updated_at = ? WHERE id = ?"
804
- ).run(passwordHash, (/* @__PURE__ */ new Date()).toISOString(), row.user_id);
805
- this.db.prepare(
806
- "UPDATE kyro_password_resets SET used_at = ? WHERE id = ?"
807
- ).run((/* @__PURE__ */ new Date()).toISOString(), row.id);
808
- this.db.prepare(
809
- "DELETE FROM kyro_sessions WHERE user_id = ?"
810
- ).run(row.user_id);
811
- return { success: true };
812
- }
813
- };
814
-
815
- export { SQLiteAuthAdapter };
816
- //# sourceMappingURL=chunk-Q72BOAPK.js.map
817
- //# sourceMappingURL=chunk-Q72BOAPK.js.map