@etcsec-com/etc-collector 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (617) hide show
  1. package/.env.example +60 -0
  2. package/.env.test.example +33 -0
  3. package/.github/workflows/ci.yml +83 -0
  4. package/.github/workflows/release.yml +246 -0
  5. package/.prettierrc.json +10 -0
  6. package/CHANGELOG.md +15 -0
  7. package/Dockerfile +57 -0
  8. package/LICENSE +190 -0
  9. package/README.md +194 -0
  10. package/dist/api/controllers/audit.controller.d.ts +21 -0
  11. package/dist/api/controllers/audit.controller.d.ts.map +1 -0
  12. package/dist/api/controllers/audit.controller.js +179 -0
  13. package/dist/api/controllers/audit.controller.js.map +1 -0
  14. package/dist/api/controllers/auth.controller.d.ts +16 -0
  15. package/dist/api/controllers/auth.controller.d.ts.map +1 -0
  16. package/dist/api/controllers/auth.controller.js +146 -0
  17. package/dist/api/controllers/auth.controller.js.map +1 -0
  18. package/dist/api/controllers/export.controller.d.ts +27 -0
  19. package/dist/api/controllers/export.controller.d.ts.map +1 -0
  20. package/dist/api/controllers/export.controller.js +80 -0
  21. package/dist/api/controllers/export.controller.js.map +1 -0
  22. package/dist/api/controllers/health.controller.d.ts +5 -0
  23. package/dist/api/controllers/health.controller.d.ts.map +1 -0
  24. package/dist/api/controllers/health.controller.js +16 -0
  25. package/dist/api/controllers/health.controller.js.map +1 -0
  26. package/dist/api/controllers/jobs.controller.d.ts +13 -0
  27. package/dist/api/controllers/jobs.controller.d.ts.map +1 -0
  28. package/dist/api/controllers/jobs.controller.js +125 -0
  29. package/dist/api/controllers/jobs.controller.js.map +1 -0
  30. package/dist/api/controllers/providers.controller.d.ts +15 -0
  31. package/dist/api/controllers/providers.controller.d.ts.map +1 -0
  32. package/dist/api/controllers/providers.controller.js +112 -0
  33. package/dist/api/controllers/providers.controller.js.map +1 -0
  34. package/dist/api/dto/AuditRequest.dto.d.ts +6 -0
  35. package/dist/api/dto/AuditRequest.dto.d.ts.map +1 -0
  36. package/dist/api/dto/AuditRequest.dto.js +3 -0
  37. package/dist/api/dto/AuditRequest.dto.js.map +1 -0
  38. package/dist/api/dto/AuditResponse.dto.d.ts +17 -0
  39. package/dist/api/dto/AuditResponse.dto.d.ts.map +1 -0
  40. package/dist/api/dto/AuditResponse.dto.js +3 -0
  41. package/dist/api/dto/AuditResponse.dto.js.map +1 -0
  42. package/dist/api/dto/TokenRequest.dto.d.ts +6 -0
  43. package/dist/api/dto/TokenRequest.dto.d.ts.map +1 -0
  44. package/dist/api/dto/TokenRequest.dto.js +3 -0
  45. package/dist/api/dto/TokenRequest.dto.js.map +1 -0
  46. package/dist/api/dto/TokenResponse.dto.d.ts +12 -0
  47. package/dist/api/dto/TokenResponse.dto.d.ts.map +1 -0
  48. package/dist/api/dto/TokenResponse.dto.js +3 -0
  49. package/dist/api/dto/TokenResponse.dto.js.map +1 -0
  50. package/dist/api/middlewares/authenticate.d.ts +12 -0
  51. package/dist/api/middlewares/authenticate.d.ts.map +1 -0
  52. package/dist/api/middlewares/authenticate.js +141 -0
  53. package/dist/api/middlewares/authenticate.js.map +1 -0
  54. package/dist/api/middlewares/errorHandler.d.ts +3 -0
  55. package/dist/api/middlewares/errorHandler.d.ts.map +1 -0
  56. package/dist/api/middlewares/errorHandler.js +30 -0
  57. package/dist/api/middlewares/errorHandler.js.map +1 -0
  58. package/dist/api/middlewares/rateLimit.d.ts +3 -0
  59. package/dist/api/middlewares/rateLimit.d.ts.map +1 -0
  60. package/dist/api/middlewares/rateLimit.js +34 -0
  61. package/dist/api/middlewares/rateLimit.js.map +1 -0
  62. package/dist/api/middlewares/validate.d.ts +4 -0
  63. package/dist/api/middlewares/validate.d.ts.map +1 -0
  64. package/dist/api/middlewares/validate.js +31 -0
  65. package/dist/api/middlewares/validate.js.map +1 -0
  66. package/dist/api/routes/audit.routes.d.ts +5 -0
  67. package/dist/api/routes/audit.routes.d.ts.map +1 -0
  68. package/dist/api/routes/audit.routes.js +24 -0
  69. package/dist/api/routes/audit.routes.js.map +1 -0
  70. package/dist/api/routes/auth.routes.d.ts +6 -0
  71. package/dist/api/routes/auth.routes.d.ts.map +1 -0
  72. package/dist/api/routes/auth.routes.js +22 -0
  73. package/dist/api/routes/auth.routes.js.map +1 -0
  74. package/dist/api/routes/export.routes.d.ts +5 -0
  75. package/dist/api/routes/export.routes.d.ts.map +1 -0
  76. package/dist/api/routes/export.routes.js +16 -0
  77. package/dist/api/routes/export.routes.js.map +1 -0
  78. package/dist/api/routes/health.routes.d.ts +4 -0
  79. package/dist/api/routes/health.routes.d.ts.map +1 -0
  80. package/dist/api/routes/health.routes.js +11 -0
  81. package/dist/api/routes/health.routes.js.map +1 -0
  82. package/dist/api/routes/index.d.ts +10 -0
  83. package/dist/api/routes/index.d.ts.map +1 -0
  84. package/dist/api/routes/index.js +20 -0
  85. package/dist/api/routes/index.js.map +1 -0
  86. package/dist/api/routes/providers.routes.d.ts +5 -0
  87. package/dist/api/routes/providers.routes.d.ts.map +1 -0
  88. package/dist/api/routes/providers.routes.js +13 -0
  89. package/dist/api/routes/providers.routes.js.map +1 -0
  90. package/dist/api/validators/audit.schemas.d.ts +60 -0
  91. package/dist/api/validators/audit.schemas.d.ts.map +1 -0
  92. package/dist/api/validators/audit.schemas.js +55 -0
  93. package/dist/api/validators/audit.schemas.js.map +1 -0
  94. package/dist/api/validators/auth.schemas.d.ts +17 -0
  95. package/dist/api/validators/auth.schemas.d.ts.map +1 -0
  96. package/dist/api/validators/auth.schemas.js +21 -0
  97. package/dist/api/validators/auth.schemas.js.map +1 -0
  98. package/dist/app.d.ts +3 -0
  99. package/dist/app.d.ts.map +1 -0
  100. package/dist/app.js +62 -0
  101. package/dist/app.js.map +1 -0
  102. package/dist/config/config.schema.d.ts +65 -0
  103. package/dist/config/config.schema.d.ts.map +1 -0
  104. package/dist/config/config.schema.js +95 -0
  105. package/dist/config/config.schema.js.map +1 -0
  106. package/dist/config/index.d.ts +4 -0
  107. package/dist/config/index.d.ts.map +1 -0
  108. package/dist/config/index.js +75 -0
  109. package/dist/config/index.js.map +1 -0
  110. package/dist/container.d.ts +47 -0
  111. package/dist/container.d.ts.map +1 -0
  112. package/dist/container.js +137 -0
  113. package/dist/container.js.map +1 -0
  114. package/dist/data/database.d.ts +13 -0
  115. package/dist/data/database.d.ts.map +1 -0
  116. package/dist/data/database.js +68 -0
  117. package/dist/data/database.js.map +1 -0
  118. package/dist/data/jobs/token-cleanup.job.d.ts +23 -0
  119. package/dist/data/jobs/token-cleanup.job.d.ts.map +1 -0
  120. package/dist/data/jobs/token-cleanup.job.js +96 -0
  121. package/dist/data/jobs/token-cleanup.job.js.map +1 -0
  122. package/dist/data/migrations/migration.runner.d.ts +13 -0
  123. package/dist/data/migrations/migration.runner.d.ts.map +1 -0
  124. package/dist/data/migrations/migration.runner.js +136 -0
  125. package/dist/data/migrations/migration.runner.js.map +1 -0
  126. package/dist/data/models/Token.model.d.ts +30 -0
  127. package/dist/data/models/Token.model.d.ts.map +1 -0
  128. package/dist/data/models/Token.model.js +3 -0
  129. package/dist/data/models/Token.model.js.map +1 -0
  130. package/dist/data/repositories/token.repository.d.ts +16 -0
  131. package/dist/data/repositories/token.repository.d.ts.map +1 -0
  132. package/dist/data/repositories/token.repository.js +97 -0
  133. package/dist/data/repositories/token.repository.js.map +1 -0
  134. package/dist/providers/azure/auth.provider.d.ts +5 -0
  135. package/dist/providers/azure/auth.provider.d.ts.map +1 -0
  136. package/dist/providers/azure/auth.provider.js +13 -0
  137. package/dist/providers/azure/auth.provider.js.map +1 -0
  138. package/dist/providers/azure/azure-errors.d.ts +40 -0
  139. package/dist/providers/azure/azure-errors.d.ts.map +1 -0
  140. package/dist/providers/azure/azure-errors.js +121 -0
  141. package/dist/providers/azure/azure-errors.js.map +1 -0
  142. package/dist/providers/azure/azure-retry.d.ts +41 -0
  143. package/dist/providers/azure/azure-retry.d.ts.map +1 -0
  144. package/dist/providers/azure/azure-retry.js +85 -0
  145. package/dist/providers/azure/azure-retry.js.map +1 -0
  146. package/dist/providers/azure/graph-client.d.ts +26 -0
  147. package/dist/providers/azure/graph-client.d.ts.map +1 -0
  148. package/dist/providers/azure/graph-client.js +146 -0
  149. package/dist/providers/azure/graph-client.js.map +1 -0
  150. package/dist/providers/azure/graph.provider.d.ts +23 -0
  151. package/dist/providers/azure/graph.provider.d.ts.map +1 -0
  152. package/dist/providers/azure/graph.provider.js +161 -0
  153. package/dist/providers/azure/graph.provider.js.map +1 -0
  154. package/dist/providers/azure/queries/app.queries.d.ts +6 -0
  155. package/dist/providers/azure/queries/app.queries.d.ts.map +1 -0
  156. package/dist/providers/azure/queries/app.queries.js +9 -0
  157. package/dist/providers/azure/queries/app.queries.js.map +1 -0
  158. package/dist/providers/azure/queries/policy.queries.d.ts +6 -0
  159. package/dist/providers/azure/queries/policy.queries.d.ts.map +1 -0
  160. package/dist/providers/azure/queries/policy.queries.js +9 -0
  161. package/dist/providers/azure/queries/policy.queries.js.map +1 -0
  162. package/dist/providers/azure/queries/user.queries.d.ts +7 -0
  163. package/dist/providers/azure/queries/user.queries.d.ts.map +1 -0
  164. package/dist/providers/azure/queries/user.queries.js +10 -0
  165. package/dist/providers/azure/queries/user.queries.js.map +1 -0
  166. package/dist/providers/interfaces/IGraphProvider.d.ts +31 -0
  167. package/dist/providers/interfaces/IGraphProvider.d.ts.map +1 -0
  168. package/dist/providers/interfaces/IGraphProvider.js +3 -0
  169. package/dist/providers/interfaces/IGraphProvider.js.map +1 -0
  170. package/dist/providers/interfaces/ILDAPProvider.d.ts +37 -0
  171. package/dist/providers/interfaces/ILDAPProvider.d.ts.map +1 -0
  172. package/dist/providers/interfaces/ILDAPProvider.js +3 -0
  173. package/dist/providers/interfaces/ILDAPProvider.js.map +1 -0
  174. package/dist/providers/ldap/acl-parser.d.ts +8 -0
  175. package/dist/providers/ldap/acl-parser.d.ts.map +1 -0
  176. package/dist/providers/ldap/acl-parser.js +157 -0
  177. package/dist/providers/ldap/acl-parser.js.map +1 -0
  178. package/dist/providers/ldap/ad-mappers.d.ts +8 -0
  179. package/dist/providers/ldap/ad-mappers.d.ts.map +1 -0
  180. package/dist/providers/ldap/ad-mappers.js +162 -0
  181. package/dist/providers/ldap/ad-mappers.js.map +1 -0
  182. package/dist/providers/ldap/ldap-client.d.ts +33 -0
  183. package/dist/providers/ldap/ldap-client.d.ts.map +1 -0
  184. package/dist/providers/ldap/ldap-client.js +195 -0
  185. package/dist/providers/ldap/ldap-client.js.map +1 -0
  186. package/dist/providers/ldap/ldap-errors.d.ts +48 -0
  187. package/dist/providers/ldap/ldap-errors.d.ts.map +1 -0
  188. package/dist/providers/ldap/ldap-errors.js +120 -0
  189. package/dist/providers/ldap/ldap-errors.js.map +1 -0
  190. package/dist/providers/ldap/ldap-retry.d.ts +14 -0
  191. package/dist/providers/ldap/ldap-retry.d.ts.map +1 -0
  192. package/dist/providers/ldap/ldap-retry.js +102 -0
  193. package/dist/providers/ldap/ldap-retry.js.map +1 -0
  194. package/dist/providers/ldap/ldap-sanitizer.d.ts +12 -0
  195. package/dist/providers/ldap/ldap-sanitizer.d.ts.map +1 -0
  196. package/dist/providers/ldap/ldap-sanitizer.js +104 -0
  197. package/dist/providers/ldap/ldap-sanitizer.js.map +1 -0
  198. package/dist/providers/ldap/ldap.provider.d.ts +21 -0
  199. package/dist/providers/ldap/ldap.provider.d.ts.map +1 -0
  200. package/dist/providers/ldap/ldap.provider.js +165 -0
  201. package/dist/providers/ldap/ldap.provider.js.map +1 -0
  202. package/dist/providers/ldap/queries/computer.queries.d.ts +6 -0
  203. package/dist/providers/ldap/queries/computer.queries.d.ts.map +1 -0
  204. package/dist/providers/ldap/queries/computer.queries.js +9 -0
  205. package/dist/providers/ldap/queries/computer.queries.js.map +1 -0
  206. package/dist/providers/ldap/queries/group.queries.d.ts +6 -0
  207. package/dist/providers/ldap/queries/group.queries.d.ts.map +1 -0
  208. package/dist/providers/ldap/queries/group.queries.js +9 -0
  209. package/dist/providers/ldap/queries/group.queries.js.map +1 -0
  210. package/dist/providers/ldap/queries/user.queries.d.ts +7 -0
  211. package/dist/providers/ldap/queries/user.queries.d.ts.map +1 -0
  212. package/dist/providers/ldap/queries/user.queries.js +10 -0
  213. package/dist/providers/ldap/queries/user.queries.js.map +1 -0
  214. package/dist/providers/smb/smb.provider.d.ts +68 -0
  215. package/dist/providers/smb/smb.provider.d.ts.map +1 -0
  216. package/dist/providers/smb/smb.provider.js +382 -0
  217. package/dist/providers/smb/smb.provider.js.map +1 -0
  218. package/dist/server.d.ts +2 -0
  219. package/dist/server.d.ts.map +1 -0
  220. package/dist/server.js +44 -0
  221. package/dist/server.js.map +1 -0
  222. package/dist/services/audit/ad-audit.service.d.ts +70 -0
  223. package/dist/services/audit/ad-audit.service.d.ts.map +1 -0
  224. package/dist/services/audit/ad-audit.service.js +1019 -0
  225. package/dist/services/audit/ad-audit.service.js.map +1 -0
  226. package/dist/services/audit/attack-graph.service.d.ts +62 -0
  227. package/dist/services/audit/attack-graph.service.d.ts.map +1 -0
  228. package/dist/services/audit/attack-graph.service.js +702 -0
  229. package/dist/services/audit/attack-graph.service.js.map +1 -0
  230. package/dist/services/audit/audit.service.d.ts +4 -0
  231. package/dist/services/audit/audit.service.d.ts.map +1 -0
  232. package/dist/services/audit/audit.service.js +10 -0
  233. package/dist/services/audit/audit.service.js.map +1 -0
  234. package/dist/services/audit/azure-audit.service.d.ts +37 -0
  235. package/dist/services/audit/azure-audit.service.d.ts.map +1 -0
  236. package/dist/services/audit/azure-audit.service.js +153 -0
  237. package/dist/services/audit/azure-audit.service.js.map +1 -0
  238. package/dist/services/audit/detectors/ad/accounts.detector.d.ts +37 -0
  239. package/dist/services/audit/detectors/ad/accounts.detector.d.ts.map +1 -0
  240. package/dist/services/audit/detectors/ad/accounts.detector.js +881 -0
  241. package/dist/services/audit/detectors/ad/accounts.detector.js.map +1 -0
  242. package/dist/services/audit/detectors/ad/adcs.detector.d.ts +21 -0
  243. package/dist/services/audit/detectors/ad/adcs.detector.d.ts.map +1 -0
  244. package/dist/services/audit/detectors/ad/adcs.detector.js +227 -0
  245. package/dist/services/audit/detectors/ad/adcs.detector.js.map +1 -0
  246. package/dist/services/audit/detectors/ad/advanced.detector.d.ts +63 -0
  247. package/dist/services/audit/detectors/ad/advanced.detector.d.ts.map +1 -0
  248. package/dist/services/audit/detectors/ad/advanced.detector.js +867 -0
  249. package/dist/services/audit/detectors/ad/advanced.detector.js.map +1 -0
  250. package/dist/services/audit/detectors/ad/attack-paths.detector.d.ts +16 -0
  251. package/dist/services/audit/detectors/ad/attack-paths.detector.d.ts.map +1 -0
  252. package/dist/services/audit/detectors/ad/attack-paths.detector.js +369 -0
  253. package/dist/services/audit/detectors/ad/attack-paths.detector.js.map +1 -0
  254. package/dist/services/audit/detectors/ad/compliance.detector.d.ts +28 -0
  255. package/dist/services/audit/detectors/ad/compliance.detector.d.ts.map +1 -0
  256. package/dist/services/audit/detectors/ad/compliance.detector.js +896 -0
  257. package/dist/services/audit/detectors/ad/compliance.detector.js.map +1 -0
  258. package/dist/services/audit/detectors/ad/computers.detector.d.ts +30 -0
  259. package/dist/services/audit/detectors/ad/computers.detector.d.ts.map +1 -0
  260. package/dist/services/audit/detectors/ad/computers.detector.js +799 -0
  261. package/dist/services/audit/detectors/ad/computers.detector.js.map +1 -0
  262. package/dist/services/audit/detectors/ad/gpo.detector.d.ts +17 -0
  263. package/dist/services/audit/detectors/ad/gpo.detector.d.ts.map +1 -0
  264. package/dist/services/audit/detectors/ad/gpo.detector.js +257 -0
  265. package/dist/services/audit/detectors/ad/gpo.detector.js.map +1 -0
  266. package/dist/services/audit/detectors/ad/groups.detector.d.ts +19 -0
  267. package/dist/services/audit/detectors/ad/groups.detector.d.ts.map +1 -0
  268. package/dist/services/audit/detectors/ad/groups.detector.js +488 -0
  269. package/dist/services/audit/detectors/ad/groups.detector.js.map +1 -0
  270. package/dist/services/audit/detectors/ad/index.d.ts +15 -0
  271. package/dist/services/audit/detectors/ad/index.d.ts.map +1 -0
  272. package/dist/services/audit/detectors/ad/index.js +51 -0
  273. package/dist/services/audit/detectors/ad/index.js.map +1 -0
  274. package/dist/services/audit/detectors/ad/kerberos.detector.d.ts +17 -0
  275. package/dist/services/audit/detectors/ad/kerberos.detector.d.ts.map +1 -0
  276. package/dist/services/audit/detectors/ad/kerberos.detector.js +293 -0
  277. package/dist/services/audit/detectors/ad/kerberos.detector.js.map +1 -0
  278. package/dist/services/audit/detectors/ad/monitoring.detector.d.ts +23 -0
  279. package/dist/services/audit/detectors/ad/monitoring.detector.d.ts.map +1 -0
  280. package/dist/services/audit/detectors/ad/monitoring.detector.js +328 -0
  281. package/dist/services/audit/detectors/ad/monitoring.detector.js.map +1 -0
  282. package/dist/services/audit/detectors/ad/network.detector.d.ts +39 -0
  283. package/dist/services/audit/detectors/ad/network.detector.d.ts.map +1 -0
  284. package/dist/services/audit/detectors/ad/network.detector.js +257 -0
  285. package/dist/services/audit/detectors/ad/network.detector.js.map +1 -0
  286. package/dist/services/audit/detectors/ad/password.detector.d.ts +14 -0
  287. package/dist/services/audit/detectors/ad/password.detector.d.ts.map +1 -0
  288. package/dist/services/audit/detectors/ad/password.detector.js +235 -0
  289. package/dist/services/audit/detectors/ad/password.detector.js.map +1 -0
  290. package/dist/services/audit/detectors/ad/permissions.detector.d.ts +20 -0
  291. package/dist/services/audit/detectors/ad/permissions.detector.d.ts.map +1 -0
  292. package/dist/services/audit/detectors/ad/permissions.detector.js +392 -0
  293. package/dist/services/audit/detectors/ad/permissions.detector.js.map +1 -0
  294. package/dist/services/audit/detectors/ad/trusts.detector.d.ts +11 -0
  295. package/dist/services/audit/detectors/ad/trusts.detector.d.ts.map +1 -0
  296. package/dist/services/audit/detectors/ad/trusts.detector.js +186 -0
  297. package/dist/services/audit/detectors/ad/trusts.detector.js.map +1 -0
  298. package/dist/services/audit/detectors/azure/app-security.detector.d.ts +11 -0
  299. package/dist/services/audit/detectors/azure/app-security.detector.d.ts.map +1 -0
  300. package/dist/services/audit/detectors/azure/app-security.detector.js +184 -0
  301. package/dist/services/audit/detectors/azure/app-security.detector.js.map +1 -0
  302. package/dist/services/audit/detectors/azure/conditional-access.detector.d.ts +10 -0
  303. package/dist/services/audit/detectors/azure/conditional-access.detector.d.ts.map +1 -0
  304. package/dist/services/audit/detectors/azure/conditional-access.detector.js +130 -0
  305. package/dist/services/audit/detectors/azure/conditional-access.detector.js.map +1 -0
  306. package/dist/services/audit/detectors/azure/privilege-security.detector.d.ts +8 -0
  307. package/dist/services/audit/detectors/azure/privilege-security.detector.d.ts.map +1 -0
  308. package/dist/services/audit/detectors/azure/privilege-security.detector.js +113 -0
  309. package/dist/services/audit/detectors/azure/privilege-security.detector.js.map +1 -0
  310. package/dist/services/audit/detectors/azure/user-security.detector.d.ts +14 -0
  311. package/dist/services/audit/detectors/azure/user-security.detector.d.ts.map +1 -0
  312. package/dist/services/audit/detectors/azure/user-security.detector.js +198 -0
  313. package/dist/services/audit/detectors/azure/user-security.detector.js.map +1 -0
  314. package/dist/services/audit/detectors/index.d.ts +2 -0
  315. package/dist/services/audit/detectors/index.d.ts.map +1 -0
  316. package/dist/services/audit/detectors/index.js +38 -0
  317. package/dist/services/audit/detectors/index.js.map +1 -0
  318. package/dist/services/audit/response-formatter.d.ts +176 -0
  319. package/dist/services/audit/response-formatter.d.ts.map +1 -0
  320. package/dist/services/audit/response-formatter.js +240 -0
  321. package/dist/services/audit/response-formatter.js.map +1 -0
  322. package/dist/services/audit/scoring.service.d.ts +15 -0
  323. package/dist/services/audit/scoring.service.d.ts.map +1 -0
  324. package/dist/services/audit/scoring.service.js +139 -0
  325. package/dist/services/audit/scoring.service.js.map +1 -0
  326. package/dist/services/auth/crypto.service.d.ts +19 -0
  327. package/dist/services/auth/crypto.service.d.ts.map +1 -0
  328. package/dist/services/auth/crypto.service.js +135 -0
  329. package/dist/services/auth/crypto.service.js.map +1 -0
  330. package/dist/services/auth/errors.d.ts +19 -0
  331. package/dist/services/auth/errors.d.ts.map +1 -0
  332. package/dist/services/auth/errors.js +46 -0
  333. package/dist/services/auth/errors.js.map +1 -0
  334. package/dist/services/auth/token.service.d.ts +41 -0
  335. package/dist/services/auth/token.service.d.ts.map +1 -0
  336. package/dist/services/auth/token.service.js +208 -0
  337. package/dist/services/auth/token.service.js.map +1 -0
  338. package/dist/services/config/config.service.d.ts +6 -0
  339. package/dist/services/config/config.service.d.ts.map +1 -0
  340. package/dist/services/config/config.service.js +64 -0
  341. package/dist/services/config/config.service.js.map +1 -0
  342. package/dist/services/export/export.service.d.ts +28 -0
  343. package/dist/services/export/export.service.d.ts.map +1 -0
  344. package/dist/services/export/export.service.js +28 -0
  345. package/dist/services/export/export.service.js.map +1 -0
  346. package/dist/services/export/formatters/csv.formatter.d.ts +8 -0
  347. package/dist/services/export/formatters/csv.formatter.d.ts.map +1 -0
  348. package/dist/services/export/formatters/csv.formatter.js +46 -0
  349. package/dist/services/export/formatters/csv.formatter.js.map +1 -0
  350. package/dist/services/export/formatters/json.formatter.d.ts +40 -0
  351. package/dist/services/export/formatters/json.formatter.d.ts.map +1 -0
  352. package/dist/services/export/formatters/json.formatter.js +58 -0
  353. package/dist/services/export/formatters/json.formatter.js.map +1 -0
  354. package/dist/services/jobs/azure-job-runner.d.ts +38 -0
  355. package/dist/services/jobs/azure-job-runner.d.ts.map +1 -0
  356. package/dist/services/jobs/azure-job-runner.js +199 -0
  357. package/dist/services/jobs/azure-job-runner.js.map +1 -0
  358. package/dist/services/jobs/index.d.ts +4 -0
  359. package/dist/services/jobs/index.d.ts.map +1 -0
  360. package/dist/services/jobs/index.js +20 -0
  361. package/dist/services/jobs/index.js.map +1 -0
  362. package/dist/services/jobs/job-runner.d.ts +64 -0
  363. package/dist/services/jobs/job-runner.d.ts.map +1 -0
  364. package/dist/services/jobs/job-runner.js +952 -0
  365. package/dist/services/jobs/job-runner.js.map +1 -0
  366. package/dist/services/jobs/job-store.d.ts +27 -0
  367. package/dist/services/jobs/job-store.d.ts.map +1 -0
  368. package/dist/services/jobs/job-store.js +261 -0
  369. package/dist/services/jobs/job-store.js.map +1 -0
  370. package/dist/services/jobs/job.types.d.ts +67 -0
  371. package/dist/services/jobs/job.types.d.ts.map +1 -0
  372. package/dist/services/jobs/job.types.js +36 -0
  373. package/dist/services/jobs/job.types.js.map +1 -0
  374. package/dist/types/ad.types.d.ts +74 -0
  375. package/dist/types/ad.types.d.ts.map +1 -0
  376. package/dist/types/ad.types.js +3 -0
  377. package/dist/types/ad.types.js.map +1 -0
  378. package/dist/types/adcs.types.d.ts +58 -0
  379. package/dist/types/adcs.types.d.ts.map +1 -0
  380. package/dist/types/adcs.types.js +38 -0
  381. package/dist/types/adcs.types.js.map +1 -0
  382. package/dist/types/attack-graph.types.d.ts +135 -0
  383. package/dist/types/attack-graph.types.d.ts.map +1 -0
  384. package/dist/types/attack-graph.types.js +58 -0
  385. package/dist/types/attack-graph.types.js.map +1 -0
  386. package/dist/types/audit.types.d.ts +34 -0
  387. package/dist/types/audit.types.d.ts.map +1 -0
  388. package/dist/types/audit.types.js +3 -0
  389. package/dist/types/audit.types.js.map +1 -0
  390. package/dist/types/azure.types.d.ts +61 -0
  391. package/dist/types/azure.types.d.ts.map +1 -0
  392. package/dist/types/azure.types.js +3 -0
  393. package/dist/types/azure.types.js.map +1 -0
  394. package/dist/types/config.types.d.ts +63 -0
  395. package/dist/types/config.types.d.ts.map +1 -0
  396. package/dist/types/config.types.js +3 -0
  397. package/dist/types/config.types.js.map +1 -0
  398. package/dist/types/error.types.d.ts +33 -0
  399. package/dist/types/error.types.d.ts.map +1 -0
  400. package/dist/types/error.types.js +70 -0
  401. package/dist/types/error.types.js.map +1 -0
  402. package/dist/types/finding.types.d.ts +133 -0
  403. package/dist/types/finding.types.d.ts.map +1 -0
  404. package/dist/types/finding.types.js +3 -0
  405. package/dist/types/finding.types.js.map +1 -0
  406. package/dist/types/gpo.types.d.ts +39 -0
  407. package/dist/types/gpo.types.d.ts.map +1 -0
  408. package/dist/types/gpo.types.js +15 -0
  409. package/dist/types/gpo.types.js.map +1 -0
  410. package/dist/types/token.types.d.ts +26 -0
  411. package/dist/types/token.types.d.ts.map +1 -0
  412. package/dist/types/token.types.js +3 -0
  413. package/dist/types/token.types.js.map +1 -0
  414. package/dist/types/trust.types.d.ts +45 -0
  415. package/dist/types/trust.types.d.ts.map +1 -0
  416. package/dist/types/trust.types.js +71 -0
  417. package/dist/types/trust.types.js.map +1 -0
  418. package/dist/utils/entity-converter.d.ts +17 -0
  419. package/dist/utils/entity-converter.d.ts.map +1 -0
  420. package/dist/utils/entity-converter.js +285 -0
  421. package/dist/utils/entity-converter.js.map +1 -0
  422. package/dist/utils/graph.util.d.ts +66 -0
  423. package/dist/utils/graph.util.d.ts.map +1 -0
  424. package/dist/utils/graph.util.js +382 -0
  425. package/dist/utils/graph.util.js.map +1 -0
  426. package/dist/utils/logger.d.ts +7 -0
  427. package/dist/utils/logger.d.ts.map +1 -0
  428. package/dist/utils/logger.js +86 -0
  429. package/dist/utils/logger.js.map +1 -0
  430. package/dist/utils/type-name-normalizer.d.ts +5 -0
  431. package/dist/utils/type-name-normalizer.d.ts.map +1 -0
  432. package/dist/utils/type-name-normalizer.js +218 -0
  433. package/dist/utils/type-name-normalizer.js.map +1 -0
  434. package/docker-compose.yml +26 -0
  435. package/docs/api/README.md +178 -0
  436. package/docs/api/openapi.yaml +1524 -0
  437. package/eslint.config.js +54 -0
  438. package/jest.config.js +38 -0
  439. package/package.json +97 -0
  440. package/scripts/fetch-ad-cert.sh +142 -0
  441. package/src/.gitkeep +0 -0
  442. package/src/api/.gitkeep +0 -0
  443. package/src/api/controllers/.gitkeep +0 -0
  444. package/src/api/controllers/audit.controller.ts +313 -0
  445. package/src/api/controllers/auth.controller.ts +258 -0
  446. package/src/api/controllers/export.controller.ts +153 -0
  447. package/src/api/controllers/health.controller.ts +16 -0
  448. package/src/api/controllers/jobs.controller.ts +187 -0
  449. package/src/api/controllers/providers.controller.ts +165 -0
  450. package/src/api/dto/.gitkeep +0 -0
  451. package/src/api/dto/AuditRequest.dto.ts +8 -0
  452. package/src/api/dto/AuditResponse.dto.ts +19 -0
  453. package/src/api/dto/TokenRequest.dto.ts +8 -0
  454. package/src/api/dto/TokenResponse.dto.ts +14 -0
  455. package/src/api/middlewares/.gitkeep +0 -0
  456. package/src/api/middlewares/authenticate.ts +203 -0
  457. package/src/api/middlewares/errorHandler.ts +54 -0
  458. package/src/api/middlewares/rateLimit.ts +35 -0
  459. package/src/api/middlewares/validate.ts +32 -0
  460. package/src/api/routes/.gitkeep +0 -0
  461. package/src/api/routes/audit.routes.ts +77 -0
  462. package/src/api/routes/auth.routes.ts +71 -0
  463. package/src/api/routes/export.routes.ts +34 -0
  464. package/src/api/routes/health.routes.ts +14 -0
  465. package/src/api/routes/index.ts +40 -0
  466. package/src/api/routes/providers.routes.ts +24 -0
  467. package/src/api/validators/.gitkeep +0 -0
  468. package/src/api/validators/audit.schemas.ts +59 -0
  469. package/src/api/validators/auth.schemas.ts +59 -0
  470. package/src/app.ts +87 -0
  471. package/src/config/.gitkeep +0 -0
  472. package/src/config/config.schema.ts +108 -0
  473. package/src/config/index.ts +82 -0
  474. package/src/container.ts +221 -0
  475. package/src/data/.gitkeep +0 -0
  476. package/src/data/database.ts +78 -0
  477. package/src/data/jobs/token-cleanup.job.ts +166 -0
  478. package/src/data/migrations/.gitkeep +0 -0
  479. package/src/data/migrations/001_initial_schema.sql +47 -0
  480. package/src/data/migrations/migration.runner.ts +125 -0
  481. package/src/data/models/.gitkeep +0 -0
  482. package/src/data/models/Token.model.ts +35 -0
  483. package/src/data/repositories/.gitkeep +0 -0
  484. package/src/data/repositories/token.repository.ts +160 -0
  485. package/src/providers/.gitkeep +0 -0
  486. package/src/providers/azure/.gitkeep +0 -0
  487. package/src/providers/azure/auth.provider.ts +14 -0
  488. package/src/providers/azure/azure-errors.ts +189 -0
  489. package/src/providers/azure/azure-retry.ts +168 -0
  490. package/src/providers/azure/graph-client.ts +315 -0
  491. package/src/providers/azure/graph.provider.ts +294 -0
  492. package/src/providers/azure/queries/app.queries.ts +9 -0
  493. package/src/providers/azure/queries/policy.queries.ts +9 -0
  494. package/src/providers/azure/queries/user.queries.ts +10 -0
  495. package/src/providers/interfaces/.gitkeep +0 -0
  496. package/src/providers/interfaces/IGraphProvider.ts +117 -0
  497. package/src/providers/interfaces/ILDAPProvider.ts +142 -0
  498. package/src/providers/ldap/.gitkeep +0 -0
  499. package/src/providers/ldap/acl-parser.ts +231 -0
  500. package/src/providers/ldap/ad-mappers.ts +280 -0
  501. package/src/providers/ldap/ldap-client.ts +259 -0
  502. package/src/providers/ldap/ldap-errors.ts +188 -0
  503. package/src/providers/ldap/ldap-retry.ts +267 -0
  504. package/src/providers/ldap/ldap-sanitizer.ts +273 -0
  505. package/src/providers/ldap/ldap.provider.ts +293 -0
  506. package/src/providers/ldap/queries/computer.queries.ts +9 -0
  507. package/src/providers/ldap/queries/group.queries.ts +9 -0
  508. package/src/providers/ldap/queries/user.queries.ts +10 -0
  509. package/src/providers/smb/smb.provider.ts +653 -0
  510. package/src/server.ts +60 -0
  511. package/src/services/.gitkeep +0 -0
  512. package/src/services/audit/.gitkeep +0 -0
  513. package/src/services/audit/ad-audit.service.ts +1481 -0
  514. package/src/services/audit/attack-graph.service.ts +1104 -0
  515. package/src/services/audit/audit.service.ts +12 -0
  516. package/src/services/audit/azure-audit.service.ts +286 -0
  517. package/src/services/audit/detectors/ad/accounts.detector.ts +1232 -0
  518. package/src/services/audit/detectors/ad/adcs.detector.ts +449 -0
  519. package/src/services/audit/detectors/ad/advanced.detector.ts +1270 -0
  520. package/src/services/audit/detectors/ad/attack-paths.detector.ts +600 -0
  521. package/src/services/audit/detectors/ad/compliance.detector.ts +1421 -0
  522. package/src/services/audit/detectors/ad/computers.detector.ts +1188 -0
  523. package/src/services/audit/detectors/ad/gpo.detector.ts +485 -0
  524. package/src/services/audit/detectors/ad/groups.detector.ts +685 -0
  525. package/src/services/audit/detectors/ad/index.ts +84 -0
  526. package/src/services/audit/detectors/ad/kerberos.detector.ts +424 -0
  527. package/src/services/audit/detectors/ad/monitoring.detector.ts +501 -0
  528. package/src/services/audit/detectors/ad/network.detector.ts +538 -0
  529. package/src/services/audit/detectors/ad/password.detector.ts +324 -0
  530. package/src/services/audit/detectors/ad/permissions.detector.ts +637 -0
  531. package/src/services/audit/detectors/ad/trusts.detector.ts +315 -0
  532. package/src/services/audit/detectors/azure/app-security.detector.ts +246 -0
  533. package/src/services/audit/detectors/azure/conditional-access.detector.ts +186 -0
  534. package/src/services/audit/detectors/azure/privilege-security.detector.ts +176 -0
  535. package/src/services/audit/detectors/azure/user-security.detector.ts +280 -0
  536. package/src/services/audit/detectors/index.ts +18 -0
  537. package/src/services/audit/response-formatter.ts +604 -0
  538. package/src/services/audit/scoring.service.ts +234 -0
  539. package/src/services/auth/.gitkeep +0 -0
  540. package/src/services/auth/crypto.service.ts +230 -0
  541. package/src/services/auth/errors.ts +47 -0
  542. package/src/services/auth/token.service.ts +420 -0
  543. package/src/services/config/.gitkeep +0 -0
  544. package/src/services/config/config.service.ts +75 -0
  545. package/src/services/export/.gitkeep +0 -0
  546. package/src/services/export/export.service.ts +99 -0
  547. package/src/services/export/formatters/csv.formatter.ts +124 -0
  548. package/src/services/export/formatters/json.formatter.ts +160 -0
  549. package/src/services/jobs/azure-job-runner.ts +312 -0
  550. package/src/services/jobs/index.ts +9 -0
  551. package/src/services/jobs/job-runner.ts +1280 -0
  552. package/src/services/jobs/job-store.ts +384 -0
  553. package/src/services/jobs/job.types.ts +182 -0
  554. package/src/types/.gitkeep +0 -0
  555. package/src/types/ad.types.ts +91 -0
  556. package/src/types/adcs.types.ts +107 -0
  557. package/src/types/attack-graph.types.ts +260 -0
  558. package/src/types/audit.types.ts +42 -0
  559. package/src/types/azure.types.ts +68 -0
  560. package/src/types/config.types.ts +79 -0
  561. package/src/types/error.types.ts +69 -0
  562. package/src/types/finding.types.ts +284 -0
  563. package/src/types/gpo.types.ts +72 -0
  564. package/src/types/smb2.d.ts +73 -0
  565. package/src/types/token.types.ts +32 -0
  566. package/src/types/trust.types.ts +140 -0
  567. package/src/utils/.gitkeep +0 -0
  568. package/src/utils/entity-converter.ts +453 -0
  569. package/src/utils/graph.util.ts +609 -0
  570. package/src/utils/logger.ts +111 -0
  571. package/src/utils/type-name-normalizer.ts +302 -0
  572. package/tests/.gitkeep +0 -0
  573. package/tests/e2e/.gitkeep +0 -0
  574. package/tests/fixtures/.gitkeep +0 -0
  575. package/tests/integration/.gitkeep +0 -0
  576. package/tests/integration/README.md +156 -0
  577. package/tests/integration/ad-audit.integration.test.ts +216 -0
  578. package/tests/integration/api/.gitkeep +0 -0
  579. package/tests/integration/api/endpoints.integration.test.ts +431 -0
  580. package/tests/integration/auth/jwt-authentication.integration.test.ts +358 -0
  581. package/tests/integration/providers/.gitkeep +0 -0
  582. package/tests/integration/providers/azure-basic.integration.test.ts +167 -0
  583. package/tests/integration/providers/ldap-basic.integration.test.ts +152 -0
  584. package/tests/integration/providers/ldap-connectivity.test.ts +44 -0
  585. package/tests/integration/providers/ldap-provider.integration.test.ts +347 -0
  586. package/tests/mocks/.gitkeep +0 -0
  587. package/tests/setup.ts +16 -0
  588. package/tests/unit/.gitkeep +0 -0
  589. package/tests/unit/api/middlewares/authenticate.test.ts +446 -0
  590. package/tests/unit/providers/.gitkeep +0 -0
  591. package/tests/unit/providers/azure/azure-errors.test.ts +193 -0
  592. package/tests/unit/providers/azure/azure-retry.test.ts +254 -0
  593. package/tests/unit/providers/azure/graph-provider.test.ts +313 -0
  594. package/tests/unit/providers/ldap/ad-mappers.test.ts +392 -0
  595. package/tests/unit/providers/ldap/ldap-provider.test.ts +376 -0
  596. package/tests/unit/providers/ldap/ldap-retry.test.ts +377 -0
  597. package/tests/unit/providers/ldap/ldap-sanitizer.test.ts +301 -0
  598. package/tests/unit/sample.test.ts +19 -0
  599. package/tests/unit/services/.gitkeep +0 -0
  600. package/tests/unit/services/audit/detectors/ad/accounts.detector.test.ts +393 -0
  601. package/tests/unit/services/audit/detectors/ad/advanced.detector.test.ts +380 -0
  602. package/tests/unit/services/audit/detectors/ad/computers.detector.test.ts +440 -0
  603. package/tests/unit/services/audit/detectors/ad/groups.detector.test.ts +276 -0
  604. package/tests/unit/services/audit/detectors/ad/kerberos.detector.test.ts +215 -0
  605. package/tests/unit/services/audit/detectors/ad/password.detector.test.ts +226 -0
  606. package/tests/unit/services/audit/detectors/ad/permissions.detector.test.ts +244 -0
  607. package/tests/unit/services/audit/detectors/azure/app-security.detector.test.ts +349 -0
  608. package/tests/unit/services/audit/detectors/azure/conditional-access.detector.test.ts +374 -0
  609. package/tests/unit/services/audit/detectors/azure/privilege-security.detector.test.ts +374 -0
  610. package/tests/unit/services/audit/detectors/azure/user-security.detector.test.ts +297 -0
  611. package/tests/unit/services/auth/crypto.service.test.ts +296 -0
  612. package/tests/unit/services/auth/token.service.test.ts +579 -0
  613. package/tests/unit/services/export/export.service.test.ts +241 -0
  614. package/tests/unit/services/export/formatters/csv.formatter.test.ts +270 -0
  615. package/tests/unit/services/export/formatters/json.formatter.test.ts +258 -0
  616. package/tests/unit/utils/.gitkeep +0 -0
  617. package/tsconfig.json +50 -0
@@ -0,0 +1,221 @@
1
+ import Database from 'better-sqlite3';
2
+ import { getConfig } from './config';
3
+ import { DatabaseManager } from './data/database';
4
+ import { TokenRepository } from './data/repositories/token.repository';
5
+ import { CryptoService } from './services/auth/crypto.service';
6
+ import { TokenService } from './services/auth/token.service';
7
+ import { HealthController } from './api/controllers/health.controller';
8
+ import { AuthController } from './api/controllers/auth.controller';
9
+ import { AuditController } from './api/controllers/audit.controller';
10
+ import { ExportController } from './api/controllers/export.controller';
11
+ import { ProvidersController } from './api/controllers/providers.controller';
12
+ import { LDAPProvider } from './providers/ldap/ldap.provider';
13
+ import { GraphProvider } from './providers/azure/graph.provider';
14
+ import type { Logger } from 'winston';
15
+ import { logger } from './utils/logger';
16
+ import { InfoEndpointsConfig } from './types/config.types';
17
+
18
+ /**
19
+ * Dependency Injection Container
20
+ *
21
+ * Manages all application dependencies with singleton pattern.
22
+ * Handles proper initialization order:
23
+ * 1. Config
24
+ * 2. Database + Repositories
25
+ * 3. CryptoService (loads RSA keys)
26
+ * 4. TokenService
27
+ * 5. LDAP Provider
28
+ * 6. Azure Graph Provider
29
+ * 7. Controllers
30
+ *
31
+ * Updated: Story 1.4 (JWT), Story 1.5 (LDAP), Story 1.6 (Azure)
32
+ */
33
+ export class DIContainer {
34
+ private static instance: DIContainer | null = null;
35
+ private logger: Logger;
36
+
37
+ // Database
38
+ private db!: Database.Database;
39
+ private dbManager!: DatabaseManager;
40
+
41
+ // Repositories
42
+ private tokenRepository!: TokenRepository;
43
+
44
+ // Services
45
+ private cryptoService!: CryptoService;
46
+ private tokenService!: TokenService;
47
+
48
+ // Providers
49
+ private ldapProvider!: LDAPProvider;
50
+ private graphProvider!: GraphProvider;
51
+
52
+ // Controllers
53
+ private healthController!: HealthController;
54
+ private authController!: AuthController;
55
+ private auditController!: AuditController;
56
+ private exportController!: ExportController;
57
+ private providersController!: ProvidersController;
58
+
59
+ // Config
60
+ private infoEndpointsConfig!: InfoEndpointsConfig;
61
+
62
+ private constructor() {
63
+ this.logger = logger;
64
+ }
65
+
66
+ /**
67
+ * Get singleton instance
68
+ *
69
+ * @throws Error if instance not initialized (call initialize() first)
70
+ */
71
+ static getInstance(): DIContainer {
72
+ if (!DIContainer.instance) {
73
+ throw new Error('DIContainer not initialized. Call DIContainer.initialize() first.');
74
+ }
75
+ return DIContainer.instance;
76
+ }
77
+
78
+ /**
79
+ * Initialize DI container with async dependencies
80
+ *
81
+ * This method must be called before using the container.
82
+ * It loads configuration, initializes database, loads RSA keys, and creates all services.
83
+ *
84
+ * @returns Promise<DIContainer> Initialized container instance
85
+ */
86
+ static async initialize(): Promise<DIContainer> {
87
+ if (DIContainer.instance) {
88
+ return DIContainer.instance;
89
+ }
90
+
91
+ const container = new DIContainer();
92
+ await container.init();
93
+ DIContainer.instance = container;
94
+ return container;
95
+ }
96
+
97
+ /**
98
+ * Reset singleton instance (for testing)
99
+ */
100
+ static reset(): void {
101
+ DIContainer.instance = null;
102
+ }
103
+
104
+ /**
105
+ * Internal initialization logic
106
+ */
107
+ private async init(): Promise<void> {
108
+ this.logger.info('Initializing DI container');
109
+
110
+ // 1. Load configuration
111
+ const config = getConfig();
112
+ this.logger.debug('Configuration loaded', {
113
+ port: config.server.port,
114
+ env: config.server.nodeEnv,
115
+ dbPath: config.database.path,
116
+ });
117
+
118
+ // 2. Initialize database and repositories
119
+ this.dbManager = DatabaseManager.getInstance();
120
+ this.db = this.dbManager.connect(config.database.path);
121
+ this.tokenRepository = new TokenRepository(this.db);
122
+ this.logger.debug('Database and repositories initialized');
123
+
124
+ // 3. Initialize crypto service and load RSA keys
125
+ this.cryptoService = new CryptoService(
126
+ config.jwt.privateKeyPath,
127
+ config.jwt.publicKeyPath
128
+ );
129
+ await this.cryptoService.loadOrGenerateKeys();
130
+ this.logger.debug('Crypto service initialized and keys loaded');
131
+
132
+ // 4. Initialize token service
133
+ this.tokenService = new TokenService(this.tokenRepository, this.cryptoService);
134
+ this.logger.debug('Token service initialized');
135
+
136
+ // 5. Initialize LDAP provider
137
+ this.ldapProvider = new LDAPProvider(config.ldap);
138
+ this.logger.debug('LDAP provider initialized', {
139
+ url: config.ldap.url,
140
+ baseDN: config.ldap.baseDN,
141
+ });
142
+
143
+ // 6. Initialize Azure Graph provider (only if enabled)
144
+ if (config.azure.enabled && config.azure.tenantId && config.azure.clientId && config.azure.clientSecret) {
145
+ this.graphProvider = new GraphProvider({
146
+ tenantId: config.azure.tenantId,
147
+ clientId: config.azure.clientId,
148
+ clientSecret: config.azure.clientSecret,
149
+ });
150
+ this.logger.debug('Azure Graph provider initialized', {
151
+ tenantId: config.azure.tenantId,
152
+ clientId: config.azure.clientId,
153
+ });
154
+ } else {
155
+ this.logger.info('Azure provider disabled (AZURE_ENABLED=false or missing credentials)');
156
+ }
157
+
158
+ // 7. Initialize controllers
159
+ this.healthController = new HealthController();
160
+ this.authController = new AuthController(this.tokenService, config.jwt);
161
+ this.auditController = new AuditController();
162
+ this.exportController = new ExportController();
163
+ this.providersController = new ProvidersController(config.ldap, config.azure, this.graphProvider);
164
+ this.logger.debug('Controllers initialized');
165
+
166
+ // 8. Store config for routes
167
+ this.infoEndpointsConfig = config.infoEndpoints;
168
+
169
+ this.logger.info('DI container initialization complete');
170
+ }
171
+
172
+ // === Getters ===
173
+
174
+ getDatabase(): Database.Database {
175
+ return this.db;
176
+ }
177
+
178
+ getTokenRepository(): TokenRepository {
179
+ return this.tokenRepository;
180
+ }
181
+
182
+ getCryptoService(): CryptoService {
183
+ return this.cryptoService;
184
+ }
185
+
186
+ getTokenService(): TokenService {
187
+ return this.tokenService;
188
+ }
189
+
190
+ getLDAPProvider(): LDAPProvider {
191
+ return this.ldapProvider;
192
+ }
193
+
194
+ getGraphProvider(): GraphProvider {
195
+ return this.graphProvider;
196
+ }
197
+
198
+ getHealthController(): HealthController {
199
+ return this.healthController;
200
+ }
201
+
202
+ getAuthController(): AuthController {
203
+ return this.authController;
204
+ }
205
+
206
+ getAuditController(): AuditController {
207
+ return this.auditController;
208
+ }
209
+
210
+ getExportController(): ExportController {
211
+ return this.exportController;
212
+ }
213
+
214
+ getProvidersController(): ProvidersController {
215
+ return this.providersController;
216
+ }
217
+
218
+ getInfoEndpointsConfig(): InfoEndpointsConfig {
219
+ return this.infoEndpointsConfig;
220
+ }
221
+ }
File without changes
@@ -0,0 +1,78 @@
1
+ import Database from 'better-sqlite3';
2
+ import { mkdirSync, existsSync } from 'fs';
3
+ import { dirname } from 'path';
4
+ import { logInfo, logError } from '../utils/logger';
5
+
6
+ /**
7
+ * SQLite Database Connection Manager
8
+ * Singleton pattern for database access
9
+ */
10
+ export class DatabaseManager {
11
+ private static instance: DatabaseManager;
12
+ private db: Database.Database | null = null;
13
+ private dbPath: string | null = null;
14
+
15
+ private constructor() {}
16
+
17
+ static getInstance(): DatabaseManager {
18
+ if (!DatabaseManager.instance) {
19
+ DatabaseManager.instance = new DatabaseManager();
20
+ }
21
+ return DatabaseManager.instance;
22
+ }
23
+
24
+ connect(dbPath: string): Database.Database {
25
+ if (this.db) {
26
+ return this.db;
27
+ }
28
+
29
+ try {
30
+ // Create parent directory if not exists
31
+ const dir = dirname(dbPath);
32
+ if (!existsSync(dir)) {
33
+ mkdirSync(dir, { recursive: true });
34
+ logInfo('Created database directory', { path: dir });
35
+ }
36
+
37
+ // Connect to database
38
+ this.db = new Database(dbPath);
39
+ this.dbPath = dbPath;
40
+
41
+ // Configure pragmas for performance and safety
42
+ this.db.pragma('journal_mode = WAL'); // Write-Ahead Logging
43
+ this.db.pragma('synchronous = NORMAL'); // Balance safety/performance
44
+ this.db.pragma('foreign_keys = ON'); // Enable foreign key constraints
45
+ this.db.pragma('busy_timeout = 5000'); // 5 second timeout on locks
46
+
47
+ logInfo('Database connected successfully', {
48
+ path: dbPath,
49
+ journalMode: this.db.pragma('journal_mode', { simple: true }),
50
+ });
51
+
52
+ return this.db;
53
+ } catch (error) {
54
+ logError('Failed to connect to database', error as Error, { path: dbPath });
55
+ throw error;
56
+ }
57
+ }
58
+
59
+ getDatabase(): Database.Database {
60
+ if (!this.db) {
61
+ throw new Error('Database not connected. Call connect() first.');
62
+ }
63
+ return this.db;
64
+ }
65
+
66
+ close(): void {
67
+ if (this.db) {
68
+ logInfo('Closing database connection', { path: this.dbPath });
69
+ this.db.close();
70
+ this.db = null;
71
+ this.dbPath = null;
72
+ }
73
+ }
74
+
75
+ isConnected(): boolean {
76
+ return this.db !== null;
77
+ }
78
+ }
@@ -0,0 +1,166 @@
1
+ import { TokenRepository } from '../repositories/token.repository';
2
+ import { logInfo, logError } from '../../utils/logger';
3
+
4
+ /**
5
+ * Token Cleanup Job
6
+ * Removes expired and old revoked tokens according to retention policy
7
+ *
8
+ * Retention Policy:
9
+ * - Expired tokens (expires_at < now): Deleted immediately if not revoked
10
+ * - Expired + Revoked tokens (expires_at < now AND revoked_at < now - 90 days): Deleted after 90 days
11
+ * - Active tokens: Never deleted
12
+ *
13
+ * This job should be scheduled to run periodically (e.g., daily at 3 AM)
14
+ */
15
+ export class TokenCleanupJob {
16
+ constructor(private tokenRepo: TokenRepository) {}
17
+
18
+ /**
19
+ * Execute the cleanup job
20
+ * @returns Number of tokens deleted
21
+ */
22
+ run(): number {
23
+ logInfo('Starting token cleanup job');
24
+
25
+ try {
26
+ const before = this.tokenRepo.count();
27
+
28
+ // Delete expired tokens (90-day retention for revoked)
29
+ const deletedCount = this.deleteExpiredTokens();
30
+
31
+ const after = this.tokenRepo.count();
32
+
33
+ logInfo('Token cleanup job completed', {
34
+ tokensBefore: before,
35
+ tokensAfter: after,
36
+ deletedCount,
37
+ });
38
+
39
+ return deletedCount;
40
+ } catch (error) {
41
+ logError('Token cleanup job failed', error as Error);
42
+ throw error;
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Delete expired tokens with 90-day retention for revoked tokens
48
+ * @private
49
+ * @returns Number of tokens deleted
50
+ */
51
+ private deleteExpiredTokens(): number {
52
+ // Query deletes:
53
+ // 1. Non-revoked expired tokens (cleanup immediately)
54
+ // 2. Revoked tokens that expired AND were revoked > 90 days ago (retain for audit)
55
+ const stmt = this.tokenRepo['db'].prepare(`
56
+ DELETE FROM tokens
57
+ WHERE datetime(expires_at) <= datetime('now')
58
+ AND (
59
+ revoked_at IS NULL
60
+ OR datetime(revoked_at) <= datetime('now', '-90 days')
61
+ )
62
+ `);
63
+
64
+ const result = stmt.run();
65
+ const deletedCount = result.changes;
66
+
67
+ if (deletedCount > 0) {
68
+ logInfo('Deleted expired tokens', { count: deletedCount });
69
+ } else {
70
+ logInfo('No expired tokens to delete');
71
+ }
72
+
73
+ return deletedCount;
74
+ }
75
+
76
+ /**
77
+ * Get cleanup statistics without deleting anything
78
+ * Useful for monitoring and alerting
79
+ * @returns Cleanup statistics
80
+ */
81
+ getStatistics(): CleanupStatistics {
82
+ const db = this.tokenRepo['db'];
83
+
84
+ // Count expired non-revoked tokens (immediate deletion candidates)
85
+ const expiredNonRevoked = db
86
+ .prepare(`
87
+ SELECT COUNT(*) as count FROM tokens
88
+ WHERE datetime(expires_at) <= datetime('now')
89
+ AND revoked_at IS NULL
90
+ `)
91
+ .get() as { count: number };
92
+
93
+ // Count old revoked expired tokens (deletion candidates after 90 days)
94
+ const oldRevokedExpired = db
95
+ .prepare(`
96
+ SELECT COUNT(*) as count FROM tokens
97
+ WHERE datetime(expires_at) <= datetime('now')
98
+ AND revoked_at IS NOT NULL
99
+ AND datetime(revoked_at) <= datetime('now', '-90 days')
100
+ `)
101
+ .get() as { count: number };
102
+
103
+ // Count recent revoked expired tokens (retained for audit, < 90 days)
104
+ const recentRevokedExpired = db
105
+ .prepare(`
106
+ SELECT COUNT(*) as count FROM tokens
107
+ WHERE datetime(expires_at) <= datetime('now')
108
+ AND revoked_at IS NOT NULL
109
+ AND datetime(revoked_at) > datetime('now', '-90 days')
110
+ `)
111
+ .get() as { count: number };
112
+
113
+ const totalDeletionCandidates = expiredNonRevoked.count + oldRevokedExpired.count;
114
+
115
+ const stats: CleanupStatistics = {
116
+ totalTokens: this.tokenRepo.count(),
117
+ activeTokens: this.tokenRepo.countActive(),
118
+ expiredNonRevoked: expiredNonRevoked.count,
119
+ oldRevokedExpired: oldRevokedExpired.count,
120
+ recentRevokedExpired: recentRevokedExpired.count,
121
+ totalDeletionCandidates,
122
+ };
123
+
124
+ logInfo('Token cleanup statistics', stats as unknown as Record<string, unknown>);
125
+
126
+ return stats;
127
+ }
128
+
129
+ /**
130
+ * Run cleanup job and return statistics
131
+ * Combines cleanup and reporting in one operation
132
+ * @returns Cleanup result with statistics
133
+ */
134
+ runWithStatistics(): CleanupResult {
135
+ const statsBefore = this.getStatistics();
136
+ const deletedCount = this.run();
137
+ const statsAfter = this.getStatistics();
138
+
139
+ return {
140
+ deletedCount,
141
+ statsBefore,
142
+ statsAfter,
143
+ };
144
+ }
145
+ }
146
+
147
+ /**
148
+ * Token cleanup statistics
149
+ */
150
+ export interface CleanupStatistics {
151
+ totalTokens: number;
152
+ activeTokens: number;
153
+ expiredNonRevoked: number; // Immediate deletion candidates
154
+ oldRevokedExpired: number; // Deletion candidates after 90 days
155
+ recentRevokedExpired: number; // Retained for audit (< 90 days)
156
+ totalDeletionCandidates: number; // Sum of immediate + old revoked
157
+ }
158
+
159
+ /**
160
+ * Cleanup job result
161
+ */
162
+ export interface CleanupResult {
163
+ deletedCount: number;
164
+ statsBefore: CleanupStatistics;
165
+ statsAfter: CleanupStatistics;
166
+ }
File without changes
@@ -0,0 +1,47 @@
1
+ -- Initial Schema Migration
2
+ -- Creates tokens table for JWT token management with constraints and views
3
+
4
+ -- Tokens table
5
+ CREATE TABLE IF NOT EXISTS tokens (
6
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
7
+ jti TEXT UNIQUE NOT NULL,
8
+ public_key TEXT NOT NULL,
9
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
10
+ expires_at TEXT NOT NULL,
11
+ max_uses INTEGER NOT NULL DEFAULT 0,
12
+ used_count INTEGER NOT NULL DEFAULT 0,
13
+ revoked_at TEXT,
14
+ revoked_by TEXT,
15
+ revoked_reason TEXT,
16
+ metadata TEXT,
17
+ CONSTRAINT check_usage CHECK (used_count <= max_uses OR max_uses = 0),
18
+ CONSTRAINT check_dates CHECK (datetime(expires_at) > datetime(created_at))
19
+ );
20
+
21
+ -- Indexes for performance
22
+ CREATE INDEX IF NOT EXISTS idx_tokens_jti ON tokens(jti);
23
+ CREATE INDEX IF NOT EXISTS idx_tokens_expires_at ON tokens(expires_at);
24
+ CREATE INDEX IF NOT EXISTS idx_tokens_revoked_at ON tokens(revoked_at);
25
+ CREATE INDEX IF NOT EXISTS idx_tokens_created_at ON tokens(created_at);
26
+
27
+ -- Partial index for active tokens (optimization)
28
+ CREATE INDEX IF NOT EXISTS idx_tokens_expired
29
+ ON tokens(expires_at)
30
+ WHERE revoked_at IS NULL;
31
+
32
+ -- View for active tokens
33
+ CREATE VIEW IF NOT EXISTS v_active_tokens AS
34
+ SELECT
35
+ id,
36
+ jti,
37
+ created_at,
38
+ expires_at,
39
+ max_uses,
40
+ used_count,
41
+ CASE
42
+ WHEN max_uses = 0 THEN -1
43
+ ELSE (max_uses - used_count)
44
+ END AS remaining_uses
45
+ FROM tokens
46
+ WHERE revoked_at IS NULL
47
+ AND datetime(expires_at) > datetime('now');
@@ -0,0 +1,125 @@
1
+ import { readFileSync, readdirSync } from 'fs';
2
+ import { join } from 'path';
3
+ import Database from 'better-sqlite3';
4
+ import { logInfo, logError } from '../../utils/logger';
5
+
6
+ /**
7
+ * Migration Runner
8
+ * Executes SQL migration files sequentially with version tracking
9
+ */
10
+ export class MigrationRunner {
11
+ constructor(private db: Database.Database) {}
12
+
13
+ async run(): Promise<void> {
14
+ try {
15
+ logInfo('Starting database migrations');
16
+
17
+ // Create migrations tracking table
18
+ this.createMigrationsTable();
19
+
20
+ // Get current version
21
+ const currentVersion = this.getCurrentVersion();
22
+ logInfo('Current migration version', { version: currentVersion });
23
+
24
+ // Find all migration files
25
+ const migrations = this.findMigrationFiles();
26
+
27
+ // Apply pending migrations
28
+ let appliedCount = 0;
29
+ for (const migration of migrations) {
30
+ if (migration.version > currentVersion) {
31
+ this.applyMigration(migration);
32
+ appliedCount++;
33
+ }
34
+ }
35
+
36
+ if (appliedCount === 0) {
37
+ logInfo('No pending migrations');
38
+ } else {
39
+ logInfo('Migrations completed', { appliedCount });
40
+ }
41
+ } catch (error) {
42
+ logError('Migration failed', error as Error);
43
+ throw error;
44
+ }
45
+ }
46
+
47
+ private createMigrationsTable(): void {
48
+ this.db.exec(`
49
+ CREATE TABLE IF NOT EXISTS migrations (
50
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
51
+ version INTEGER UNIQUE NOT NULL,
52
+ name TEXT NOT NULL,
53
+ applied_at TEXT NOT NULL DEFAULT (datetime('now'))
54
+ );
55
+ `);
56
+ }
57
+
58
+ private getCurrentVersion(): number {
59
+ const result = this.db
60
+ .prepare('SELECT COALESCE(MAX(version), 0) as version FROM migrations')
61
+ .get() as { version: number };
62
+ return result.version;
63
+ }
64
+
65
+ private findMigrationFiles(): Array<{ version: number; name: string; path: string }> {
66
+ const migrationsDir = __dirname;
67
+ const files = readdirSync(migrationsDir).filter((f) => f.endsWith('.sql'));
68
+
69
+ return files
70
+ .map((file) => ({
71
+ version: this.getMigrationVersion(file),
72
+ name: file,
73
+ path: join(migrationsDir, file),
74
+ }))
75
+ .sort((a, b) => a.version - b.version);
76
+ }
77
+
78
+ private getMigrationVersion(filename: string): number {
79
+ const match = filename.match(/^(\d+)_/);
80
+ if (!match || !match[1]) {
81
+ throw new Error(`Invalid migration filename: ${filename}`);
82
+ }
83
+ return parseInt(match[1], 10);
84
+ }
85
+
86
+ private applyMigration(migration: { version: number; name: string; path: string }): void {
87
+ logInfo('Applying migration', { name: migration.name, version: migration.version });
88
+
89
+ // Wrap in transaction for atomicity
90
+ const apply = this.db.transaction(() => {
91
+ try {
92
+ // Read and execute SQL
93
+ const sql = readFileSync(migration.path, 'utf-8');
94
+ this.db.exec(sql);
95
+
96
+ // Record migration
97
+ this.db
98
+ .prepare('INSERT INTO migrations (version, name) VALUES (?, ?)')
99
+ .run(migration.version, migration.name);
100
+
101
+ logInfo('Migration applied successfully', { name: migration.name });
102
+ } catch (error) {
103
+ logError('Migration failed', error as Error, { name: migration.name });
104
+ throw error;
105
+ }
106
+ });
107
+
108
+ apply();
109
+ }
110
+
111
+ /**
112
+ * Static helper for running migrations from config
113
+ */
114
+ static async runMigrations(dbPath: string): Promise<void> {
115
+ const Database = (await import('better-sqlite3')).default;
116
+ const db = new Database(dbPath);
117
+
118
+ try {
119
+ const runner = new MigrationRunner(db);
120
+ await runner.run();
121
+ } finally {
122
+ db.close();
123
+ }
124
+ }
125
+ }
File without changes
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Token Model
3
+ * Represents a JWT token in the database
4
+ */
5
+ export interface Token {
6
+ id: number;
7
+ jti: string;
8
+ public_key: string;
9
+ created_at: string;
10
+ expires_at: string;
11
+ max_uses: number;
12
+ used_count: number;
13
+ revoked_at: string | null;
14
+ revoked_by: string | null;
15
+ revoked_reason: string | null;
16
+ metadata: string | null;
17
+ }
18
+
19
+ export interface TokenCreateInput {
20
+ jti: string;
21
+ public_key: string;
22
+ expires_at: string;
23
+ max_uses?: number;
24
+ metadata?: string;
25
+ }
26
+
27
+ export interface ActiveToken {
28
+ id: number;
29
+ jti: string;
30
+ created_at: string;
31
+ expires_at: string;
32
+ max_uses: number;
33
+ used_count: number;
34
+ remaining_uses: number;
35
+ }
File without changes