@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,273 @@
1
+ /**
2
+ * LDAP Injection Prevention
3
+ *
4
+ * Sanitizes LDAP filters and Distinguished Names to prevent injection attacks.
5
+ * Follows OWASP guidelines and RFC 4515 (LDAP filters) / RFC 4514 (DNs).
6
+ *
7
+ * Task 2: Implement LDAP Sanitizer for Injection Prevention (Story 1.5)
8
+ */
9
+
10
+ /**
11
+ * LDAP Sanitizer
12
+ *
13
+ * Provides methods to sanitize and validate LDAP inputs.
14
+ */
15
+ export class LDAPSanitizer {
16
+ /**
17
+ * LDAP filter special characters that require escaping (RFC 4515)
18
+ */
19
+ private static readonly FILTER_ESCAPE_MAP: Record<string, string> = {
20
+ '\\': '\\5c', // Backslash (must be first)
21
+ '*': '\\2a', // Asterisk
22
+ '(': '\\28', // Left parenthesis
23
+ ')': '\\29', // Right parenthesis
24
+ '\0': '\\00', // NUL character
25
+ };
26
+
27
+ /**
28
+ * DN special characters that require escaping (RFC 4514)
29
+ */
30
+ private static readonly DN_SPECIAL_CHARS = [',', '=', '+', '<', '>', '#', ';', '\\', '"'];
31
+
32
+ /**
33
+ * Sanitize LDAP filter string to prevent injection attacks
34
+ *
35
+ * Escapes special characters in LDAP filter values according to RFC 4515.
36
+ * This prevents attackers from injecting malicious filter logic.
37
+ *
38
+ * @param filter - The filter string to sanitize
39
+ * @returns Sanitized filter string with escaped special characters
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * // Prevents injection: (uid=*)(objectClass=*)
44
+ * LDAPSanitizer.sanitizeFilter("*)(objectClass=*")
45
+ * // Returns: "\2a\29\28objectClass=\2a"
46
+ * ```
47
+ */
48
+ static sanitizeFilter(filter: string): string {
49
+ if (!filter) {
50
+ return filter;
51
+ }
52
+
53
+ let sanitized = filter;
54
+
55
+ // Process in specific order: backslash first to avoid double-escaping
56
+ for (const [char, escape] of Object.entries(this.FILTER_ESCAPE_MAP)) {
57
+ sanitized = sanitized.split(char).join(escape);
58
+ }
59
+
60
+ return sanitized;
61
+ }
62
+
63
+ /**
64
+ * Sanitize Distinguished Name (DN) to prevent injection
65
+ *
66
+ * Escapes special characters in DN components according to RFC 4514.
67
+ * Handles leading/trailing spaces and special character positions.
68
+ *
69
+ * @param dn - The DN string to sanitize
70
+ * @returns Sanitized DN string with properly escaped characters
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * LDAPSanitizer.sanitizeDN('cn=John, Doe')
75
+ * // Returns: "cn=John\\, Doe"
76
+ * ```
77
+ */
78
+ static sanitizeDN(dn: string): string {
79
+ if (!dn) {
80
+ return dn;
81
+ }
82
+
83
+ let sanitized = dn;
84
+
85
+ // Escape backslash first to prevent double-escaping
86
+ sanitized = sanitized.replace(/\\/g, '\\\\');
87
+
88
+ // Escape other special characters
89
+ for (const char of this.DN_SPECIAL_CHARS) {
90
+ if (char === '\\') continue; // Already handled
91
+ const regex = new RegExp(`\\${char}`, 'g');
92
+ sanitized = sanitized.replace(regex, `\\${char}`);
93
+ }
94
+
95
+ // Escape leading space
96
+ if (sanitized.startsWith(' ')) {
97
+ sanitized = '\\' + sanitized;
98
+ }
99
+
100
+ // Escape trailing space
101
+ if (sanitized.endsWith(' ') && !sanitized.endsWith('\\ ')) {
102
+ sanitized = sanitized.slice(0, -1) + '\\ ';
103
+ }
104
+
105
+ // Escape leading # (hash)
106
+ if (sanitized.startsWith('#')) {
107
+ sanitized = '\\' + sanitized;
108
+ }
109
+
110
+ return sanitized;
111
+ }
112
+
113
+ /**
114
+ * Validate LDAP filter syntax
115
+ *
116
+ * Checks if an LDAP filter has valid syntax:
117
+ * - Balanced parentheses
118
+ * - Valid operators (&, |, !)
119
+ * - Proper filter structure
120
+ *
121
+ * @param filter - The filter to validate
122
+ * @returns true if filter syntax is valid, false otherwise
123
+ *
124
+ * @example
125
+ * ```typescript
126
+ * LDAPSanitizer.isValidFilter('(uid=john)') // true
127
+ * LDAPSanitizer.isValidFilter('(uid=john') // false - unbalanced
128
+ * LDAPSanitizer.isValidFilter('uid=john') // false - missing parens
129
+ * ```
130
+ */
131
+ static isValidFilter(filter: string): boolean {
132
+ if (!filter || typeof filter !== 'string') {
133
+ return false;
134
+ }
135
+
136
+ // Filter must start and end with parentheses
137
+ if (!filter.startsWith('(') || !filter.endsWith(')')) {
138
+ return false;
139
+ }
140
+
141
+ // Check balanced parentheses
142
+ let depth = 0;
143
+ for (const char of filter) {
144
+ if (char === '(') {
145
+ depth++;
146
+ } else if (char === ')') {
147
+ depth--;
148
+ }
149
+ // Depth should never go negative
150
+ if (depth < 0) {
151
+ return false;
152
+ }
153
+ }
154
+
155
+ // Must end with depth 0 (balanced)
156
+ if (depth !== 0) {
157
+ return false;
158
+ }
159
+
160
+ // Basic structure validation: must contain at least one operator or attribute
161
+ // Valid filters: (&(...)), (|(...)), (!(...)), or (attribute=value)
162
+ const hasLogicalOp = /^(\(&|\(\||\(!)/.test(filter);
163
+ const hasAttribute = /\w+=/.test(filter);
164
+
165
+ if (!hasLogicalOp && !hasAttribute) {
166
+ return false;
167
+ }
168
+
169
+ return true;
170
+ }
171
+
172
+ /**
173
+ * Validate Distinguished Name (DN) format
174
+ *
175
+ * Checks if a DN has valid structure:
176
+ * - Contains attribute=value pairs
177
+ * - Properly formatted with commas
178
+ *
179
+ * @param dn - The DN to validate
180
+ * @returns true if DN format is valid, false otherwise
181
+ *
182
+ * @example
183
+ * ```typescript
184
+ * LDAPSanitizer.isValidDN('cn=John Doe,ou=Users,dc=example,dc=com') // true
185
+ * LDAPSanitizer.isValidDN('invalid-dn') // false
186
+ * ```
187
+ */
188
+ static isValidDN(dn: string): boolean {
189
+ if (!dn || typeof dn !== 'string') {
190
+ return false;
191
+ }
192
+
193
+ // DN must contain at least one attribute=value pair
194
+ const dnPattern = /^([a-zA-Z][a-zA-Z0-9-]*=[^,]+)(,\s*[a-zA-Z][a-zA-Z0-9-]*=[^,]+)*$/;
195
+ return dnPattern.test(dn.trim());
196
+ }
197
+
198
+ /**
199
+ * Sanitize LDAP attribute name
200
+ *
201
+ * Ensures attribute name only contains valid characters.
202
+ * Attribute names should only contain alphanumeric characters, hyphens, and dots.
203
+ *
204
+ * @param attribute - The attribute name to sanitize
205
+ * @returns Sanitized attribute name or empty string if invalid
206
+ */
207
+ static sanitizeAttribute(attribute: string): string {
208
+ if (!attribute || typeof attribute !== 'string') {
209
+ return '';
210
+ }
211
+
212
+ // Remove any characters that aren't alphanumeric, hyphen, or dot
213
+ return attribute.replace(/[^a-zA-Z0-9.-]/g, '');
214
+ }
215
+
216
+ /**
217
+ * Build safe LDAP filter from components
218
+ *
219
+ * Constructs an LDAP filter with properly sanitized values.
220
+ * Use this instead of string concatenation to build filters.
221
+ *
222
+ * @param attribute - Attribute name
223
+ * @param operator - Comparison operator (=, >=, <=, ~=)
224
+ * @param value - Value to filter by (will be sanitized)
225
+ * @returns Safe LDAP filter string
226
+ *
227
+ * @example
228
+ * ```typescript
229
+ * LDAPSanitizer.buildFilter('uid', '=', 'john*')
230
+ * // Returns: "(uid=john\\2a)"
231
+ * ```
232
+ */
233
+ static buildFilter(
234
+ attribute: string,
235
+ operator: '=' | '>=' | '<=' | '~=' | '=*',
236
+ value: string
237
+ ): string {
238
+ const safeAttribute = this.sanitizeAttribute(attribute);
239
+ const safeValue = operator === '=*' ? value : this.sanitizeFilter(value);
240
+
241
+ return `(${safeAttribute}${operator}${safeValue})`;
242
+ }
243
+
244
+ /**
245
+ * Build safe logical filter (AND/OR/NOT)
246
+ *
247
+ * Combines multiple filters with logical operators.
248
+ *
249
+ * @param operator - Logical operator (&, |, !)
250
+ * @param filters - Array of filter strings to combine
251
+ * @returns Combined filter string
252
+ *
253
+ * @example
254
+ * ```typescript
255
+ * LDAPSanitizer.buildLogicalFilter('&', [
256
+ * '(objectClass=user)',
257
+ * '(uid=john)',
258
+ * ])
259
+ * // Returns: "(&(objectClass=user)(uid=john))"
260
+ * ```
261
+ */
262
+ static buildLogicalFilter(operator: '&' | '|' | '!', filters: string[]): string {
263
+ if (!filters || filters.length === 0) {
264
+ return '';
265
+ }
266
+
267
+ if (operator === '!' && filters.length !== 1) {
268
+ throw new Error('NOT operator requires exactly one filter');
269
+ }
270
+
271
+ return `(${operator}${filters.join('')})`;
272
+ }
273
+ }
@@ -0,0 +1,293 @@
1
+ import { ILDAPProvider, SearchOptions, ConnectionTestResult } from '../interfaces/ILDAPProvider';
2
+ import { ADUser, ADGroup, ADComputer, ADOU } from '../../types/ad.types';
3
+ import { LDAPConfig } from '../../types/config.types';
4
+ import { LDAPClient, LDAPConnectionOptions } from './ldap-client';
5
+ import { LDAPSanitizer } from './ldap-sanitizer';
6
+ import { mapToADUser, mapToADGroup, mapToADComputer, mapToADOU, mapToGeneric } from './ad-mappers';
7
+ import { logger } from '../../utils/logger';
8
+
9
+ /**
10
+ * LDAP Provider Implementation
11
+ *
12
+ * Provides Active Directory connectivity via LDAP/LDAPS.
13
+ * Implements all LDAP operations with sanitization and type mapping.
14
+ *
15
+ * Task 3: Implement LDAP Provider (Story 1.5)
16
+ */
17
+ export class LDAPProvider implements ILDAPProvider {
18
+ private client: LDAPClient;
19
+ private config: LDAPConfig;
20
+
21
+ /**
22
+ * Get base DN for searches
23
+ */
24
+ getBaseDN(): string {
25
+ return this.config.baseDN;
26
+ }
27
+
28
+ /**
29
+ * Get LDAP URL (for debugging)
30
+ */
31
+ getUrl(): string {
32
+ return this.config.url;
33
+ }
34
+
35
+ constructor(config: LDAPConfig) {
36
+ this.config = config;
37
+
38
+ // Create client with connection options
39
+ const connectionOptions: LDAPConnectionOptions = {
40
+ url: config.url,
41
+ bindDN: config.bindDN,
42
+ bindPassword: config.bindPassword,
43
+ timeout: config.timeout,
44
+ caCertPath: config.caCertPath,
45
+ tlsOptions: {
46
+ rejectUnauthorized: config.tlsVerify,
47
+ },
48
+ skipHostnameVerification: config.skipHostnameVerification,
49
+ tlsServername: config.tlsServername,
50
+ };
51
+
52
+ this.client = new LDAPClient(connectionOptions);
53
+ }
54
+
55
+ /**
56
+ * Connect and bind to LDAP server
57
+ */
58
+ async connect(): Promise<void> {
59
+ logger.info('Connecting to LDAP server...');
60
+ await this.client.connect();
61
+ }
62
+
63
+ /**
64
+ * Disconnect from LDAP server
65
+ */
66
+ async disconnect(): Promise<void> {
67
+ logger.info('Disconnecting from LDAP server...');
68
+ await this.client.disconnect();
69
+ }
70
+
71
+ /**
72
+ * Test LDAP connection
73
+ */
74
+ async testConnection(): Promise<ConnectionTestResult> {
75
+ logger.info('Testing LDAP connection...');
76
+
77
+ const result = await this.client.testConnection();
78
+
79
+ if (result.success) {
80
+ // Determine protocol from URL
81
+ const protocol = this.config.url.startsWith('ldaps://') ? 'ldaps' : 'ldap';
82
+
83
+ return {
84
+ success: true,
85
+ message: 'Connection successful',
86
+ details: {
87
+ url: this.config.url,
88
+ baseDN: this.config.baseDN,
89
+ protocol,
90
+ bindDN: this.config.bindDN,
91
+ responseTime: result.responseTime,
92
+ },
93
+ };
94
+ } else {
95
+ return {
96
+ success: false,
97
+ message: 'Connection failed',
98
+ };
99
+ }
100
+ }
101
+
102
+ /**
103
+ * Search for users in Active Directory
104
+ *
105
+ * Default filter: (&(objectClass=user)(objectCategory=person))
106
+ */
107
+ async searchUsers(filter?: string, attributes?: string[]): Promise<ADUser[]> {
108
+ // Build filter with sanitization
109
+ const userFilter = filter
110
+ ? `(&(objectClass=user)(objectCategory=person)${filter})`
111
+ : '(&(objectClass=user)(objectCategory=person))';
112
+
113
+ logger.debug(`Searching for users with filter: ${userFilter}`);
114
+
115
+ // Default attributes for users
116
+ const defaultAttributes = [
117
+ 'dn',
118
+ 'sAMAccountName',
119
+ 'userPrincipalName',
120
+ 'displayName',
121
+ 'userAccountControl',
122
+ 'pwdLastSet',
123
+ 'lastLogon',
124
+ 'adminCount',
125
+ 'memberOf',
126
+ ];
127
+
128
+ const searchOptions: SearchOptions = {
129
+ filter: userFilter,
130
+ scope: 'sub',
131
+ attributes: attributes || defaultAttributes,
132
+ paged: true,
133
+ };
134
+
135
+ const entries = await this.client.search(this.config.baseDN, searchOptions);
136
+
137
+ // Map entries to ADUser objects
138
+ return entries.map(mapToADUser);
139
+ }
140
+
141
+ /**
142
+ * Search for groups in Active Directory
143
+ *
144
+ * Default filter: (objectClass=group)
145
+ */
146
+ async searchGroups(filter?: string, attributes?: string[]): Promise<ADGroup[]> {
147
+ // Build filter
148
+ const groupFilter = filter ? `(&(objectClass=group)${filter})` : '(objectClass=group)';
149
+
150
+ logger.debug(`Searching for groups with filter: ${groupFilter}`);
151
+
152
+ // Default attributes for groups
153
+ const defaultAttributes = [
154
+ 'dn',
155
+ 'sAMAccountName',
156
+ 'displayName',
157
+ 'groupType',
158
+ 'memberOf',
159
+ 'member',
160
+ ];
161
+
162
+ const searchOptions: SearchOptions = {
163
+ filter: groupFilter,
164
+ scope: 'sub',
165
+ attributes: attributes || defaultAttributes,
166
+ paged: true,
167
+ };
168
+
169
+ const entries = await this.client.search(this.config.baseDN, searchOptions);
170
+
171
+ // Map entries to ADGroup objects
172
+ return entries.map(mapToADGroup);
173
+ }
174
+
175
+ /**
176
+ * Search for computers in Active Directory
177
+ *
178
+ * Default filter: (objectClass=computer)
179
+ */
180
+ async searchComputers(filter?: string, attributes?: string[]): Promise<ADComputer[]> {
181
+ // Build filter
182
+ const computerFilter = filter ? `(&(objectClass=computer)${filter})` : '(objectClass=computer)';
183
+
184
+ logger.debug(`Searching for computers with filter: ${computerFilter}`);
185
+
186
+ // Default attributes for computers
187
+ const defaultAttributes = [
188
+ 'dn',
189
+ 'sAMAccountName',
190
+ 'dNSHostName',
191
+ 'operatingSystem',
192
+ 'operatingSystemVersion',
193
+ 'lastLogon',
194
+ 'userAccountControl',
195
+ ];
196
+
197
+ const searchOptions: SearchOptions = {
198
+ filter: computerFilter,
199
+ scope: 'sub',
200
+ attributes: attributes || defaultAttributes,
201
+ paged: true,
202
+ };
203
+
204
+ const entries = await this.client.search(this.config.baseDN, searchOptions);
205
+
206
+ // Map entries to ADComputer objects
207
+ return entries.map(mapToADComputer);
208
+ }
209
+
210
+ /**
211
+ * Search for organizational units in Active Directory
212
+ *
213
+ * Default filter: (objectClass=organizationalUnit)
214
+ */
215
+ async searchOUs(filter?: string, attributes?: string[]): Promise<ADOU[]> {
216
+ // Build filter
217
+ const ouFilter = filter
218
+ ? `(&(objectClass=organizationalUnit)${filter})`
219
+ : '(objectClass=organizationalUnit)';
220
+
221
+ logger.debug(`Searching for OUs with filter: ${ouFilter}`);
222
+
223
+ // Default attributes for OUs
224
+ const defaultAttributes = ['dn', 'name', 'ou', 'description'];
225
+
226
+ const searchOptions: SearchOptions = {
227
+ filter: ouFilter,
228
+ scope: 'sub',
229
+ attributes: attributes || defaultAttributes,
230
+ paged: true,
231
+ };
232
+
233
+ const entries = await this.client.search(this.config.baseDN, searchOptions);
234
+
235
+ // Map entries to ADOU objects
236
+ return entries.map(mapToADOU);
237
+ }
238
+
239
+ /**
240
+ * Generic LDAP search
241
+ *
242
+ * Performs a low-level LDAP search with custom base DN and options.
243
+ */
244
+ async search<T>(baseDN: string, options: SearchOptions): Promise<T[]> {
245
+ logger.debug(`Generic LDAP search: baseDN=${baseDN}, filter=${options.filter}`);
246
+
247
+ // Validate filter syntax
248
+ if (!LDAPSanitizer.isValidFilter(options.filter)) {
249
+ throw new Error(`Invalid LDAP filter syntax: ${options.filter}`);
250
+ }
251
+
252
+ // Validate base DN
253
+ if (!LDAPSanitizer.isValidDN(baseDN)) {
254
+ throw new Error(`Invalid LDAP DN: ${baseDN}`);
255
+ }
256
+
257
+ const entries = await this.client.search(baseDN, options);
258
+
259
+ // Map to generic objects
260
+ return entries.map((entry) => mapToGeneric(entry) as T);
261
+ }
262
+
263
+ /**
264
+ * Build a safe LDAP filter
265
+ *
266
+ * Utility method to build filters with sanitization.
267
+ *
268
+ * @param attribute - Attribute name
269
+ * @param operator - Comparison operator
270
+ * @param value - Value to filter by (will be sanitized)
271
+ * @returns Safe LDAP filter
272
+ */
273
+ buildSafeFilter(
274
+ attribute: string,
275
+ operator: '=' | '>=' | '<=' | '~=' | '=*',
276
+ value: string
277
+ ): string {
278
+ return LDAPSanitizer.buildFilter(attribute, operator, value);
279
+ }
280
+
281
+ /**
282
+ * Build a logical filter (AND/OR/NOT)
283
+ *
284
+ * Utility method to combine multiple filters.
285
+ *
286
+ * @param operator - Logical operator
287
+ * @param filters - Array of filter strings
288
+ * @returns Combined filter
289
+ */
290
+ buildLogicalFilter(operator: '&' | '|' | '!', filters: string[]): string {
291
+ return LDAPSanitizer.buildLogicalFilter(operator, filters);
292
+ }
293
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Predefined LDAP Computer Queries
3
+ * TODO: Full implementation in Story 1.5
4
+ */
5
+ export const ComputerQueries = {
6
+ ALL_COMPUTERS: '(objectClass=computer)',
7
+ SERVERS: '(&(objectClass=computer)(operatingSystem=*Server*))',
8
+ WORKSTATIONS: '(&(objectClass=computer)(!(operatingSystem=*Server*)))',
9
+ };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Predefined LDAP Group Queries
3
+ * TODO: Full implementation in Story 1.5
4
+ */
5
+ export const GroupQueries = {
6
+ ALL_GROUPS: '(objectClass=group)',
7
+ SECURITY_GROUPS: '(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=2147483648))',
8
+ DISTRIBUTION_GROUPS: '(&(objectClass=group)(!(groupType:1.2.840.113556.1.4.803:=2147483648)))',
9
+ };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Predefined LDAP User Queries
3
+ * TODO: Full implementation in Story 1.5
4
+ */
5
+ export const UserQueries = {
6
+ ALL_USERS: '(objectClass=user)',
7
+ ENABLED_USERS: '(&(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))',
8
+ DISABLED_USERS: '(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=2))',
9
+ ADMIN_USERS: '(&(objectClass=user)(adminCount=1))',
10
+ };