mirror of
https://github.com/freedbygrace/ActiveDirectoryManager.git
synced 2026-08-08 18:04:38 +00:00
Add Active Directory group management functionality
Replit-Commit-Author: Agent Replit-Commit-Session-Id: 705f2157-ef97-4fbd-89e4-8c7f2ecaea90 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/7ed01c5f-a82d-405a-b728-b2e3d127c60c/6f419947-5d2b-4028-a9f5-2456de5a48d3.jpg
This commit is contained in:
Generated
+215
@@ -68,6 +68,7 @@
|
|||||||
"input-otp": "^1.2.4",
|
"input-otp": "^1.2.4",
|
||||||
"ioredis": "^5.6.0",
|
"ioredis": "^5.6.0",
|
||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.2",
|
||||||
|
"ldapjs": "^3.0.7",
|
||||||
"lucide-react": "^0.453.0",
|
"lucide-react": "^0.453.0",
|
||||||
"memorystore": "^1.6.7",
|
"memorystore": "^1.6.7",
|
||||||
"morgan": "^1.10.0",
|
"morgan": "^1.10.0",
|
||||||
@@ -1514,6 +1515,101 @@
|
|||||||
"integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==",
|
"integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@ldapjs/asn1": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ldapjs/asn1/-/asn1-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-G9+DkEOirNgdPmD0I8nu57ygQJKOOgFEMKknEuQvIHbGLwP3ny1mY+OTUYLCbCaGJP4sox5eYgBJRuSUpnAddA==",
|
||||||
|
"deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@ldapjs/attribute": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ldapjs/attribute/-/attribute-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-ptMl2d/5xJ0q+RgmnqOi3Zgwk/TMJYG7dYMC0Keko+yZU6n+oFM59MjQOUht5pxJeS4FWrImhu/LebX24vJNRQ==",
|
||||||
|
"deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@ldapjs/asn1": "2.0.0",
|
||||||
|
"@ldapjs/protocol": "^1.2.1",
|
||||||
|
"process-warning": "^2.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@ldapjs/change": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ldapjs/change/-/change-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-EOQNFH1RIku3M1s0OAJOzGfAohuFYXFY4s73wOhRm4KFGhmQQ7MChOh2YtYu9Kwgvuq1B0xKciXVzHCGkB5V+Q==",
|
||||||
|
"deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@ldapjs/asn1": "2.0.0",
|
||||||
|
"@ldapjs/attribute": "1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@ldapjs/controls": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ldapjs/controls/-/controls-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-2pFdD1yRC9V9hXfAWvCCO2RRWK9OdIEcJIos/9cCVP9O4k72BY1bLDQQ4KpUoJnl4y/JoD4iFgM+YWT3IfITWw==",
|
||||||
|
"deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@ldapjs/asn1": "^1.2.0",
|
||||||
|
"@ldapjs/protocol": "^1.2.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ldapjs/asn1/-/asn1-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-KX/qQJ2xxzvO2/WOvr1UdQ+8P5dVvuOLk/C9b1bIkXxZss8BaR28njXdPgFCpj5aHaf1t8PmuVnea+N9YG9YMw==",
|
||||||
|
"deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@ldapjs/dn": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ldapjs/dn/-/dn-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-R72zH5ZeBj/Fujf/yBu78YzpJjJXG46YHFo5E4W1EqfNpo1UsVPqdLrRMXeKIsJT3x9dJVIfR6OpzgINlKpi0A==",
|
||||||
|
"deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@ldapjs/asn1": "2.0.0",
|
||||||
|
"process-warning": "^2.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@ldapjs/filter": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ldapjs/filter/-/filter-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-TwPK5eEgNdUO1ABPBUQabcZ+h9heDORE4V9WNZqCtYLKc06+6+UAJ3IAbr0L0bYTnkkWC/JEQD2F+zAFsuikNw==",
|
||||||
|
"deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@ldapjs/asn1": "2.0.0",
|
||||||
|
"@ldapjs/protocol": "^1.2.1",
|
||||||
|
"process-warning": "^2.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@ldapjs/messages": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ldapjs/messages/-/messages-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-K7xZpXJ21bj92jS35wtRbdcNrwmxAtPwy4myeh9duy/eR3xQKvikVycbdWVzkYEAVE5Ce520VXNOwCHjomjCZw==",
|
||||||
|
"deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@ldapjs/asn1": "^2.0.0",
|
||||||
|
"@ldapjs/attribute": "^1.0.0",
|
||||||
|
"@ldapjs/change": "^1.0.0",
|
||||||
|
"@ldapjs/controls": "^2.1.0",
|
||||||
|
"@ldapjs/dn": "^1.1.0",
|
||||||
|
"@ldapjs/filter": "^2.1.1",
|
||||||
|
"@ldapjs/protocol": "^1.2.1",
|
||||||
|
"process-warning": "^2.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@ldapjs/protocol": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ldapjs/protocol/-/protocol-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-O89xFDLW2gBoZWNXuXpBSM32/KealKCTb3JGtJdtUQc7RjAk8XzrRgyz02cPAwGKwKPxy0ivuC7UP9bmN87egQ==",
|
||||||
|
"deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@neondatabase/serverless": {
|
"node_modules/@neondatabase/serverless": {
|
||||||
"version": "0.10.4",
|
"version": "0.10.4",
|
||||||
"resolved": "https://registry.npmjs.org/@neondatabase/serverless/-/serverless-0.10.4.tgz",
|
"resolved": "https://registry.npmjs.org/@neondatabase/serverless/-/serverless-0.10.4.tgz",
|
||||||
@@ -3786,6 +3882,12 @@
|
|||||||
"vite": "^4.2.0 || ^5.0.0"
|
"vite": "^4.2.0 || ^5.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/abstract-logging": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/accepts": {
|
"node_modules/accepts": {
|
||||||
"version": "1.3.8",
|
"version": "1.3.8",
|
||||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
||||||
@@ -3872,6 +3974,15 @@
|
|||||||
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
|
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/assert-plus": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/autoprefixer": {
|
"node_modules/autoprefixer": {
|
||||||
"version": "10.4.20",
|
"version": "10.4.20",
|
||||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz",
|
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz",
|
||||||
@@ -3910,6 +4021,18 @@
|
|||||||
"postcss": "^8.1.0"
|
"postcss": "^8.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/backoff": {
|
||||||
|
"version": "2.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz",
|
||||||
|
"integrity": "sha512-wC5ihrnUXmR2douXmXLCe5O3zg3GKIyvRi/hi58a/XyRxVI+3/yM0PYueQOZXPXQ9pxBislYkw+sF9b7C/RuMA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"precond": "0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/balanced-match": {
|
"node_modules/balanced-match": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
@@ -4369,6 +4492,12 @@
|
|||||||
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
|
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/core-util-is": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.6",
|
"version": "7.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||||
@@ -5546,6 +5675,15 @@
|
|||||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/extsprintf": {
|
||||||
|
"version": "1.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz",
|
||||||
|
"integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==",
|
||||||
|
"engines": [
|
||||||
|
"node >=0.6.0"
|
||||||
|
],
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/fast-equals": {
|
"node_modules/fast-equals": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.0.1.tgz",
|
||||||
@@ -6204,6 +6342,29 @@
|
|||||||
"safe-buffer": "^5.0.1"
|
"safe-buffer": "^5.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ldapjs": {
|
||||||
|
"version": "3.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/ldapjs/-/ldapjs-3.0.7.tgz",
|
||||||
|
"integrity": "sha512-1ky+WrN+4CFMuoekUOv7Y1037XWdjKpu0xAPwSP+9KdvmV9PG+qOKlssDV6a+U32apwxdD3is/BZcWOYzN30cg==",
|
||||||
|
"deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@ldapjs/asn1": "^2.0.0",
|
||||||
|
"@ldapjs/attribute": "^1.0.0",
|
||||||
|
"@ldapjs/change": "^1.0.0",
|
||||||
|
"@ldapjs/controls": "^2.1.0",
|
||||||
|
"@ldapjs/dn": "^1.1.0",
|
||||||
|
"@ldapjs/filter": "^2.1.1",
|
||||||
|
"@ldapjs/messages": "^1.3.0",
|
||||||
|
"@ldapjs/protocol": "^1.2.1",
|
||||||
|
"abstract-logging": "^2.0.1",
|
||||||
|
"assert-plus": "^1.0.0",
|
||||||
|
"backoff": "^2.5.0",
|
||||||
|
"once": "^1.4.0",
|
||||||
|
"vasync": "^2.2.1",
|
||||||
|
"verror": "^1.10.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/lilconfig": {
|
"node_modules/lilconfig": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
|
||||||
@@ -7217,6 +7378,20 @@
|
|||||||
"integrity": "sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==",
|
"integrity": "sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/precond": {
|
||||||
|
"version": "0.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz",
|
||||||
|
"integrity": "sha512-QCYG84SgGyGzqJ/vlMsxeXd/pgL/I94ixdNFyh1PusWmTCyVfPJjZ1K1jvHtsbfnXQs2TSkEP2fR7QiMZAnKFQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/process-warning": {
|
||||||
|
"version": "2.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.3.2.tgz",
|
||||||
|
"integrity": "sha512-n9wh8tvBe5sFmsqlg+XQhaQLumwpqoAUruLwjCopgTmUBjJ/fjtBsJzKleCaIGBOMXYEhp1YfKl4d7rJ5ZKJGA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/prop-types": {
|
"node_modules/prop-types": {
|
||||||
"version": "15.8.1",
|
"version": "15.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||||
@@ -8953,6 +9128,32 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/vasync": {
|
||||||
|
"version": "2.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/vasync/-/vasync-2.2.1.tgz",
|
||||||
|
"integrity": "sha512-Hq72JaTpcTFdWiNA4Y22Amej2GH3BFmBaKPPlDZ4/oC8HNn2ISHLkFrJU4Ds8R3jcUi7oo5Y9jcMHKjES+N9wQ==",
|
||||||
|
"engines": [
|
||||||
|
"node >=0.6.0"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"verror": "1.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/vasync/node_modules/verror": {
|
||||||
|
"version": "1.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
|
||||||
|
"integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==",
|
||||||
|
"engines": [
|
||||||
|
"node >=0.6.0"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"assert-plus": "^1.0.0",
|
||||||
|
"core-util-is": "1.0.2",
|
||||||
|
"extsprintf": "^1.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/vaul": {
|
"node_modules/vaul": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/vaul/-/vaul-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/vaul/-/vaul-1.1.1.tgz",
|
||||||
@@ -8966,6 +9167,20 @@
|
|||||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0"
|
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/verror": {
|
||||||
|
"version": "1.10.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz",
|
||||||
|
"integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"assert-plus": "^1.0.0",
|
||||||
|
"core-util-is": "1.0.2",
|
||||||
|
"extsprintf": "^1.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/victory-vendor": {
|
"node_modules/victory-vendor": {
|
||||||
"version": "36.9.2",
|
"version": "36.9.2",
|
||||||
"resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz",
|
"resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz",
|
||||||
|
|||||||
@@ -70,6 +70,7 @@
|
|||||||
"input-otp": "^1.2.4",
|
"input-otp": "^1.2.4",
|
||||||
"ioredis": "^5.6.0",
|
"ioredis": "^5.6.0",
|
||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.2",
|
||||||
|
"ldapjs": "^3.0.7",
|
||||||
"lucide-react": "^0.453.0",
|
"lucide-react": "^0.453.0",
|
||||||
"memorystore": "^1.6.7",
|
"memorystore": "^1.6.7",
|
||||||
"morgan": "^1.10.0",
|
"morgan": "^1.10.0",
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{pkgs}: {
|
||||||
|
deps = [
|
||||||
|
pkgs.postgresql
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -19,6 +19,7 @@ import {
|
|||||||
requireAdmin,
|
requireAdmin,
|
||||||
initializeRBAC
|
initializeRBAC
|
||||||
} from "./authorization";
|
} from "./authorization";
|
||||||
|
import { ldapClient } from "./ldap";
|
||||||
|
|
||||||
// Extend Express Request to include user property
|
// Extend Express Request to include user property
|
||||||
interface Request extends ExpressRequest {
|
interface Request extends ExpressRequest {
|
||||||
@@ -1003,6 +1004,148 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
|||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/connections/{connectionId}/ad-groups:
|
||||||
|
* post:
|
||||||
|
* summary: Create a new Active Directory group
|
||||||
|
* tags: [AD Groups]
|
||||||
|
* security:
|
||||||
|
* - cookieAuth: []
|
||||||
|
* - bearerAuth: []
|
||||||
|
* parameters:
|
||||||
|
* - in: path
|
||||||
|
* name: connectionId
|
||||||
|
* required: true
|
||||||
|
* schema:
|
||||||
|
* type: integer
|
||||||
|
* description: LDAP connection ID
|
||||||
|
* requestBody:
|
||||||
|
* required: true
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* required:
|
||||||
|
* - name
|
||||||
|
* - parentDN
|
||||||
|
* properties:
|
||||||
|
* name:
|
||||||
|
* type: string
|
||||||
|
* description: The name of the group (will be used for cn and sAMAccountName)
|
||||||
|
* parentDN:
|
||||||
|
* type: string
|
||||||
|
* description: The distinguished name of the parent container (OU or domain)
|
||||||
|
* description:
|
||||||
|
* type: string
|
||||||
|
* description: Group description
|
||||||
|
* groupType:
|
||||||
|
* type: string
|
||||||
|
* enum: ['Global', 'DomainLocal', 'Universal']
|
||||||
|
* default: 'Global'
|
||||||
|
* description: Group scope type
|
||||||
|
* groupCategory:
|
||||||
|
* type: string
|
||||||
|
* enum: ['Security', 'Distribution']
|
||||||
|
* default: 'Security'
|
||||||
|
* description: Group category type
|
||||||
|
* responses:
|
||||||
|
* 201:
|
||||||
|
* description: Group created successfully
|
||||||
|
* 400:
|
||||||
|
* description: Invalid input
|
||||||
|
* 401:
|
||||||
|
* description: Unauthorized
|
||||||
|
* 403:
|
||||||
|
* description: Forbidden
|
||||||
|
* 500:
|
||||||
|
* description: Server error
|
||||||
|
*/
|
||||||
|
app.post("/api/connections/:connectionId/ad-groups", authenticateApiToken, requirePermission(PERMISSIONS.CREATE_AD_GROUPS), async (req: Request, res, next) => {
|
||||||
|
try {
|
||||||
|
const connectionId = parseInt(req.params.connectionId);
|
||||||
|
const { name, parentDN, description, groupType = 'Global', groupCategory = 'Security' } = req.body;
|
||||||
|
|
||||||
|
// Basic validation
|
||||||
|
if (!name || !parentDN) {
|
||||||
|
return res.status(400).json({ message: "Group name and parent DN are required" });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get connection
|
||||||
|
const connection = await storage.getLdapConnection(connectionId);
|
||||||
|
if (!connection) {
|
||||||
|
return res.status(404).json({ message: "LDAP connection not found" });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the DN for the new group
|
||||||
|
const groupDN = `CN=${name},${parentDN}`;
|
||||||
|
|
||||||
|
// Set the group type value based on type and category
|
||||||
|
const groupTypeValue =
|
||||||
|
(groupCategory === 'Security' ? 0x80000000 : 0) |
|
||||||
|
(groupType === 'Global' ? 0x2 : groupType === 'Universal' ? 0x8 : 0x4);
|
||||||
|
|
||||||
|
// Attributes for the new group
|
||||||
|
const groupAttributes = {
|
||||||
|
objectClass: ['top', 'group'],
|
||||||
|
cn: name,
|
||||||
|
sAMAccountName: name,
|
||||||
|
description: description || '',
|
||||||
|
groupType: groupTypeValue.toString()
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create the group in AD
|
||||||
|
await ldapClient.createEntry(connectionId, groupDN, groupAttributes);
|
||||||
|
|
||||||
|
// Search for the newly created group to get its attributes
|
||||||
|
const searchResults = await ldapClient.searchGroups(connectionId, `(&(objectClass=group)(cn=${name}))`, [
|
||||||
|
'objectGUID', 'distinguishedName', 'canonicalName', 'cn', 'sAMAccountName', 'description', 'groupType'
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!searchResults || searchResults.length === 0) {
|
||||||
|
return res.status(500).json({ message: "Group created but could not retrieve details" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const adGroup = searchResults[0];
|
||||||
|
|
||||||
|
// Store in database
|
||||||
|
const storedGroup = await storage.createAdGroup({
|
||||||
|
connectionId,
|
||||||
|
objectGUID: adGroup.objectGUID,
|
||||||
|
distinguishedName: adGroup.distinguishedName,
|
||||||
|
canonicalName: adGroup.canonicalName,
|
||||||
|
cn: adGroup.cn,
|
||||||
|
sAMAccountName: adGroup.sAMAccountName,
|
||||||
|
groupType: groupCategory + ' ' + groupType,
|
||||||
|
description: adGroup.description,
|
||||||
|
members: [], // No members initially
|
||||||
|
adProperties: adGroup // Store all attributes
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add audit log
|
||||||
|
await storage.createAuditLogEntry({
|
||||||
|
userId: req.user.id,
|
||||||
|
connectionId,
|
||||||
|
action: 'create',
|
||||||
|
targetId: storedGroup.id.toString(),
|
||||||
|
details: {
|
||||||
|
objectType: 'group',
|
||||||
|
objectName: name,
|
||||||
|
distinguishedName: groupDN,
|
||||||
|
groupType: groupCategory + ' ' + groupType
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
res.status(201).json(storedGroup);
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error creating AD group:", err);
|
||||||
|
if (err.message && err.message.includes('Entry Already Exists')) {
|
||||||
|
return res.status(409).json({ message: "Group already exists" });
|
||||||
|
}
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @swagger
|
* @swagger
|
||||||
@@ -1353,6 +1496,186 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
|||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/connections/{connectionId}/ad-computers:
|
||||||
|
* post:
|
||||||
|
* summary: Create a new Active Directory computer
|
||||||
|
* tags: [AD Computers]
|
||||||
|
* security:
|
||||||
|
* - cookieAuth: []
|
||||||
|
* - bearerAuth: []
|
||||||
|
* parameters:
|
||||||
|
* - in: path
|
||||||
|
* name: connectionId
|
||||||
|
* required: true
|
||||||
|
* schema:
|
||||||
|
* type: integer
|
||||||
|
* description: LDAP connection ID
|
||||||
|
* requestBody:
|
||||||
|
* required: true
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* required:
|
||||||
|
* - name
|
||||||
|
* - parentDN
|
||||||
|
* properties:
|
||||||
|
* name:
|
||||||
|
* type: string
|
||||||
|
* description: The name of the computer (will be used for cn and sAMAccountName)
|
||||||
|
* parentDN:
|
||||||
|
* type: string
|
||||||
|
* description: The distinguished name of the parent container (OU or domain)
|
||||||
|
* description:
|
||||||
|
* type: string
|
||||||
|
* description: Computer description
|
||||||
|
* dnsHostName:
|
||||||
|
* type: string
|
||||||
|
* description: DNS host name of the computer
|
||||||
|
* operatingSystem:
|
||||||
|
* type: string
|
||||||
|
* description: Operating system of the computer
|
||||||
|
* operatingSystemVersion:
|
||||||
|
* type: string
|
||||||
|
* description: Operating system version
|
||||||
|
* enabled:
|
||||||
|
* type: boolean
|
||||||
|
* default: true
|
||||||
|
* description: Whether the computer account is enabled
|
||||||
|
* responses:
|
||||||
|
* 201:
|
||||||
|
* description: Computer created successfully
|
||||||
|
* 400:
|
||||||
|
* description: Invalid input
|
||||||
|
* 401:
|
||||||
|
* description: Unauthorized
|
||||||
|
* 403:
|
||||||
|
* description: Forbidden
|
||||||
|
* 500:
|
||||||
|
* description: Server error
|
||||||
|
*/
|
||||||
|
app.post("/api/connections/:connectionId/ad-computers", authenticateApiToken, requirePermission(PERMISSIONS.CREATE_AD_COMPUTERS), async (req: Request, res, next) => {
|
||||||
|
try {
|
||||||
|
const connectionId = parseInt(req.params.connectionId);
|
||||||
|
const {
|
||||||
|
name,
|
||||||
|
parentDN,
|
||||||
|
description,
|
||||||
|
dnsHostName,
|
||||||
|
operatingSystem,
|
||||||
|
operatingSystemVersion,
|
||||||
|
enabled = true
|
||||||
|
} = req.body;
|
||||||
|
|
||||||
|
// Basic validation
|
||||||
|
if (!name || !parentDN) {
|
||||||
|
return res.status(400).json({ message: "Computer name and parent DN are required" });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get connection
|
||||||
|
const connection = await storage.getLdapConnection(connectionId);
|
||||||
|
if (!connection) {
|
||||||
|
return res.status(404).json({ message: "LDAP connection not found" });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the DN for the new computer
|
||||||
|
const computerDN = `CN=${name},${parentDN}`;
|
||||||
|
|
||||||
|
// The sAMAccountName needs to end with $
|
||||||
|
const sAMAccountName = name.endsWith('$') ? name : `${name}$`;
|
||||||
|
|
||||||
|
// Create the userAccountControl value
|
||||||
|
// 4096 = WORKSTATION_TRUST_ACCOUNT
|
||||||
|
// 2 = ACCOUNTDISABLE (if not enabled)
|
||||||
|
const userAccountControl = enabled ? 4096 : 4098;
|
||||||
|
|
||||||
|
// Set the dnsHostName if not provided
|
||||||
|
const actualDnsHostName = dnsHostName || `${name}.${connection.domain}`;
|
||||||
|
|
||||||
|
// Attributes for the new computer
|
||||||
|
const computerAttributes: {
|
||||||
|
objectClass: string[];
|
||||||
|
cn: string;
|
||||||
|
sAMAccountName: string;
|
||||||
|
userAccountControl: string;
|
||||||
|
description: string;
|
||||||
|
dNSHostName: string;
|
||||||
|
operatingSystem?: string;
|
||||||
|
operatingSystemVersion?: string;
|
||||||
|
} = {
|
||||||
|
objectClass: ['top', 'computer'],
|
||||||
|
cn: name,
|
||||||
|
sAMAccountName: sAMAccountName,
|
||||||
|
userAccountControl: userAccountControl.toString(),
|
||||||
|
description: description || '',
|
||||||
|
dNSHostName: actualDnsHostName
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add operating system information if provided
|
||||||
|
if (operatingSystem) {
|
||||||
|
computerAttributes.operatingSystem = operatingSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (operatingSystemVersion) {
|
||||||
|
computerAttributes.operatingSystemVersion = operatingSystemVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the computer in AD
|
||||||
|
await ldapClient.createEntry(connectionId, computerDN, computerAttributes);
|
||||||
|
|
||||||
|
// Search for the newly created computer to get its attributes
|
||||||
|
const searchResults = await ldapClient.searchComputers(connectionId, `(&(objectClass=computer)(cn=${name}))`, [
|
||||||
|
'objectGUID', 'distinguishedName', 'canonicalName', 'cn', 'sAMAccountName', 'description',
|
||||||
|
'dNSHostName', 'operatingSystem', 'operatingSystemVersion', 'userAccountControl'
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!searchResults || searchResults.length === 0) {
|
||||||
|
return res.status(500).json({ message: "Computer created but could not retrieve details" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const adComputer = searchResults[0];
|
||||||
|
|
||||||
|
// Store in database
|
||||||
|
const storedComputer = await storage.createAdComputer({
|
||||||
|
connectionId,
|
||||||
|
objectGUID: adComputer.objectGUID,
|
||||||
|
distinguishedName: adComputer.distinguishedName,
|
||||||
|
canonicalName: adComputer.canonicalName,
|
||||||
|
cn: adComputer.cn,
|
||||||
|
name: adComputer.cn,
|
||||||
|
sAMAccountName: adComputer.sAMAccountName,
|
||||||
|
dnsHostName: adComputer.dNSHostName,
|
||||||
|
operatingSystem: adComputer.operatingSystem,
|
||||||
|
operatingSystemVersion: adComputer.operatingSystemVersion,
|
||||||
|
enabled: (parseInt(adComputer.userAccountControl) & 2) === 0, // Check if ACCOUNTDISABLE flag is not set
|
||||||
|
adProperties: adComputer // Store all attributes
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add audit log
|
||||||
|
await storage.createAuditLogEntry({
|
||||||
|
userId: req.user.id,
|
||||||
|
connectionId,
|
||||||
|
action: 'create',
|
||||||
|
targetId: storedComputer.id.toString(),
|
||||||
|
details: {
|
||||||
|
distinguishedName: computerDN,
|
||||||
|
enabled: enabled,
|
||||||
|
name: name
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
res.status(201).json(storedComputer);
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error creating AD computer:", err);
|
||||||
|
if (err.message && err.message.includes('Entry Already Exists')) {
|
||||||
|
return res.status(409).json({ message: "Computer already exists" });
|
||||||
|
}
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @swagger
|
* @swagger
|
||||||
|
|||||||
@@ -198,6 +198,7 @@ export const adComputers = pgTable("ad_computers", {
|
|||||||
canonicalName: text("canonical_name"),
|
canonicalName: text("canonical_name"),
|
||||||
cn: text("cn"),
|
cn: text("cn"),
|
||||||
name: text("name").notNull(),
|
name: text("name").notNull(),
|
||||||
|
sAMAccountName: text("sam_account_name"),
|
||||||
dnsHostName: text("dns_host_name"),
|
dnsHostName: text("dns_host_name"),
|
||||||
operatingSystem: text("operating_system"),
|
operatingSystem: text("operating_system"),
|
||||||
operatingSystemVersion: text("operating_system_version"),
|
operatingSystemVersion: text("operating_system_version"),
|
||||||
|
|||||||
Reference in New Issue
Block a user