mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 15:27:46 +00:00
feat: secret reference graph for understanding how its pulled
This commit is contained in:
Generated
+111
-115
@@ -5852,12 +5852,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@probot/pino": {
|
"node_modules/@probot/pino": {
|
||||||
"version": "2.4.0",
|
"version": "2.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@probot/pino/-/pino-2.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/@probot/pino/-/pino-2.5.0.tgz",
|
||||||
"integrity": "sha512-KUJ3eK2zLrPny7idWm9eQbBNhCJUjm1A1ttA6U4qiR2/ONWSffVlvr8oR26L59sVhoDkv1DOGmGPZS/bvSFisw==",
|
"integrity": "sha512-I7zI6MWP1wz9qvTY8U3wOWeRXY2NiuTDqf91v/LQl9oiffUHl+Z1YelRvNcvHbaUo/GK7E1mJr+Sw4dHuSGxpg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sentry/node": "^6.0.0",
|
"@sentry/node": "^7.119.2",
|
||||||
"pino-pretty": "^6.0.0",
|
"pino-pretty": "^6.0.0",
|
||||||
"pump": "^3.0.0",
|
"pump": "^3.0.0",
|
||||||
"readable-stream": "^3.6.0",
|
"readable-stream": "^3.6.0",
|
||||||
@@ -6147,118 +6147,85 @@
|
|||||||
"win32"
|
"win32"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"node_modules/@sentry-internal/tracing": {
|
||||||
|
"version": "7.119.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.119.2.tgz",
|
||||||
|
"integrity": "sha512-V2W+STWrafyGJhQv3ulMFXYDwWHiU6wHQAQBShsHVACiFaDrJ2kPRet38FKv4dMLlLlP2xN+ss2e5zv3tYlTiQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@sentry/core": "7.119.2",
|
||||||
|
"@sentry/types": "7.119.2",
|
||||||
|
"@sentry/utils": "7.119.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@sentry/core": {
|
"node_modules/@sentry/core": {
|
||||||
"version": "6.19.7",
|
"version": "7.119.2",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.19.7.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.119.2.tgz",
|
||||||
"integrity": "sha512-tOfZ/umqB2AcHPGbIrsFLcvApdTm9ggpi/kQZFkej7kMphjT+SGBiQfYtjyg9jcRW+ilAR4JXC9BGKsdEQ+8Vw==",
|
"integrity": "sha512-hQr3d2yWq/2lMvoyBPOwXw1IHqTrCjOsU1vYKhAa6w9vGbJZFGhKGGE2KEi/92c3gqGn+gW/PC7cV6waCTDuVA==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sentry/hub": "6.19.7",
|
"@sentry/types": "7.119.2",
|
||||||
"@sentry/minimal": "6.19.7",
|
"@sentry/utils": "7.119.2"
|
||||||
"@sentry/types": "6.19.7",
|
|
||||||
"@sentry/utils": "6.19.7",
|
|
||||||
"tslib": "^1.9.3"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sentry/core/node_modules/tslib": {
|
"node_modules/@sentry/integrations": {
|
||||||
"version": "1.14.1",
|
"version": "7.119.2",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-7.119.2.tgz",
|
||||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
"integrity": "sha512-dCuXKvbUE3gXVVa696SYMjlhSP6CxpMH/gl4Jk26naEB8Xjsn98z/hqEoXLg6Nab73rjR9c/9AdKqBbwVMHyrQ==",
|
||||||
},
|
"license": "MIT",
|
||||||
"node_modules/@sentry/hub": {
|
|
||||||
"version": "6.19.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.19.7.tgz",
|
|
||||||
"integrity": "sha512-y3OtbYFAqKHCWezF0EGGr5lcyI2KbaXW2Ik7Xp8Mu9TxbSTuwTe4rTntwg8ngPjUQU3SUHzgjqVB8qjiGqFXCA==",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sentry/types": "6.19.7",
|
"@sentry/core": "7.119.2",
|
||||||
"@sentry/utils": "6.19.7",
|
"@sentry/types": "7.119.2",
|
||||||
"tslib": "^1.9.3"
|
"@sentry/utils": "7.119.2",
|
||||||
|
"localforage": "^1.8.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sentry/hub/node_modules/tslib": {
|
|
||||||
"version": "1.14.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
|
||||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
|
||||||
},
|
|
||||||
"node_modules/@sentry/minimal": {
|
|
||||||
"version": "6.19.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.19.7.tgz",
|
|
||||||
"integrity": "sha512-wcYmSJOdvk6VAPx8IcmZgN08XTXRwRtB1aOLZm+MVHjIZIhHoBGZJYTVQS/BWjldsamj2cX3YGbGXNunaCfYJQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"@sentry/hub": "6.19.7",
|
|
||||||
"@sentry/types": "6.19.7",
|
|
||||||
"tslib": "^1.9.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@sentry/minimal/node_modules/tslib": {
|
|
||||||
"version": "1.14.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
|
||||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
|
||||||
},
|
|
||||||
"node_modules/@sentry/node": {
|
"node_modules/@sentry/node": {
|
||||||
"version": "6.19.7",
|
"version": "7.119.2",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/node/-/node-6.19.7.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.119.2.tgz",
|
||||||
"integrity": "sha512-gtmRC4dAXKODMpHXKfrkfvyBL3cI8y64vEi3fDD046uqYcrWdgoQsffuBbxMAizc6Ez1ia+f0Flue6p15Qaltg==",
|
"integrity": "sha512-TPNnqxh+Myooe4jTyRiXrzrM2SH08R4+nrmBls4T7lKp2E5R/3mDSe/YTn5rRcUt1k1hPx1NgO/taG0DoS5cXA==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sentry/core": "6.19.7",
|
"@sentry-internal/tracing": "7.119.2",
|
||||||
"@sentry/hub": "6.19.7",
|
"@sentry/core": "7.119.2",
|
||||||
"@sentry/types": "6.19.7",
|
"@sentry/integrations": "7.119.2",
|
||||||
"@sentry/utils": "6.19.7",
|
"@sentry/types": "7.119.2",
|
||||||
"cookie": "^0.4.1",
|
"@sentry/utils": "7.119.2"
|
||||||
"https-proxy-agent": "^5.0.0",
|
|
||||||
"lru_map": "^0.3.3",
|
|
||||||
"tslib": "^1.9.3"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sentry/node/node_modules/cookie": {
|
|
||||||
"version": "0.4.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
|
|
||||||
"integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@sentry/node/node_modules/tslib": {
|
|
||||||
"version": "1.14.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
|
||||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
|
||||||
},
|
|
||||||
"node_modules/@sentry/types": {
|
"node_modules/@sentry/types": {
|
||||||
"version": "6.19.7",
|
"version": "7.119.2",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.19.7.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.119.2.tgz",
|
||||||
"integrity": "sha512-jH84pDYE+hHIbVnab3Hr+ZXr1v8QABfhx39KknxqKWr2l0oEItzepV0URvbEhB446lk/S/59230dlUUIBGsXbg==",
|
"integrity": "sha512-ydq1tWsdG7QW+yFaTp0gFaowMLNVikIqM70wxWNK+u98QzKnVY/3XTixxNLsUtnAB4Y+isAzFhrc6Vb5GFdFeg==",
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sentry/utils": {
|
"node_modules/@sentry/utils": {
|
||||||
"version": "6.19.7",
|
"version": "7.119.2",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.19.7.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.119.2.tgz",
|
||||||
"integrity": "sha512-z95ECmE3i9pbWoXQrD/7PgkBAzJYR+iXtPuTkpBjDKs86O3mT+PXOT3BAn79w2wkn7/i3vOGD2xVr1uiMl26dA==",
|
"integrity": "sha512-TLdUCvcNgzKP0r9YD7tgCL1PEUp42TObISridsPJ5rhpVGQJvpr+Six0zIkfDUxerLYWZoK8QMm9KgFlPLNQzA==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sentry/types": "6.19.7",
|
"@sentry/types": "7.119.2"
|
||||||
"tslib": "^1.9.3"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sentry/utils/node_modules/tslib": {
|
|
||||||
"version": "1.14.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
|
||||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
|
||||||
},
|
|
||||||
"node_modules/@serdnam/pino-cloudwatch-transport": {
|
"node_modules/@serdnam/pino-cloudwatch-transport": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/@serdnam/pino-cloudwatch-transport/-/pino-cloudwatch-transport-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@serdnam/pino-cloudwatch-transport/-/pino-cloudwatch-transport-1.0.4.tgz",
|
||||||
@@ -9728,9 +9695,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/cookie": {
|
"node_modules/cookie": {
|
||||||
"version": "0.6.0",
|
"version": "0.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
|
||||||
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
|
"integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
@@ -10863,9 +10830,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/express": {
|
"node_modules/express": {
|
||||||
"version": "4.21.0",
|
"version": "4.21.1",
|
||||||
"resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz",
|
"resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz",
|
||||||
"integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==",
|
"integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"accepts": "~1.3.8",
|
"accepts": "~1.3.8",
|
||||||
@@ -10873,7 +10840,7 @@
|
|||||||
"body-parser": "1.20.3",
|
"body-parser": "1.20.3",
|
||||||
"content-disposition": "0.5.4",
|
"content-disposition": "0.5.4",
|
||||||
"content-type": "~1.0.4",
|
"content-type": "~1.0.4",
|
||||||
"cookie": "0.6.0",
|
"cookie": "0.7.1",
|
||||||
"cookie-signature": "1.0.6",
|
"cookie-signature": "1.0.6",
|
||||||
"debug": "2.6.9",
|
"debug": "2.6.9",
|
||||||
"depd": "2.0.0",
|
"depd": "2.0.0",
|
||||||
@@ -10905,12 +10872,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/express-session": {
|
"node_modules/express-session": {
|
||||||
"version": "1.18.0",
|
"version": "1.18.1",
|
||||||
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.1.tgz",
|
||||||
"integrity": "sha512-m93QLWr0ju+rOwApSsyso838LQwgfs44QtOP/WBiwtAgPIo/SAh1a5c6nn2BR6mFNZehTpqKDESzP+fRHVbxwQ==",
|
"integrity": "sha512-a5mtTqEaZvBCL9A9aqkrtfz+3SMDhOVUnjafjo+s7A9Txkq+SVX2DLvSp1Zrv4uCXa3lMSK3viWnh9Gg07PBUA==",
|
||||||
|
"license": "MIT",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cookie": "0.6.0",
|
"cookie": "0.7.2",
|
||||||
"cookie-signature": "1.0.7",
|
"cookie-signature": "1.0.7",
|
||||||
"debug": "2.6.9",
|
"debug": "2.6.9",
|
||||||
"depd": "~2.0.0",
|
"depd": "~2.0.0",
|
||||||
@@ -10944,6 +10912,15 @@
|
|||||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
|
"node_modules/express/node_modules/cookie": {
|
||||||
|
"version": "0.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
|
||||||
|
"integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/express/node_modules/cookie-signature": {
|
"node_modules/express/node_modules/cookie-signature": {
|
||||||
"version": "1.0.6",
|
"version": "1.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||||
@@ -12424,6 +12401,12 @@
|
|||||||
"integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
|
"integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/immediate": {
|
||||||
|
"version": "3.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
|
||||||
|
"integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/import-fresh": {
|
"node_modules/import-fresh": {
|
||||||
"version": "3.3.0",
|
"version": "3.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
||||||
@@ -13420,13 +13403,22 @@
|
|||||||
"libsodium": "^0.7.13"
|
"libsodium": "^0.7.13"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/lie": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"immediate": "~3.0.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/light-my-request": {
|
"node_modules/light-my-request": {
|
||||||
"version": "5.13.0",
|
"version": "5.14.0",
|
||||||
"resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-5.13.0.tgz",
|
"resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-5.14.0.tgz",
|
||||||
"integrity": "sha512-9IjUN9ZyCS9pTG+KqTDEQo68Sui2lHsYBrfMyVUTTZ3XhH8PMZq7xO94Kr+eP9dhi/kcKsx4N41p2IXEBil1pQ==",
|
"integrity": "sha512-aORPWntbpH5esaYpGOOmri0OHDOe3wC5M2MQxZ9dvMLZm6DnaAn0kJlcbU9hwsQgLzmZyReKwFwwPkR+nHu5kA==",
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cookie": "^0.6.0",
|
"cookie": "^0.7.0",
|
||||||
"process-warning": "^3.0.0",
|
"process-warning": "^3.0.0",
|
||||||
"set-cookie-parser": "^2.4.1"
|
"set-cookie-parser": "^2.4.1"
|
||||||
}
|
}
|
||||||
@@ -13505,6 +13497,15 @@
|
|||||||
"url": "https://github.com/sponsors/antfu"
|
"url": "https://github.com/sponsors/antfu"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/localforage": {
|
||||||
|
"version": "1.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz",
|
||||||
|
"integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"lie": "3.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/locate-path": {
|
"node_modules/locate-path": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
|
||||||
@@ -13632,11 +13633,6 @@
|
|||||||
"get-func-name": "^2.0.1"
|
"get-func-name": "^2.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/lru_map": {
|
|
||||||
"version": "0.3.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz",
|
|
||||||
"integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ=="
|
|
||||||
},
|
|
||||||
"node_modules/lru-cache": {
|
"node_modules/lru-cache": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||||
@@ -15261,9 +15257,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/picocolors": {
|
"node_modules/picocolors": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||||
"integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==",
|
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
@@ -18865,9 +18861,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vite": {
|
"node_modules/vite": {
|
||||||
"version": "5.4.8",
|
"version": "5.4.9",
|
||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.9.tgz",
|
||||||
"integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==",
|
"integrity": "sha512-20OVpJHh0PAM0oSOELa5GaZNWeDjcAvQjGXy2Uyr+Tp+/D2/Hdz6NLgpJLsarPTA2QJ6v8mX2P1ZfbsSKvdMkg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -669,6 +669,12 @@ export const RAW_SECRETS = {
|
|||||||
type: "The type of the secret to delete.",
|
type: "The type of the secret to delete.",
|
||||||
projectSlug: "The slug of the project to delete the secret in.",
|
projectSlug: "The slug of the project to delete the secret in.",
|
||||||
workspaceId: "The ID of the project where the secret is located."
|
workspaceId: "The ID of the project where the secret is located."
|
||||||
|
},
|
||||||
|
GET_REFERENCE_TREE: {
|
||||||
|
secretName: "The name of the secret to get.",
|
||||||
|
workspaceId: "The ID of the project to get the secret from.",
|
||||||
|
environment: "The slug of the environment to get the secret from.",
|
||||||
|
secretPath: "The path of the secret to get."
|
||||||
}
|
}
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,18 @@ import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types";
|
|||||||
|
|
||||||
import { secretRawSchema } from "../sanitizedSchemas";
|
import { secretRawSchema } from "../sanitizedSchemas";
|
||||||
|
|
||||||
|
const SecretReferenceNode = z.object({
|
||||||
|
key: z.string(),
|
||||||
|
value: z.string().optional(),
|
||||||
|
environment: z.string(),
|
||||||
|
secretPath: z.string()
|
||||||
|
});
|
||||||
|
type TSecretReferenceNode = z.infer<typeof SecretReferenceNode> & { children: TSecretReferenceNode[] };
|
||||||
|
|
||||||
|
const SecretReferenceNodeTree: z.ZodType<TSecretReferenceNode> = SecretReferenceNode.extend({
|
||||||
|
children: z.lazy(() => SecretReferenceNodeTree.array())
|
||||||
|
});
|
||||||
|
|
||||||
export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||||
server.route({
|
server.route({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@@ -2102,6 +2114,58 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
method: "GET",
|
||||||
|
url: "/raw/:secretName/secret-reference-tree",
|
||||||
|
config: {
|
||||||
|
rateLimit: secretsLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
description: "Get secret reference tree",
|
||||||
|
security: [
|
||||||
|
{
|
||||||
|
bearerAuth: []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
params: z.object({
|
||||||
|
secretName: z.string().trim().describe(RAW_SECRETS.GET_REFERENCE_TREE.secretName)
|
||||||
|
}),
|
||||||
|
querystring: z.object({
|
||||||
|
workspaceId: z.string().trim().describe(RAW_SECRETS.GET_REFERENCE_TREE.workspaceId),
|
||||||
|
environment: z.string().trim().describe(RAW_SECRETS.GET_REFERENCE_TREE.environment),
|
||||||
|
secretPath: z
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.default("/")
|
||||||
|
.transform(removeTrailingSlash)
|
||||||
|
.describe(RAW_SECRETS.GET_REFERENCE_TREE.secretPath)
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
tree: SecretReferenceNodeTree,
|
||||||
|
value: z.string().optional()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const { secretName } = req.params;
|
||||||
|
const { secretPath, environment, workspaceId } = req.query;
|
||||||
|
const { tree, value } = await server.services.secret.getSecretReferenceTree({
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
projectId: workspaceId,
|
||||||
|
secretName,
|
||||||
|
secretPath,
|
||||||
|
environment
|
||||||
|
});
|
||||||
|
|
||||||
|
return { tree, value };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
server.route({
|
server.route({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
url: "/backfill-secret-references",
|
url: "/backfill-secret-references",
|
||||||
|
|||||||
@@ -371,6 +371,13 @@ const formatMultiValueEnv = (val?: string) => {
|
|||||||
return `"${val.replace(/\n/g, "\\n")}"`;
|
return `"${val.replace(/\n/g, "\\n")}"`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type TSecretReferenceTraceNode = {
|
||||||
|
key: string;
|
||||||
|
value?: string;
|
||||||
|
environment: string;
|
||||||
|
secretPath: string;
|
||||||
|
children: TSecretReferenceTraceNode[];
|
||||||
|
};
|
||||||
type TInterpolateSecretArg = {
|
type TInterpolateSecretArg = {
|
||||||
projectId: string;
|
projectId: string;
|
||||||
decryptSecretValue: (encryptedValue?: Buffer | null) => string | undefined;
|
decryptSecretValue: (encryptedValue?: Buffer | null) => string | undefined;
|
||||||
@@ -412,14 +419,21 @@ export const expandSecretReferencesFactory = ({
|
|||||||
return secretCache[cacheKey][secretKey] || { value: "", tags: [] };
|
return secretCache[cacheKey][secretKey] || { value: "", tags: [] };
|
||||||
};
|
};
|
||||||
|
|
||||||
const recursivelyExpandSecret = async (dto: { value?: string; secretPath: string; environment: string }) => {
|
const recursivelyExpandSecret = async (dto: {
|
||||||
if (!dto.value) return "";
|
value?: string;
|
||||||
|
secretPath: string;
|
||||||
|
environment: string;
|
||||||
|
shouldStackTrace?: boolean;
|
||||||
|
}) => {
|
||||||
|
const stackTrace = { ...dto, key: "root", children: [] } as TSecretReferenceTraceNode;
|
||||||
|
|
||||||
const stack = [{ ...dto, depth: 0 }];
|
if (!dto.value) return { expandedValue: "", stackTrace };
|
||||||
|
const stack = [{ ...dto, depth: 0, trace: stackTrace }];
|
||||||
let expandedValue = dto.value;
|
let expandedValue = dto.value;
|
||||||
|
|
||||||
while (stack.length) {
|
while (stack.length) {
|
||||||
const { value, secretPath, environment, depth } = stack.pop()!;
|
const { value, secretPath, environment, depth, trace } = stack.pop()!;
|
||||||
|
|
||||||
// eslint-disable-next-line no-continue
|
// eslint-disable-next-line no-continue
|
||||||
if (depth > MAX_SECRET_REFERENCE_DEPTH) continue;
|
if (depth > MAX_SECRET_REFERENCE_DEPTH) continue;
|
||||||
const refs = value?.match(INTERPOLATION_SYNTAX_REG);
|
const refs = value?.match(INTERPOLATION_SYNTAX_REG);
|
||||||
@@ -432,6 +446,11 @@ export const expandSecretReferencesFactory = ({
|
|||||||
// eslint-disable-next-line no-continue
|
// eslint-disable-next-line no-continue
|
||||||
if (!entities.length) continue;
|
if (!entities.length) continue;
|
||||||
|
|
||||||
|
let referredSecretPath = "";
|
||||||
|
let referredSecretKey = "";
|
||||||
|
let referredSecretEnvironmentSlug = "";
|
||||||
|
let referredSecretValue = "";
|
||||||
|
|
||||||
if (entities.length === 1) {
|
if (entities.length === 1) {
|
||||||
const [secretKey] = entities;
|
const [secretKey] = entities;
|
||||||
|
|
||||||
@@ -444,17 +463,11 @@ export const expandSecretReferencesFactory = ({
|
|||||||
|
|
||||||
const cacheKey = getCacheUniqueKey(environment, secretPath);
|
const cacheKey = getCacheUniqueKey(environment, secretPath);
|
||||||
secretCache[cacheKey][secretKey] = referredValue;
|
secretCache[cacheKey][secretKey] = referredValue;
|
||||||
if (INTERPOLATION_SYNTAX_REG.test(referredValue.value)) {
|
|
||||||
stack.push({
|
referredSecretValue = referredValue.value;
|
||||||
value: referredValue.value,
|
referredSecretKey = secretKey;
|
||||||
secretPath,
|
referredSecretPath = secretPath;
|
||||||
environment,
|
referredSecretEnvironmentSlug = environment;
|
||||||
depth: depth + 1
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (referredValue) {
|
|
||||||
expandedValue = expandedValue.replaceAll(interpolationSyntax, referredValue.value);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
const secretReferenceEnvironment = entities[0];
|
const secretReferenceEnvironment = entities[0];
|
||||||
const secretReferencePath = path.join("/", ...entities.slice(1, entities.length - 1));
|
const secretReferencePath = path.join("/", ...entities.slice(1, entities.length - 1));
|
||||||
@@ -469,24 +482,42 @@ export const expandSecretReferencesFactory = ({
|
|||||||
|
|
||||||
const cacheKey = getCacheUniqueKey(secretReferenceEnvironment, secretReferencePath);
|
const cacheKey = getCacheUniqueKey(secretReferenceEnvironment, secretReferencePath);
|
||||||
secretCache[cacheKey][secretReferenceKey] = referedValue;
|
secretCache[cacheKey][secretReferenceKey] = referedValue;
|
||||||
if (INTERPOLATION_SYNTAX_REG.test(referedValue.value)) {
|
|
||||||
stack.push({
|
|
||||||
value: referedValue.value,
|
|
||||||
secretPath: secretReferencePath,
|
|
||||||
environment: secretReferenceEnvironment,
|
|
||||||
depth: depth + 1
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (referedValue) {
|
referredSecretValue = referedValue.value;
|
||||||
expandedValue = expandedValue.replaceAll(interpolationSyntax, referedValue.value);
|
referredSecretKey = secretReferenceKey;
|
||||||
|
referredSecretPath = secretReferencePath;
|
||||||
|
referredSecretEnvironmentSlug = secretReferenceEnvironment;
|
||||||
|
}
|
||||||
|
|
||||||
|
const node = {
|
||||||
|
value: referredSecretValue,
|
||||||
|
secretPath: referredSecretPath,
|
||||||
|
environment: referredSecretEnvironmentSlug,
|
||||||
|
depth: depth + 1,
|
||||||
|
trace
|
||||||
|
};
|
||||||
|
|
||||||
|
const shouldExpandMore = INTERPOLATION_SYNTAX_REG.test(referredSecretValue);
|
||||||
|
if (dto.shouldStackTrace) {
|
||||||
|
const stackTraceNode = { ...node, children: [], key: referredSecretKey, trace: null };
|
||||||
|
trace?.children.push(stackTraceNode);
|
||||||
|
// if stack trace this would be child node
|
||||||
|
if (shouldExpandMore) {
|
||||||
|
stack.push({ ...node, trace: stackTraceNode });
|
||||||
}
|
}
|
||||||
|
} else if (shouldExpandMore) {
|
||||||
|
// if no stack trace is needed we just keep going with root node
|
||||||
|
stack.push(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (referredSecretValue) {
|
||||||
|
expandedValue = expandedValue.replaceAll(interpolationSyntax, referredSecretValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return expandedValue;
|
return { expandedValue, stackTrace };
|
||||||
};
|
};
|
||||||
|
|
||||||
const expandSecret = async (inputSecret: {
|
const expandSecret = async (inputSecret: {
|
||||||
@@ -500,10 +531,21 @@ export const expandSecretReferencesFactory = ({
|
|||||||
const shouldExpand = Boolean(inputSecret.value?.match(INTERPOLATION_SYNTAX_REG));
|
const shouldExpand = Boolean(inputSecret.value?.match(INTERPOLATION_SYNTAX_REG));
|
||||||
if (!shouldExpand) return inputSecret.value;
|
if (!shouldExpand) return inputSecret.value;
|
||||||
|
|
||||||
const expandedSecretValue = await recursivelyExpandSecret(inputSecret);
|
const { expandedValue } = await recursivelyExpandSecret(inputSecret);
|
||||||
return inputSecret.skipMultilineEncoding ? formatMultiValueEnv(expandedSecretValue) : expandedSecretValue;
|
|
||||||
|
return inputSecret.skipMultilineEncoding ? formatMultiValueEnv(expandedValue) : expandedValue;
|
||||||
};
|
};
|
||||||
return expandSecret;
|
|
||||||
|
const getExpandedSecretStackTrace = async (inputSecret: {
|
||||||
|
value?: string;
|
||||||
|
secretPath: string;
|
||||||
|
environment: string;
|
||||||
|
}) => {
|
||||||
|
const { stackTrace } = await recursivelyExpandSecret({ ...inputSecret, shouldStackTrace: true });
|
||||||
|
return stackTrace;
|
||||||
|
};
|
||||||
|
|
||||||
|
return { expandSecretReferences: expandSecret, getExpandedSecretStackTrace };
|
||||||
};
|
};
|
||||||
|
|
||||||
export const reshapeBridgeSecret = (
|
export const reshapeBridgeSecret = (
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import {
|
|||||||
TDeleteManySecretDTO,
|
TDeleteManySecretDTO,
|
||||||
TDeleteSecretDTO,
|
TDeleteSecretDTO,
|
||||||
TGetASecretDTO,
|
TGetASecretDTO,
|
||||||
|
TGetSecretReferencesTreeDTO,
|
||||||
TGetSecretsDTO,
|
TGetSecretsDTO,
|
||||||
TGetSecretVersionsDTO,
|
TGetSecretVersionsDTO,
|
||||||
TMoveSecretsDTO,
|
TMoveSecretsDTO,
|
||||||
@@ -815,7 +816,7 @@ export const secretV2BridgeServiceFactory = ({
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
const expandSecretReferences = expandSecretReferencesFactory({
|
const { expandSecretReferences } = expandSecretReferencesFactory({
|
||||||
projectId,
|
projectId,
|
||||||
folderDAL,
|
folderDAL,
|
||||||
secretDAL,
|
secretDAL,
|
||||||
@@ -965,7 +966,7 @@ export const secretV2BridgeServiceFactory = ({
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
const expandSecretReferences = expandSecretReferencesFactory({
|
const { expandSecretReferences } = expandSecretReferencesFactory({
|
||||||
projectId,
|
projectId,
|
||||||
folderDAL,
|
folderDAL,
|
||||||
secretDAL,
|
secretDAL,
|
||||||
@@ -1032,6 +1033,7 @@ export const secretV2BridgeServiceFactory = ({
|
|||||||
value: secretValue,
|
value: secretValue,
|
||||||
skipMultilineEncoding: secret.skipMultilineEncoding
|
skipMultilineEncoding: secret.skipMultilineEncoding
|
||||||
});
|
});
|
||||||
|
|
||||||
secretValue = expandedSecretValue || "";
|
secretValue = expandedSecretValue || "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1928,6 +1930,77 @@ export const secretV2BridgeServiceFactory = ({
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getSecretReferenceTree = async ({
|
||||||
|
environment,
|
||||||
|
secretPath,
|
||||||
|
projectId,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
actorOrgId,
|
||||||
|
secretName,
|
||||||
|
actorAuthMethod
|
||||||
|
}: TGetSecretReferencesTreeDTO) => {
|
||||||
|
const { permission } = await permissionService.getProjectPermission(
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
projectId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
);
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionActions.Read,
|
||||||
|
subject(ProjectPermissionSub.Secrets, { environment, secretPath })
|
||||||
|
);
|
||||||
|
|
||||||
|
const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath);
|
||||||
|
if (!folder)
|
||||||
|
throw new NotFoundError({
|
||||||
|
message: "Folder not found for the given environment slug & secret path",
|
||||||
|
name: "Create secret"
|
||||||
|
});
|
||||||
|
const folderId = folder.id;
|
||||||
|
|
||||||
|
const { decryptor: secretManagerDecryptor } = await kmsService.createCipherPairWithDataKey({
|
||||||
|
type: KmsDataKey.SecretManager,
|
||||||
|
projectId
|
||||||
|
});
|
||||||
|
|
||||||
|
const secret = await secretDAL.findOne({
|
||||||
|
folderId,
|
||||||
|
key: secretName,
|
||||||
|
type: SecretType.Shared
|
||||||
|
});
|
||||||
|
|
||||||
|
const secretValue = secret.encryptedValue
|
||||||
|
? secretManagerDecryptor({ cipherTextBlob: secret.encryptedValue }).toString()
|
||||||
|
: "";
|
||||||
|
|
||||||
|
const { getExpandedSecretStackTrace, expandSecretReferences } = expandSecretReferencesFactory({
|
||||||
|
projectId,
|
||||||
|
folderDAL,
|
||||||
|
secretDAL,
|
||||||
|
decryptSecretValue: (value) => (value ? secretManagerDecryptor({ cipherTextBlob: value }).toString() : undefined),
|
||||||
|
canExpandValue: (expandEnvironment, expandSecretPath) =>
|
||||||
|
permission.can(
|
||||||
|
ProjectPermissionActions.Read,
|
||||||
|
subject(ProjectPermissionSub.Secrets, { environment: expandEnvironment, secretPath: expandSecretPath })
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
const tree = await getExpandedSecretStackTrace({
|
||||||
|
environment,
|
||||||
|
secretPath,
|
||||||
|
value: secretValue
|
||||||
|
});
|
||||||
|
const value = await expandSecretReferences({
|
||||||
|
environment,
|
||||||
|
secretPath,
|
||||||
|
value: secretValue
|
||||||
|
});
|
||||||
|
return { tree, value };
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
createSecret,
|
createSecret,
|
||||||
deleteSecret,
|
deleteSecret,
|
||||||
@@ -1942,6 +2015,7 @@ export const secretV2BridgeServiceFactory = ({
|
|||||||
moveSecrets,
|
moveSecrets,
|
||||||
getSecretsCount,
|
getSecretsCount,
|
||||||
getSecretsCountMultiEnv,
|
getSecretsCountMultiEnv,
|
||||||
getSecretsMultiEnv
|
getSecretsMultiEnv,
|
||||||
|
getSecretReferenceTree
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -278,3 +278,10 @@ export type TAttachSecretTagsDTO = {
|
|||||||
secretPath: string;
|
secretPath: string;
|
||||||
type: SecretType;
|
type: SecretType;
|
||||||
} & Omit<TProjectPermission, "projectId">;
|
} & Omit<TProjectPermission, "projectId">;
|
||||||
|
|
||||||
|
export type TGetSecretReferencesTreeDTO = {
|
||||||
|
projectId: string;
|
||||||
|
secretName: string;
|
||||||
|
environment: string;
|
||||||
|
secretPath: string;
|
||||||
|
} & Omit<TProjectPermission, "projectId">;
|
||||||
|
|||||||
@@ -299,7 +299,7 @@ export const secretQueueFactory = ({
|
|||||||
);
|
);
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
const expandSecretReferences = expandSecretReferencesFactory({
|
const { expandSecretReferences } = expandSecretReferencesFactory({
|
||||||
decryptSecretValue: dto.decryptor,
|
decryptSecretValue: dto.decryptor,
|
||||||
secretDAL: secretV2BridgeDAL,
|
secretDAL: secretV2BridgeDAL,
|
||||||
folderDAL,
|
folderDAL,
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import { TSecretImportDALFactory } from "../secret-import/secret-import-dal";
|
|||||||
import { fnSecretsFromImports } from "../secret-import/secret-import-fns";
|
import { fnSecretsFromImports } from "../secret-import/secret-import-fns";
|
||||||
import { TSecretTagDALFactory } from "../secret-tag/secret-tag-dal";
|
import { TSecretTagDALFactory } from "../secret-tag/secret-tag-dal";
|
||||||
import { TSecretV2BridgeServiceFactory } from "../secret-v2-bridge/secret-v2-bridge-service";
|
import { TSecretV2BridgeServiceFactory } from "../secret-v2-bridge/secret-v2-bridge-service";
|
||||||
|
import { TGetSecretReferencesTreeDTO } from "../secret-v2-bridge/secret-v2-bridge-types";
|
||||||
import { TSecretDALFactory } from "./secret-dal";
|
import { TSecretDALFactory } from "./secret-dal";
|
||||||
import {
|
import {
|
||||||
decryptSecretRaw,
|
decryptSecretRaw,
|
||||||
@@ -1099,6 +1100,18 @@ export const secretServiceFactory = ({
|
|||||||
return secrets;
|
return secrets;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getSecretReferenceTree = async (dto: TGetSecretReferencesTreeDTO) => {
|
||||||
|
const { shouldUseSecretV2Bridge } = await projectBotService.getBotKey(dto.projectId);
|
||||||
|
|
||||||
|
if (!shouldUseSecretV2Bridge)
|
||||||
|
throw new BadRequestError({
|
||||||
|
message: "Project version doesn't not support secret reference tree",
|
||||||
|
name: "SecretReferenceTreeNotSupported"
|
||||||
|
});
|
||||||
|
|
||||||
|
return secretV2BridgeService.getSecretReferenceTree(dto);
|
||||||
|
};
|
||||||
|
|
||||||
const getSecretsRaw = async ({
|
const getSecretsRaw = async ({
|
||||||
projectId,
|
projectId,
|
||||||
path,
|
path,
|
||||||
@@ -2857,6 +2870,7 @@ export const secretServiceFactory = ({
|
|||||||
startSecretV2Migration,
|
startSecretV2Migration,
|
||||||
getSecretsCount,
|
getSecretsCount,
|
||||||
getSecretsCountMultiEnv,
|
getSecretsCountMultiEnv,
|
||||||
getSecretsRawMultiEnv
|
getSecretsRawMultiEnv,
|
||||||
|
getSecretReferenceTree
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,4 +8,8 @@ export {
|
|||||||
useUpdateSecretBatch,
|
useUpdateSecretBatch,
|
||||||
useUpdateSecretV3
|
useUpdateSecretV3
|
||||||
} from "./mutations";
|
} from "./mutations";
|
||||||
export { useGetProjectSecrets, useGetProjectSecretsAllEnv, useGetSecretVersion } from "./queries";
|
export {
|
||||||
|
useGetProjectSecrets,
|
||||||
|
useGetProjectSecretsAllEnv,
|
||||||
|
useGetSecretReferenceTree,
|
||||||
|
useGetSecretVersion} from "./queries";
|
||||||
|
|||||||
@@ -17,14 +17,17 @@ import {
|
|||||||
SecretVersions,
|
SecretVersions,
|
||||||
TGetProjectSecretsAllEnvDTO,
|
TGetProjectSecretsAllEnvDTO,
|
||||||
TGetProjectSecretsDTO,
|
TGetProjectSecretsDTO,
|
||||||
TGetProjectSecretsKey
|
TGetProjectSecretsKey,
|
||||||
|
TGetSecretReferenceTreeDTO,
|
||||||
|
TSecretReferenceTraceNode
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
export const secretKeys = {
|
export const secretKeys = {
|
||||||
// this is also used in secretSnapshot part
|
// this is also used in secretSnapshot part
|
||||||
getProjectSecret: ({ workspaceId, environment, secretPath }: TGetProjectSecretsKey) =>
|
getProjectSecret: ({ workspaceId, environment, secretPath }: TGetProjectSecretsKey) =>
|
||||||
[{ workspaceId, environment, secretPath }, "secrets"] as const,
|
[{ workspaceId, environment, secretPath }, "secrets"] as const,
|
||||||
getSecretVersion: (secretId: string) => [{ secretId }, "secret-versions"] as const
|
getSecretVersion: (secretId: string) => [{ secretId }, "secret-versions"] as const,
|
||||||
|
getSecretReferenceTree: (dto: TGetSecretReferenceTreeDTO) => ["secret-reference-tree", dto]
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchProjectSecrets = async ({
|
export const fetchProjectSecrets = async ({
|
||||||
@@ -227,3 +230,33 @@ export const useGetSecretVersion = (dto: GetSecretVersionsDTO) =>
|
|||||||
return data.sort((a, b) => b.createdAt.localeCompare(a.createdAt));
|
return data.sort((a, b) => b.createdAt.localeCompare(a.createdAt));
|
||||||
}, [])
|
}, [])
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const fetchSecretReferenceTree = async ({
|
||||||
|
secretPath,
|
||||||
|
projectId,
|
||||||
|
secretKey,
|
||||||
|
environmentSlug
|
||||||
|
}: TGetSecretReferenceTreeDTO) => {
|
||||||
|
const { data } = await apiRequest.get<{ tree: TSecretReferenceTraceNode; value: string }>(
|
||||||
|
`/api/v3/secrets/raw/${secretKey}/secret-reference-tree`,
|
||||||
|
{
|
||||||
|
params: {
|
||||||
|
secretPath,
|
||||||
|
workspaceId: projectId,
|
||||||
|
environment: environmentSlug
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useGetSecretReferenceTree = (dto: TGetSecretReferenceTreeDTO) =>
|
||||||
|
useQuery({
|
||||||
|
enabled:
|
||||||
|
Boolean(dto.environmentSlug) &&
|
||||||
|
Boolean(dto.secretPath) &&
|
||||||
|
Boolean(dto.projectId) &&
|
||||||
|
Boolean(dto.secretKey),
|
||||||
|
queryKey: secretKeys.getSecretReferenceTree(dto),
|
||||||
|
queryFn: () => fetchSecretReferenceTree(dto)
|
||||||
|
});
|
||||||
|
|||||||
@@ -210,3 +210,18 @@ export type TMoveSecretsDTO = {
|
|||||||
secretIds: string[];
|
secretIds: string[];
|
||||||
shouldOverwrite: boolean;
|
shouldOverwrite: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type TGetSecretReferenceTreeDTO = {
|
||||||
|
secretKey: string;
|
||||||
|
secretPath: string;
|
||||||
|
environmentSlug: string;
|
||||||
|
projectId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TSecretReferenceTraceNode = {
|
||||||
|
key: string;
|
||||||
|
value?: string;
|
||||||
|
environment: string;
|
||||||
|
secretPath: string;
|
||||||
|
children: TSecretReferenceTraceNode[];
|
||||||
|
};
|
||||||
|
|||||||
+36
-2
@@ -7,6 +7,7 @@ import {
|
|||||||
faCircleDot,
|
faCircleDot,
|
||||||
faClock,
|
faClock,
|
||||||
faPlus,
|
faPlus,
|
||||||
|
faRoad,
|
||||||
faShare,
|
faShare,
|
||||||
faTag
|
faTag
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
@@ -28,6 +29,9 @@ import {
|
|||||||
FormControl,
|
FormControl,
|
||||||
IconButton,
|
IconButton,
|
||||||
Input,
|
Input,
|
||||||
|
Modal,
|
||||||
|
ModalContent,
|
||||||
|
ModalTrigger,
|
||||||
Switch,
|
Switch,
|
||||||
Tag,
|
Tag,
|
||||||
TextArea,
|
TextArea,
|
||||||
@@ -41,6 +45,7 @@ import { SecretV3RawSanitized, WsTag } from "@app/hooks/api/types";
|
|||||||
|
|
||||||
import { CreateReminderForm } from "./CreateReminderForm";
|
import { CreateReminderForm } from "./CreateReminderForm";
|
||||||
import { formSchema, SecretActionType, TFormSchema } from "./SecretListView.utils";
|
import { formSchema, SecretActionType, TFormSchema } from "./SecretListView.utils";
|
||||||
|
import { SecretReferenceTree } from "./SecretReferenceDetails";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
isOpen?: boolean;
|
isOpen?: boolean;
|
||||||
@@ -448,9 +453,38 @@ export const SecretDetailSidebar = ({
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="ml-1 flex items-center space-x-2">
|
<div className="ml-1 flex items-center space-x-4">
|
||||||
|
<ProjectPermissionCan
|
||||||
|
I={ProjectPermissionActions.Edit}
|
||||||
|
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||||
|
>
|
||||||
|
{(isAllowed) => (
|
||||||
|
<Modal>
|
||||||
|
<ModalTrigger asChild>
|
||||||
|
<Button
|
||||||
|
variant="outline_bg"
|
||||||
|
className="w-full px-2 py-1"
|
||||||
|
leftIcon={<FontAwesomeIcon icon={faRoad} />}
|
||||||
|
isDisabled={!isAllowed}
|
||||||
|
>
|
||||||
|
Reference tree
|
||||||
|
</Button>
|
||||||
|
</ModalTrigger>
|
||||||
|
<ModalContent
|
||||||
|
title="Secret Reference Tree"
|
||||||
|
subTitle="Shows the actual value and reference tree"
|
||||||
|
>
|
||||||
|
<SecretReferenceTree
|
||||||
|
secretPath={secretPath}
|
||||||
|
environment={environment}
|
||||||
|
secret={secret}
|
||||||
|
/>
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
||||||
|
)}
|
||||||
|
</ProjectPermissionCan>
|
||||||
<Button
|
<Button
|
||||||
className="px-2 py-1"
|
className="w-full px-2 py-1"
|
||||||
variant="outline_bg"
|
variant="outline_bg"
|
||||||
leftIcon={<FontAwesomeIcon icon={faShare} />}
|
leftIcon={<FontAwesomeIcon icon={faShare} />}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -16,7 +16,7 @@ import { WsTag } from "@app/hooks/api/types";
|
|||||||
import { AddShareSecretModal } from "@app/views/ShareSecretPage/components/AddShareSecretModal";
|
import { AddShareSecretModal } from "@app/views/ShareSecretPage/components/AddShareSecretModal";
|
||||||
|
|
||||||
import { useSelectedSecretActions, useSelectedSecrets } from "../../SecretMainPage.store";
|
import { useSelectedSecretActions, useSelectedSecrets } from "../../SecretMainPage.store";
|
||||||
import { SecretDetailSidebar } from "./SecretDetaiSidebar";
|
import { SecretDetailSidebar } from "./SecretDetailSidebar";
|
||||||
import { SecretItem } from "./SecretItem";
|
import { SecretItem } from "./SecretItem";
|
||||||
import { FontAwesomeSpriteSymbols } from "./SecretListView.utils";
|
import { FontAwesomeSpriteSymbols } from "./SecretListView.utils";
|
||||||
|
|
||||||
|
|||||||
+124
@@ -0,0 +1,124 @@
|
|||||||
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
import { FormControl, SecretInput, Tag, Tooltip } from "@app/components/v2";
|
||||||
|
import { useWorkspace } from "@app/context";
|
||||||
|
import { useGetSecretReferenceTree } from "@app/hooks/api";
|
||||||
|
import { SecretV3RawSanitized, TSecretReferenceTraceNode } from "@app/hooks/api/types";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
environment: string;
|
||||||
|
secretPath: string;
|
||||||
|
secret: SecretV3RawSanitized;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SecretReferenceNode = ({
|
||||||
|
node,
|
||||||
|
isRoot
|
||||||
|
}: {
|
||||||
|
node: TSecretReferenceTraceNode;
|
||||||
|
isRoot?: boolean;
|
||||||
|
}) => (
|
||||||
|
<div>
|
||||||
|
{isRoot ? (
|
||||||
|
<FormControl label="Reference value" className="sticky top-0 mb-0 bg-mineshaft-800">
|
||||||
|
<SecretInput
|
||||||
|
key="value-overriden"
|
||||||
|
isReadOnly
|
||||||
|
value={node.value}
|
||||||
|
containerClassName="text-bunker-300 hover:border-primary-400/50 border border-mineshaft-600 bg-bunker-800 px-2 py-1.5"
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
) : (
|
||||||
|
<div className="py-2 text-sm">
|
||||||
|
<div>
|
||||||
|
{node.key}
|
||||||
|
<Tooltip content={node.value}>
|
||||||
|
<span
|
||||||
|
className={twMerge(
|
||||||
|
"ml-2 rounded border border-gray-400 px-1 text-xs text-gray-400",
|
||||||
|
!node.value && "border-red-400 text-red-400"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{node.value ? "value" : "empty"}
|
||||||
|
</span>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
<div className="mt-2">
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
|
<div className="flex items-center">
|
||||||
|
<Tag
|
||||||
|
size="xs"
|
||||||
|
className="mr-0 flex items-center rounded-r-none border border-mineshaft-500"
|
||||||
|
>
|
||||||
|
<div>Environment</div>
|
||||||
|
</Tag>
|
||||||
|
<Tag
|
||||||
|
size="xs"
|
||||||
|
className="flex items-center rounded-l-none border border-mineshaft-500 bg-mineshaft-900 pl-1"
|
||||||
|
>
|
||||||
|
<div className="max-w-[150px] overflow-hidden text-ellipsis whitespace-nowrap">
|
||||||
|
{node.environment}
|
||||||
|
</div>
|
||||||
|
</Tag>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center">
|
||||||
|
<Tag
|
||||||
|
size="xs"
|
||||||
|
className="mr-0 flex items-center rounded-r-none border border-mineshaft-500"
|
||||||
|
>
|
||||||
|
<div>Secret Path</div>
|
||||||
|
</Tag>
|
||||||
|
<Tag
|
||||||
|
size="xs"
|
||||||
|
className="flex items-center rounded-l-none border border-mineshaft-500 bg-mineshaft-900 pl-1"
|
||||||
|
>
|
||||||
|
<div className="max-w-[150px] overflow-hidden text-ellipsis whitespace-nowrap">
|
||||||
|
{node.secretPath}
|
||||||
|
</div>
|
||||||
|
</Tag>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="w-full border-b border-gray-800 py-1" />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{node.children.length > 0 && (
|
||||||
|
<div className="border-l border-gray-600 pl-6 transition-all hover:border-primary-600">
|
||||||
|
{node.children.map((el, index) => (
|
||||||
|
<SecretReferenceNode node={el} key={`node-${node.key}-${index + 1}`} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const SecretReferenceTree = ({ secretPath, environment, secret }: Props) => {
|
||||||
|
const { currentWorkspace } = useWorkspace();
|
||||||
|
const projectId = currentWorkspace?.id || "";
|
||||||
|
|
||||||
|
const { data } = useGetSecretReferenceTree({
|
||||||
|
secretPath,
|
||||||
|
environmentSlug: environment,
|
||||||
|
projectId,
|
||||||
|
secretKey: secret?.key
|
||||||
|
});
|
||||||
|
|
||||||
|
const tree = data?.tree;
|
||||||
|
const secretValue = data?.value;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<FormControl label="Expanded value">
|
||||||
|
<SecretInput
|
||||||
|
key="value-overriden"
|
||||||
|
isReadOnly
|
||||||
|
value={secretValue}
|
||||||
|
containerClassName="text-bunker-300 hover:border-primary-400/50 border border-mineshaft-600 bg-bunker-800 px-2 py-1.5"
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<div className="max-h-80 overflow-auto">
|
||||||
|
{tree && <SecretReferenceNode node={tree} isRoot />}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user