@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.
- package/.env.example +60 -0
- package/.env.test.example +33 -0
- package/.github/workflows/ci.yml +83 -0
- package/.github/workflows/release.yml +246 -0
- package/.prettierrc.json +10 -0
- package/CHANGELOG.md +15 -0
- package/Dockerfile +57 -0
- package/LICENSE +190 -0
- package/README.md +194 -0
- package/dist/api/controllers/audit.controller.d.ts +21 -0
- package/dist/api/controllers/audit.controller.d.ts.map +1 -0
- package/dist/api/controllers/audit.controller.js +179 -0
- package/dist/api/controllers/audit.controller.js.map +1 -0
- package/dist/api/controllers/auth.controller.d.ts +16 -0
- package/dist/api/controllers/auth.controller.d.ts.map +1 -0
- package/dist/api/controllers/auth.controller.js +146 -0
- package/dist/api/controllers/auth.controller.js.map +1 -0
- package/dist/api/controllers/export.controller.d.ts +27 -0
- package/dist/api/controllers/export.controller.d.ts.map +1 -0
- package/dist/api/controllers/export.controller.js +80 -0
- package/dist/api/controllers/export.controller.js.map +1 -0
- package/dist/api/controllers/health.controller.d.ts +5 -0
- package/dist/api/controllers/health.controller.d.ts.map +1 -0
- package/dist/api/controllers/health.controller.js +16 -0
- package/dist/api/controllers/health.controller.js.map +1 -0
- package/dist/api/controllers/jobs.controller.d.ts +13 -0
- package/dist/api/controllers/jobs.controller.d.ts.map +1 -0
- package/dist/api/controllers/jobs.controller.js +125 -0
- package/dist/api/controllers/jobs.controller.js.map +1 -0
- package/dist/api/controllers/providers.controller.d.ts +15 -0
- package/dist/api/controllers/providers.controller.d.ts.map +1 -0
- package/dist/api/controllers/providers.controller.js +112 -0
- package/dist/api/controllers/providers.controller.js.map +1 -0
- package/dist/api/dto/AuditRequest.dto.d.ts +6 -0
- package/dist/api/dto/AuditRequest.dto.d.ts.map +1 -0
- package/dist/api/dto/AuditRequest.dto.js +3 -0
- package/dist/api/dto/AuditRequest.dto.js.map +1 -0
- package/dist/api/dto/AuditResponse.dto.d.ts +17 -0
- package/dist/api/dto/AuditResponse.dto.d.ts.map +1 -0
- package/dist/api/dto/AuditResponse.dto.js +3 -0
- package/dist/api/dto/AuditResponse.dto.js.map +1 -0
- package/dist/api/dto/TokenRequest.dto.d.ts +6 -0
- package/dist/api/dto/TokenRequest.dto.d.ts.map +1 -0
- package/dist/api/dto/TokenRequest.dto.js +3 -0
- package/dist/api/dto/TokenRequest.dto.js.map +1 -0
- package/dist/api/dto/TokenResponse.dto.d.ts +12 -0
- package/dist/api/dto/TokenResponse.dto.d.ts.map +1 -0
- package/dist/api/dto/TokenResponse.dto.js +3 -0
- package/dist/api/dto/TokenResponse.dto.js.map +1 -0
- package/dist/api/middlewares/authenticate.d.ts +12 -0
- package/dist/api/middlewares/authenticate.d.ts.map +1 -0
- package/dist/api/middlewares/authenticate.js +141 -0
- package/dist/api/middlewares/authenticate.js.map +1 -0
- package/dist/api/middlewares/errorHandler.d.ts +3 -0
- package/dist/api/middlewares/errorHandler.d.ts.map +1 -0
- package/dist/api/middlewares/errorHandler.js +30 -0
- package/dist/api/middlewares/errorHandler.js.map +1 -0
- package/dist/api/middlewares/rateLimit.d.ts +3 -0
- package/dist/api/middlewares/rateLimit.d.ts.map +1 -0
- package/dist/api/middlewares/rateLimit.js +34 -0
- package/dist/api/middlewares/rateLimit.js.map +1 -0
- package/dist/api/middlewares/validate.d.ts +4 -0
- package/dist/api/middlewares/validate.d.ts.map +1 -0
- package/dist/api/middlewares/validate.js +31 -0
- package/dist/api/middlewares/validate.js.map +1 -0
- package/dist/api/routes/audit.routes.d.ts +5 -0
- package/dist/api/routes/audit.routes.d.ts.map +1 -0
- package/dist/api/routes/audit.routes.js +24 -0
- package/dist/api/routes/audit.routes.js.map +1 -0
- package/dist/api/routes/auth.routes.d.ts +6 -0
- package/dist/api/routes/auth.routes.d.ts.map +1 -0
- package/dist/api/routes/auth.routes.js +22 -0
- package/dist/api/routes/auth.routes.js.map +1 -0
- package/dist/api/routes/export.routes.d.ts +5 -0
- package/dist/api/routes/export.routes.d.ts.map +1 -0
- package/dist/api/routes/export.routes.js +16 -0
- package/dist/api/routes/export.routes.js.map +1 -0
- package/dist/api/routes/health.routes.d.ts +4 -0
- package/dist/api/routes/health.routes.d.ts.map +1 -0
- package/dist/api/routes/health.routes.js +11 -0
- package/dist/api/routes/health.routes.js.map +1 -0
- package/dist/api/routes/index.d.ts +10 -0
- package/dist/api/routes/index.d.ts.map +1 -0
- package/dist/api/routes/index.js +20 -0
- package/dist/api/routes/index.js.map +1 -0
- package/dist/api/routes/providers.routes.d.ts +5 -0
- package/dist/api/routes/providers.routes.d.ts.map +1 -0
- package/dist/api/routes/providers.routes.js +13 -0
- package/dist/api/routes/providers.routes.js.map +1 -0
- package/dist/api/validators/audit.schemas.d.ts +60 -0
- package/dist/api/validators/audit.schemas.d.ts.map +1 -0
- package/dist/api/validators/audit.schemas.js +55 -0
- package/dist/api/validators/audit.schemas.js.map +1 -0
- package/dist/api/validators/auth.schemas.d.ts +17 -0
- package/dist/api/validators/auth.schemas.d.ts.map +1 -0
- package/dist/api/validators/auth.schemas.js +21 -0
- package/dist/api/validators/auth.schemas.js.map +1 -0
- package/dist/app.d.ts +3 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +62 -0
- package/dist/app.js.map +1 -0
- package/dist/config/config.schema.d.ts +65 -0
- package/dist/config/config.schema.d.ts.map +1 -0
- package/dist/config/config.schema.js +95 -0
- package/dist/config/config.schema.js.map +1 -0
- package/dist/config/index.d.ts +4 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +75 -0
- package/dist/config/index.js.map +1 -0
- package/dist/container.d.ts +47 -0
- package/dist/container.d.ts.map +1 -0
- package/dist/container.js +137 -0
- package/dist/container.js.map +1 -0
- package/dist/data/database.d.ts +13 -0
- package/dist/data/database.d.ts.map +1 -0
- package/dist/data/database.js +68 -0
- package/dist/data/database.js.map +1 -0
- package/dist/data/jobs/token-cleanup.job.d.ts +23 -0
- package/dist/data/jobs/token-cleanup.job.d.ts.map +1 -0
- package/dist/data/jobs/token-cleanup.job.js +96 -0
- package/dist/data/jobs/token-cleanup.job.js.map +1 -0
- package/dist/data/migrations/migration.runner.d.ts +13 -0
- package/dist/data/migrations/migration.runner.d.ts.map +1 -0
- package/dist/data/migrations/migration.runner.js +136 -0
- package/dist/data/migrations/migration.runner.js.map +1 -0
- package/dist/data/models/Token.model.d.ts +30 -0
- package/dist/data/models/Token.model.d.ts.map +1 -0
- package/dist/data/models/Token.model.js +3 -0
- package/dist/data/models/Token.model.js.map +1 -0
- package/dist/data/repositories/token.repository.d.ts +16 -0
- package/dist/data/repositories/token.repository.d.ts.map +1 -0
- package/dist/data/repositories/token.repository.js +97 -0
- package/dist/data/repositories/token.repository.js.map +1 -0
- package/dist/providers/azure/auth.provider.d.ts +5 -0
- package/dist/providers/azure/auth.provider.d.ts.map +1 -0
- package/dist/providers/azure/auth.provider.js +13 -0
- package/dist/providers/azure/auth.provider.js.map +1 -0
- package/dist/providers/azure/azure-errors.d.ts +40 -0
- package/dist/providers/azure/azure-errors.d.ts.map +1 -0
- package/dist/providers/azure/azure-errors.js +121 -0
- package/dist/providers/azure/azure-errors.js.map +1 -0
- package/dist/providers/azure/azure-retry.d.ts +41 -0
- package/dist/providers/azure/azure-retry.d.ts.map +1 -0
- package/dist/providers/azure/azure-retry.js +85 -0
- package/dist/providers/azure/azure-retry.js.map +1 -0
- package/dist/providers/azure/graph-client.d.ts +26 -0
- package/dist/providers/azure/graph-client.d.ts.map +1 -0
- package/dist/providers/azure/graph-client.js +146 -0
- package/dist/providers/azure/graph-client.js.map +1 -0
- package/dist/providers/azure/graph.provider.d.ts +23 -0
- package/dist/providers/azure/graph.provider.d.ts.map +1 -0
- package/dist/providers/azure/graph.provider.js +161 -0
- package/dist/providers/azure/graph.provider.js.map +1 -0
- package/dist/providers/azure/queries/app.queries.d.ts +6 -0
- package/dist/providers/azure/queries/app.queries.d.ts.map +1 -0
- package/dist/providers/azure/queries/app.queries.js +9 -0
- package/dist/providers/azure/queries/app.queries.js.map +1 -0
- package/dist/providers/azure/queries/policy.queries.d.ts +6 -0
- package/dist/providers/azure/queries/policy.queries.d.ts.map +1 -0
- package/dist/providers/azure/queries/policy.queries.js +9 -0
- package/dist/providers/azure/queries/policy.queries.js.map +1 -0
- package/dist/providers/azure/queries/user.queries.d.ts +7 -0
- package/dist/providers/azure/queries/user.queries.d.ts.map +1 -0
- package/dist/providers/azure/queries/user.queries.js +10 -0
- package/dist/providers/azure/queries/user.queries.js.map +1 -0
- package/dist/providers/interfaces/IGraphProvider.d.ts +31 -0
- package/dist/providers/interfaces/IGraphProvider.d.ts.map +1 -0
- package/dist/providers/interfaces/IGraphProvider.js +3 -0
- package/dist/providers/interfaces/IGraphProvider.js.map +1 -0
- package/dist/providers/interfaces/ILDAPProvider.d.ts +37 -0
- package/dist/providers/interfaces/ILDAPProvider.d.ts.map +1 -0
- package/dist/providers/interfaces/ILDAPProvider.js +3 -0
- package/dist/providers/interfaces/ILDAPProvider.js.map +1 -0
- package/dist/providers/ldap/acl-parser.d.ts +8 -0
- package/dist/providers/ldap/acl-parser.d.ts.map +1 -0
- package/dist/providers/ldap/acl-parser.js +157 -0
- package/dist/providers/ldap/acl-parser.js.map +1 -0
- package/dist/providers/ldap/ad-mappers.d.ts +8 -0
- package/dist/providers/ldap/ad-mappers.d.ts.map +1 -0
- package/dist/providers/ldap/ad-mappers.js +162 -0
- package/dist/providers/ldap/ad-mappers.js.map +1 -0
- package/dist/providers/ldap/ldap-client.d.ts +33 -0
- package/dist/providers/ldap/ldap-client.d.ts.map +1 -0
- package/dist/providers/ldap/ldap-client.js +195 -0
- package/dist/providers/ldap/ldap-client.js.map +1 -0
- package/dist/providers/ldap/ldap-errors.d.ts +48 -0
- package/dist/providers/ldap/ldap-errors.d.ts.map +1 -0
- package/dist/providers/ldap/ldap-errors.js +120 -0
- package/dist/providers/ldap/ldap-errors.js.map +1 -0
- package/dist/providers/ldap/ldap-retry.d.ts +14 -0
- package/dist/providers/ldap/ldap-retry.d.ts.map +1 -0
- package/dist/providers/ldap/ldap-retry.js +102 -0
- package/dist/providers/ldap/ldap-retry.js.map +1 -0
- package/dist/providers/ldap/ldap-sanitizer.d.ts +12 -0
- package/dist/providers/ldap/ldap-sanitizer.d.ts.map +1 -0
- package/dist/providers/ldap/ldap-sanitizer.js +104 -0
- package/dist/providers/ldap/ldap-sanitizer.js.map +1 -0
- package/dist/providers/ldap/ldap.provider.d.ts +21 -0
- package/dist/providers/ldap/ldap.provider.d.ts.map +1 -0
- package/dist/providers/ldap/ldap.provider.js +165 -0
- package/dist/providers/ldap/ldap.provider.js.map +1 -0
- package/dist/providers/ldap/queries/computer.queries.d.ts +6 -0
- package/dist/providers/ldap/queries/computer.queries.d.ts.map +1 -0
- package/dist/providers/ldap/queries/computer.queries.js +9 -0
- package/dist/providers/ldap/queries/computer.queries.js.map +1 -0
- package/dist/providers/ldap/queries/group.queries.d.ts +6 -0
- package/dist/providers/ldap/queries/group.queries.d.ts.map +1 -0
- package/dist/providers/ldap/queries/group.queries.js +9 -0
- package/dist/providers/ldap/queries/group.queries.js.map +1 -0
- package/dist/providers/ldap/queries/user.queries.d.ts +7 -0
- package/dist/providers/ldap/queries/user.queries.d.ts.map +1 -0
- package/dist/providers/ldap/queries/user.queries.js +10 -0
- package/dist/providers/ldap/queries/user.queries.js.map +1 -0
- package/dist/providers/smb/smb.provider.d.ts +68 -0
- package/dist/providers/smb/smb.provider.d.ts.map +1 -0
- package/dist/providers/smb/smb.provider.js +382 -0
- package/dist/providers/smb/smb.provider.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +44 -0
- package/dist/server.js.map +1 -0
- package/dist/services/audit/ad-audit.service.d.ts +70 -0
- package/dist/services/audit/ad-audit.service.d.ts.map +1 -0
- package/dist/services/audit/ad-audit.service.js +1019 -0
- package/dist/services/audit/ad-audit.service.js.map +1 -0
- package/dist/services/audit/attack-graph.service.d.ts +62 -0
- package/dist/services/audit/attack-graph.service.d.ts.map +1 -0
- package/dist/services/audit/attack-graph.service.js +702 -0
- package/dist/services/audit/attack-graph.service.js.map +1 -0
- package/dist/services/audit/audit.service.d.ts +4 -0
- package/dist/services/audit/audit.service.d.ts.map +1 -0
- package/dist/services/audit/audit.service.js +10 -0
- package/dist/services/audit/audit.service.js.map +1 -0
- package/dist/services/audit/azure-audit.service.d.ts +37 -0
- package/dist/services/audit/azure-audit.service.d.ts.map +1 -0
- package/dist/services/audit/azure-audit.service.js +153 -0
- package/dist/services/audit/azure-audit.service.js.map +1 -0
- package/dist/services/audit/detectors/ad/accounts.detector.d.ts +37 -0
- package/dist/services/audit/detectors/ad/accounts.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/accounts.detector.js +881 -0
- package/dist/services/audit/detectors/ad/accounts.detector.js.map +1 -0
- package/dist/services/audit/detectors/ad/adcs.detector.d.ts +21 -0
- package/dist/services/audit/detectors/ad/adcs.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/adcs.detector.js +227 -0
- package/dist/services/audit/detectors/ad/adcs.detector.js.map +1 -0
- package/dist/services/audit/detectors/ad/advanced.detector.d.ts +63 -0
- package/dist/services/audit/detectors/ad/advanced.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/advanced.detector.js +867 -0
- package/dist/services/audit/detectors/ad/advanced.detector.js.map +1 -0
- package/dist/services/audit/detectors/ad/attack-paths.detector.d.ts +16 -0
- package/dist/services/audit/detectors/ad/attack-paths.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/attack-paths.detector.js +369 -0
- package/dist/services/audit/detectors/ad/attack-paths.detector.js.map +1 -0
- package/dist/services/audit/detectors/ad/compliance.detector.d.ts +28 -0
- package/dist/services/audit/detectors/ad/compliance.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/compliance.detector.js +896 -0
- package/dist/services/audit/detectors/ad/compliance.detector.js.map +1 -0
- package/dist/services/audit/detectors/ad/computers.detector.d.ts +30 -0
- package/dist/services/audit/detectors/ad/computers.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/computers.detector.js +799 -0
- package/dist/services/audit/detectors/ad/computers.detector.js.map +1 -0
- package/dist/services/audit/detectors/ad/gpo.detector.d.ts +17 -0
- package/dist/services/audit/detectors/ad/gpo.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/gpo.detector.js +257 -0
- package/dist/services/audit/detectors/ad/gpo.detector.js.map +1 -0
- package/dist/services/audit/detectors/ad/groups.detector.d.ts +19 -0
- package/dist/services/audit/detectors/ad/groups.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/groups.detector.js +488 -0
- package/dist/services/audit/detectors/ad/groups.detector.js.map +1 -0
- package/dist/services/audit/detectors/ad/index.d.ts +15 -0
- package/dist/services/audit/detectors/ad/index.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/index.js +51 -0
- package/dist/services/audit/detectors/ad/index.js.map +1 -0
- package/dist/services/audit/detectors/ad/kerberos.detector.d.ts +17 -0
- package/dist/services/audit/detectors/ad/kerberos.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/kerberos.detector.js +293 -0
- package/dist/services/audit/detectors/ad/kerberos.detector.js.map +1 -0
- package/dist/services/audit/detectors/ad/monitoring.detector.d.ts +23 -0
- package/dist/services/audit/detectors/ad/monitoring.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/monitoring.detector.js +328 -0
- package/dist/services/audit/detectors/ad/monitoring.detector.js.map +1 -0
- package/dist/services/audit/detectors/ad/network.detector.d.ts +39 -0
- package/dist/services/audit/detectors/ad/network.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/network.detector.js +257 -0
- package/dist/services/audit/detectors/ad/network.detector.js.map +1 -0
- package/dist/services/audit/detectors/ad/password.detector.d.ts +14 -0
- package/dist/services/audit/detectors/ad/password.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/password.detector.js +235 -0
- package/dist/services/audit/detectors/ad/password.detector.js.map +1 -0
- package/dist/services/audit/detectors/ad/permissions.detector.d.ts +20 -0
- package/dist/services/audit/detectors/ad/permissions.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/permissions.detector.js +392 -0
- package/dist/services/audit/detectors/ad/permissions.detector.js.map +1 -0
- package/dist/services/audit/detectors/ad/trusts.detector.d.ts +11 -0
- package/dist/services/audit/detectors/ad/trusts.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/trusts.detector.js +186 -0
- package/dist/services/audit/detectors/ad/trusts.detector.js.map +1 -0
- package/dist/services/audit/detectors/azure/app-security.detector.d.ts +11 -0
- package/dist/services/audit/detectors/azure/app-security.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/azure/app-security.detector.js +184 -0
- package/dist/services/audit/detectors/azure/app-security.detector.js.map +1 -0
- package/dist/services/audit/detectors/azure/conditional-access.detector.d.ts +10 -0
- package/dist/services/audit/detectors/azure/conditional-access.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/azure/conditional-access.detector.js +130 -0
- package/dist/services/audit/detectors/azure/conditional-access.detector.js.map +1 -0
- package/dist/services/audit/detectors/azure/privilege-security.detector.d.ts +8 -0
- package/dist/services/audit/detectors/azure/privilege-security.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/azure/privilege-security.detector.js +113 -0
- package/dist/services/audit/detectors/azure/privilege-security.detector.js.map +1 -0
- package/dist/services/audit/detectors/azure/user-security.detector.d.ts +14 -0
- package/dist/services/audit/detectors/azure/user-security.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/azure/user-security.detector.js +198 -0
- package/dist/services/audit/detectors/azure/user-security.detector.js.map +1 -0
- package/dist/services/audit/detectors/index.d.ts +2 -0
- package/dist/services/audit/detectors/index.d.ts.map +1 -0
- package/dist/services/audit/detectors/index.js +38 -0
- package/dist/services/audit/detectors/index.js.map +1 -0
- package/dist/services/audit/response-formatter.d.ts +176 -0
- package/dist/services/audit/response-formatter.d.ts.map +1 -0
- package/dist/services/audit/response-formatter.js +240 -0
- package/dist/services/audit/response-formatter.js.map +1 -0
- package/dist/services/audit/scoring.service.d.ts +15 -0
- package/dist/services/audit/scoring.service.d.ts.map +1 -0
- package/dist/services/audit/scoring.service.js +139 -0
- package/dist/services/audit/scoring.service.js.map +1 -0
- package/dist/services/auth/crypto.service.d.ts +19 -0
- package/dist/services/auth/crypto.service.d.ts.map +1 -0
- package/dist/services/auth/crypto.service.js +135 -0
- package/dist/services/auth/crypto.service.js.map +1 -0
- package/dist/services/auth/errors.d.ts +19 -0
- package/dist/services/auth/errors.d.ts.map +1 -0
- package/dist/services/auth/errors.js +46 -0
- package/dist/services/auth/errors.js.map +1 -0
- package/dist/services/auth/token.service.d.ts +41 -0
- package/dist/services/auth/token.service.d.ts.map +1 -0
- package/dist/services/auth/token.service.js +208 -0
- package/dist/services/auth/token.service.js.map +1 -0
- package/dist/services/config/config.service.d.ts +6 -0
- package/dist/services/config/config.service.d.ts.map +1 -0
- package/dist/services/config/config.service.js +64 -0
- package/dist/services/config/config.service.js.map +1 -0
- package/dist/services/export/export.service.d.ts +28 -0
- package/dist/services/export/export.service.d.ts.map +1 -0
- package/dist/services/export/export.service.js +28 -0
- package/dist/services/export/export.service.js.map +1 -0
- package/dist/services/export/formatters/csv.formatter.d.ts +8 -0
- package/dist/services/export/formatters/csv.formatter.d.ts.map +1 -0
- package/dist/services/export/formatters/csv.formatter.js +46 -0
- package/dist/services/export/formatters/csv.formatter.js.map +1 -0
- package/dist/services/export/formatters/json.formatter.d.ts +40 -0
- package/dist/services/export/formatters/json.formatter.d.ts.map +1 -0
- package/dist/services/export/formatters/json.formatter.js +58 -0
- package/dist/services/export/formatters/json.formatter.js.map +1 -0
- package/dist/services/jobs/azure-job-runner.d.ts +38 -0
- package/dist/services/jobs/azure-job-runner.d.ts.map +1 -0
- package/dist/services/jobs/azure-job-runner.js +199 -0
- package/dist/services/jobs/azure-job-runner.js.map +1 -0
- package/dist/services/jobs/index.d.ts +4 -0
- package/dist/services/jobs/index.d.ts.map +1 -0
- package/dist/services/jobs/index.js +20 -0
- package/dist/services/jobs/index.js.map +1 -0
- package/dist/services/jobs/job-runner.d.ts +64 -0
- package/dist/services/jobs/job-runner.d.ts.map +1 -0
- package/dist/services/jobs/job-runner.js +952 -0
- package/dist/services/jobs/job-runner.js.map +1 -0
- package/dist/services/jobs/job-store.d.ts +27 -0
- package/dist/services/jobs/job-store.d.ts.map +1 -0
- package/dist/services/jobs/job-store.js +261 -0
- package/dist/services/jobs/job-store.js.map +1 -0
- package/dist/services/jobs/job.types.d.ts +67 -0
- package/dist/services/jobs/job.types.d.ts.map +1 -0
- package/dist/services/jobs/job.types.js +36 -0
- package/dist/services/jobs/job.types.js.map +1 -0
- package/dist/types/ad.types.d.ts +74 -0
- package/dist/types/ad.types.d.ts.map +1 -0
- package/dist/types/ad.types.js +3 -0
- package/dist/types/ad.types.js.map +1 -0
- package/dist/types/adcs.types.d.ts +58 -0
- package/dist/types/adcs.types.d.ts.map +1 -0
- package/dist/types/adcs.types.js +38 -0
- package/dist/types/adcs.types.js.map +1 -0
- package/dist/types/attack-graph.types.d.ts +135 -0
- package/dist/types/attack-graph.types.d.ts.map +1 -0
- package/dist/types/attack-graph.types.js +58 -0
- package/dist/types/attack-graph.types.js.map +1 -0
- package/dist/types/audit.types.d.ts +34 -0
- package/dist/types/audit.types.d.ts.map +1 -0
- package/dist/types/audit.types.js +3 -0
- package/dist/types/audit.types.js.map +1 -0
- package/dist/types/azure.types.d.ts +61 -0
- package/dist/types/azure.types.d.ts.map +1 -0
- package/dist/types/azure.types.js +3 -0
- package/dist/types/azure.types.js.map +1 -0
- package/dist/types/config.types.d.ts +63 -0
- package/dist/types/config.types.d.ts.map +1 -0
- package/dist/types/config.types.js +3 -0
- package/dist/types/config.types.js.map +1 -0
- package/dist/types/error.types.d.ts +33 -0
- package/dist/types/error.types.d.ts.map +1 -0
- package/dist/types/error.types.js +70 -0
- package/dist/types/error.types.js.map +1 -0
- package/dist/types/finding.types.d.ts +133 -0
- package/dist/types/finding.types.d.ts.map +1 -0
- package/dist/types/finding.types.js +3 -0
- package/dist/types/finding.types.js.map +1 -0
- package/dist/types/gpo.types.d.ts +39 -0
- package/dist/types/gpo.types.d.ts.map +1 -0
- package/dist/types/gpo.types.js +15 -0
- package/dist/types/gpo.types.js.map +1 -0
- package/dist/types/token.types.d.ts +26 -0
- package/dist/types/token.types.d.ts.map +1 -0
- package/dist/types/token.types.js +3 -0
- package/dist/types/token.types.js.map +1 -0
- package/dist/types/trust.types.d.ts +45 -0
- package/dist/types/trust.types.d.ts.map +1 -0
- package/dist/types/trust.types.js +71 -0
- package/dist/types/trust.types.js.map +1 -0
- package/dist/utils/entity-converter.d.ts +17 -0
- package/dist/utils/entity-converter.d.ts.map +1 -0
- package/dist/utils/entity-converter.js +285 -0
- package/dist/utils/entity-converter.js.map +1 -0
- package/dist/utils/graph.util.d.ts +66 -0
- package/dist/utils/graph.util.d.ts.map +1 -0
- package/dist/utils/graph.util.js +382 -0
- package/dist/utils/graph.util.js.map +1 -0
- package/dist/utils/logger.d.ts +7 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +86 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/type-name-normalizer.d.ts +5 -0
- package/dist/utils/type-name-normalizer.d.ts.map +1 -0
- package/dist/utils/type-name-normalizer.js +218 -0
- package/dist/utils/type-name-normalizer.js.map +1 -0
- package/docker-compose.yml +26 -0
- package/docs/api/README.md +178 -0
- package/docs/api/openapi.yaml +1524 -0
- package/eslint.config.js +54 -0
- package/jest.config.js +38 -0
- package/package.json +97 -0
- package/scripts/fetch-ad-cert.sh +142 -0
- package/src/.gitkeep +0 -0
- package/src/api/.gitkeep +0 -0
- package/src/api/controllers/.gitkeep +0 -0
- package/src/api/controllers/audit.controller.ts +313 -0
- package/src/api/controllers/auth.controller.ts +258 -0
- package/src/api/controllers/export.controller.ts +153 -0
- package/src/api/controllers/health.controller.ts +16 -0
- package/src/api/controllers/jobs.controller.ts +187 -0
- package/src/api/controllers/providers.controller.ts +165 -0
- package/src/api/dto/.gitkeep +0 -0
- package/src/api/dto/AuditRequest.dto.ts +8 -0
- package/src/api/dto/AuditResponse.dto.ts +19 -0
- package/src/api/dto/TokenRequest.dto.ts +8 -0
- package/src/api/dto/TokenResponse.dto.ts +14 -0
- package/src/api/middlewares/.gitkeep +0 -0
- package/src/api/middlewares/authenticate.ts +203 -0
- package/src/api/middlewares/errorHandler.ts +54 -0
- package/src/api/middlewares/rateLimit.ts +35 -0
- package/src/api/middlewares/validate.ts +32 -0
- package/src/api/routes/.gitkeep +0 -0
- package/src/api/routes/audit.routes.ts +77 -0
- package/src/api/routes/auth.routes.ts +71 -0
- package/src/api/routes/export.routes.ts +34 -0
- package/src/api/routes/health.routes.ts +14 -0
- package/src/api/routes/index.ts +40 -0
- package/src/api/routes/providers.routes.ts +24 -0
- package/src/api/validators/.gitkeep +0 -0
- package/src/api/validators/audit.schemas.ts +59 -0
- package/src/api/validators/auth.schemas.ts +59 -0
- package/src/app.ts +87 -0
- package/src/config/.gitkeep +0 -0
- package/src/config/config.schema.ts +108 -0
- package/src/config/index.ts +82 -0
- package/src/container.ts +221 -0
- package/src/data/.gitkeep +0 -0
- package/src/data/database.ts +78 -0
- package/src/data/jobs/token-cleanup.job.ts +166 -0
- package/src/data/migrations/.gitkeep +0 -0
- package/src/data/migrations/001_initial_schema.sql +47 -0
- package/src/data/migrations/migration.runner.ts +125 -0
- package/src/data/models/.gitkeep +0 -0
- package/src/data/models/Token.model.ts +35 -0
- package/src/data/repositories/.gitkeep +0 -0
- package/src/data/repositories/token.repository.ts +160 -0
- package/src/providers/.gitkeep +0 -0
- package/src/providers/azure/.gitkeep +0 -0
- package/src/providers/azure/auth.provider.ts +14 -0
- package/src/providers/azure/azure-errors.ts +189 -0
- package/src/providers/azure/azure-retry.ts +168 -0
- package/src/providers/azure/graph-client.ts +315 -0
- package/src/providers/azure/graph.provider.ts +294 -0
- package/src/providers/azure/queries/app.queries.ts +9 -0
- package/src/providers/azure/queries/policy.queries.ts +9 -0
- package/src/providers/azure/queries/user.queries.ts +10 -0
- package/src/providers/interfaces/.gitkeep +0 -0
- package/src/providers/interfaces/IGraphProvider.ts +117 -0
- package/src/providers/interfaces/ILDAPProvider.ts +142 -0
- package/src/providers/ldap/.gitkeep +0 -0
- package/src/providers/ldap/acl-parser.ts +231 -0
- package/src/providers/ldap/ad-mappers.ts +280 -0
- package/src/providers/ldap/ldap-client.ts +259 -0
- package/src/providers/ldap/ldap-errors.ts +188 -0
- package/src/providers/ldap/ldap-retry.ts +267 -0
- package/src/providers/ldap/ldap-sanitizer.ts +273 -0
- package/src/providers/ldap/ldap.provider.ts +293 -0
- package/src/providers/ldap/queries/computer.queries.ts +9 -0
- package/src/providers/ldap/queries/group.queries.ts +9 -0
- package/src/providers/ldap/queries/user.queries.ts +10 -0
- package/src/providers/smb/smb.provider.ts +653 -0
- package/src/server.ts +60 -0
- package/src/services/.gitkeep +0 -0
- package/src/services/audit/.gitkeep +0 -0
- package/src/services/audit/ad-audit.service.ts +1481 -0
- package/src/services/audit/attack-graph.service.ts +1104 -0
- package/src/services/audit/audit.service.ts +12 -0
- package/src/services/audit/azure-audit.service.ts +286 -0
- package/src/services/audit/detectors/ad/accounts.detector.ts +1232 -0
- package/src/services/audit/detectors/ad/adcs.detector.ts +449 -0
- package/src/services/audit/detectors/ad/advanced.detector.ts +1270 -0
- package/src/services/audit/detectors/ad/attack-paths.detector.ts +600 -0
- package/src/services/audit/detectors/ad/compliance.detector.ts +1421 -0
- package/src/services/audit/detectors/ad/computers.detector.ts +1188 -0
- package/src/services/audit/detectors/ad/gpo.detector.ts +485 -0
- package/src/services/audit/detectors/ad/groups.detector.ts +685 -0
- package/src/services/audit/detectors/ad/index.ts +84 -0
- package/src/services/audit/detectors/ad/kerberos.detector.ts +424 -0
- package/src/services/audit/detectors/ad/monitoring.detector.ts +501 -0
- package/src/services/audit/detectors/ad/network.detector.ts +538 -0
- package/src/services/audit/detectors/ad/password.detector.ts +324 -0
- package/src/services/audit/detectors/ad/permissions.detector.ts +637 -0
- package/src/services/audit/detectors/ad/trusts.detector.ts +315 -0
- package/src/services/audit/detectors/azure/app-security.detector.ts +246 -0
- package/src/services/audit/detectors/azure/conditional-access.detector.ts +186 -0
- package/src/services/audit/detectors/azure/privilege-security.detector.ts +176 -0
- package/src/services/audit/detectors/azure/user-security.detector.ts +280 -0
- package/src/services/audit/detectors/index.ts +18 -0
- package/src/services/audit/response-formatter.ts +604 -0
- package/src/services/audit/scoring.service.ts +234 -0
- package/src/services/auth/.gitkeep +0 -0
- package/src/services/auth/crypto.service.ts +230 -0
- package/src/services/auth/errors.ts +47 -0
- package/src/services/auth/token.service.ts +420 -0
- package/src/services/config/.gitkeep +0 -0
- package/src/services/config/config.service.ts +75 -0
- package/src/services/export/.gitkeep +0 -0
- package/src/services/export/export.service.ts +99 -0
- package/src/services/export/formatters/csv.formatter.ts +124 -0
- package/src/services/export/formatters/json.formatter.ts +160 -0
- package/src/services/jobs/azure-job-runner.ts +312 -0
- package/src/services/jobs/index.ts +9 -0
- package/src/services/jobs/job-runner.ts +1280 -0
- package/src/services/jobs/job-store.ts +384 -0
- package/src/services/jobs/job.types.ts +182 -0
- package/src/types/.gitkeep +0 -0
- package/src/types/ad.types.ts +91 -0
- package/src/types/adcs.types.ts +107 -0
- package/src/types/attack-graph.types.ts +260 -0
- package/src/types/audit.types.ts +42 -0
- package/src/types/azure.types.ts +68 -0
- package/src/types/config.types.ts +79 -0
- package/src/types/error.types.ts +69 -0
- package/src/types/finding.types.ts +284 -0
- package/src/types/gpo.types.ts +72 -0
- package/src/types/smb2.d.ts +73 -0
- package/src/types/token.types.ts +32 -0
- package/src/types/trust.types.ts +140 -0
- package/src/utils/.gitkeep +0 -0
- package/src/utils/entity-converter.ts +453 -0
- package/src/utils/graph.util.ts +609 -0
- package/src/utils/logger.ts +111 -0
- package/src/utils/type-name-normalizer.ts +302 -0
- package/tests/.gitkeep +0 -0
- package/tests/e2e/.gitkeep +0 -0
- package/tests/fixtures/.gitkeep +0 -0
- package/tests/integration/.gitkeep +0 -0
- package/tests/integration/README.md +156 -0
- package/tests/integration/ad-audit.integration.test.ts +216 -0
- package/tests/integration/api/.gitkeep +0 -0
- package/tests/integration/api/endpoints.integration.test.ts +431 -0
- package/tests/integration/auth/jwt-authentication.integration.test.ts +358 -0
- package/tests/integration/providers/.gitkeep +0 -0
- package/tests/integration/providers/azure-basic.integration.test.ts +167 -0
- package/tests/integration/providers/ldap-basic.integration.test.ts +152 -0
- package/tests/integration/providers/ldap-connectivity.test.ts +44 -0
- package/tests/integration/providers/ldap-provider.integration.test.ts +347 -0
- package/tests/mocks/.gitkeep +0 -0
- package/tests/setup.ts +16 -0
- package/tests/unit/.gitkeep +0 -0
- package/tests/unit/api/middlewares/authenticate.test.ts +446 -0
- package/tests/unit/providers/.gitkeep +0 -0
- package/tests/unit/providers/azure/azure-errors.test.ts +193 -0
- package/tests/unit/providers/azure/azure-retry.test.ts +254 -0
- package/tests/unit/providers/azure/graph-provider.test.ts +313 -0
- package/tests/unit/providers/ldap/ad-mappers.test.ts +392 -0
- package/tests/unit/providers/ldap/ldap-provider.test.ts +376 -0
- package/tests/unit/providers/ldap/ldap-retry.test.ts +377 -0
- package/tests/unit/providers/ldap/ldap-sanitizer.test.ts +301 -0
- package/tests/unit/sample.test.ts +19 -0
- package/tests/unit/services/.gitkeep +0 -0
- package/tests/unit/services/audit/detectors/ad/accounts.detector.test.ts +393 -0
- package/tests/unit/services/audit/detectors/ad/advanced.detector.test.ts +380 -0
- package/tests/unit/services/audit/detectors/ad/computers.detector.test.ts +440 -0
- package/tests/unit/services/audit/detectors/ad/groups.detector.test.ts +276 -0
- package/tests/unit/services/audit/detectors/ad/kerberos.detector.test.ts +215 -0
- package/tests/unit/services/audit/detectors/ad/password.detector.test.ts +226 -0
- package/tests/unit/services/audit/detectors/ad/permissions.detector.test.ts +244 -0
- package/tests/unit/services/audit/detectors/azure/app-security.detector.test.ts +349 -0
- package/tests/unit/services/audit/detectors/azure/conditional-access.detector.test.ts +374 -0
- package/tests/unit/services/audit/detectors/azure/privilege-security.detector.test.ts +374 -0
- package/tests/unit/services/audit/detectors/azure/user-security.detector.test.ts +297 -0
- package/tests/unit/services/auth/crypto.service.test.ts +296 -0
- package/tests/unit/services/auth/token.service.test.ts +579 -0
- package/tests/unit/services/export/export.service.test.ts +241 -0
- package/tests/unit/services/export/formatters/csv.formatter.test.ts +270 -0
- package/tests/unit/services/export/formatters/json.formatter.test.ts +258 -0
- package/tests/unit/utils/.gitkeep +0 -0
- 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
|
+
};
|