mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat: secret reference graph for understanding how its pulled
This commit is contained in:
226
backend/package-lock.json
generated
226
backend/package-lock.json
generated
@@ -5852,12 +5852,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@probot/pino": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@probot/pino/-/pino-2.4.0.tgz",
|
||||
"integrity": "sha512-KUJ3eK2zLrPny7idWm9eQbBNhCJUjm1A1ttA6U4qiR2/ONWSffVlvr8oR26L59sVhoDkv1DOGmGPZS/bvSFisw==",
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@probot/pino/-/pino-2.5.0.tgz",
|
||||
"integrity": "sha512-I7zI6MWP1wz9qvTY8U3wOWeRXY2NiuTDqf91v/LQl9oiffUHl+Z1YelRvNcvHbaUo/GK7E1mJr+Sw4dHuSGxpg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@sentry/node": "^6.0.0",
|
||||
"@sentry/node": "^7.119.2",
|
||||
"pino-pretty": "^6.0.0",
|
||||
"pump": "^3.0.0",
|
||||
"readable-stream": "^3.6.0",
|
||||
@@ -6147,118 +6147,85 @@
|
||||
"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": {
|
||||
"version": "6.19.7",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.19.7.tgz",
|
||||
"integrity": "sha512-tOfZ/umqB2AcHPGbIrsFLcvApdTm9ggpi/kQZFkej7kMphjT+SGBiQfYtjyg9jcRW+ilAR4JXC9BGKsdEQ+8Vw==",
|
||||
"version": "7.119.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.119.2.tgz",
|
||||
"integrity": "sha512-hQr3d2yWq/2lMvoyBPOwXw1IHqTrCjOsU1vYKhAa6w9vGbJZFGhKGGE2KEi/92c3gqGn+gW/PC7cV6waCTDuVA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@sentry/hub": "6.19.7",
|
||||
"@sentry/minimal": "6.19.7",
|
||||
"@sentry/types": "6.19.7",
|
||||
"@sentry/utils": "6.19.7",
|
||||
"tslib": "^1.9.3"
|
||||
"@sentry/types": "7.119.2",
|
||||
"@sentry/utils": "7.119.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/core/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/hub": {
|
||||
"version": "6.19.7",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.19.7.tgz",
|
||||
"integrity": "sha512-y3OtbYFAqKHCWezF0EGGr5lcyI2KbaXW2Ik7Xp8Mu9TxbSTuwTe4rTntwg8ngPjUQU3SUHzgjqVB8qjiGqFXCA==",
|
||||
"node_modules/@sentry/integrations": {
|
||||
"version": "7.119.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-7.119.2.tgz",
|
||||
"integrity": "sha512-dCuXKvbUE3gXVVa696SYMjlhSP6CxpMH/gl4Jk26naEB8Xjsn98z/hqEoXLg6Nab73rjR9c/9AdKqBbwVMHyrQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@sentry/types": "6.19.7",
|
||||
"@sentry/utils": "6.19.7",
|
||||
"tslib": "^1.9.3"
|
||||
"@sentry/core": "7.119.2",
|
||||
"@sentry/types": "7.119.2",
|
||||
"@sentry/utils": "7.119.2",
|
||||
"localforage": "^1.8.1"
|
||||
},
|
||||
"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": {
|
||||
"version": "6.19.7",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/node/-/node-6.19.7.tgz",
|
||||
"integrity": "sha512-gtmRC4dAXKODMpHXKfrkfvyBL3cI8y64vEi3fDD046uqYcrWdgoQsffuBbxMAizc6Ez1ia+f0Flue6p15Qaltg==",
|
||||
"version": "7.119.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.119.2.tgz",
|
||||
"integrity": "sha512-TPNnqxh+Myooe4jTyRiXrzrM2SH08R4+nrmBls4T7lKp2E5R/3mDSe/YTn5rRcUt1k1hPx1NgO/taG0DoS5cXA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@sentry/core": "6.19.7",
|
||||
"@sentry/hub": "6.19.7",
|
||||
"@sentry/types": "6.19.7",
|
||||
"@sentry/utils": "6.19.7",
|
||||
"cookie": "^0.4.1",
|
||||
"https-proxy-agent": "^5.0.0",
|
||||
"lru_map": "^0.3.3",
|
||||
"tslib": "^1.9.3"
|
||||
"@sentry-internal/tracing": "7.119.2",
|
||||
"@sentry/core": "7.119.2",
|
||||
"@sentry/integrations": "7.119.2",
|
||||
"@sentry/types": "7.119.2",
|
||||
"@sentry/utils": "7.119.2"
|
||||
},
|
||||
"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": {
|
||||
"version": "6.19.7",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.19.7.tgz",
|
||||
"integrity": "sha512-jH84pDYE+hHIbVnab3Hr+ZXr1v8QABfhx39KknxqKWr2l0oEItzepV0URvbEhB446lk/S/59230dlUUIBGsXbg==",
|
||||
"version": "7.119.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.119.2.tgz",
|
||||
"integrity": "sha512-ydq1tWsdG7QW+yFaTp0gFaowMLNVikIqM70wxWNK+u98QzKnVY/3XTixxNLsUtnAB4Y+isAzFhrc6Vb5GFdFeg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/utils": {
|
||||
"version": "6.19.7",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.19.7.tgz",
|
||||
"integrity": "sha512-z95ECmE3i9pbWoXQrD/7PgkBAzJYR+iXtPuTkpBjDKs86O3mT+PXOT3BAn79w2wkn7/i3vOGD2xVr1uiMl26dA==",
|
||||
"version": "7.119.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.119.2.tgz",
|
||||
"integrity": "sha512-TLdUCvcNgzKP0r9YD7tgCL1PEUp42TObISridsPJ5rhpVGQJvpr+Six0zIkfDUxerLYWZoK8QMm9KgFlPLNQzA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@sentry/types": "6.19.7",
|
||||
"tslib": "^1.9.3"
|
||||
"@sentry/types": "7.119.2"
|
||||
},
|
||||
"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": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@serdnam/pino-cloudwatch-transport/-/pino-cloudwatch-transport-1.0.4.tgz",
|
||||
@@ -9728,9 +9695,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/cookie": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
|
||||
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
|
||||
"version": "0.7.2",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
|
||||
"integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
@@ -10863,9 +10830,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/express": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz",
|
||||
"integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==",
|
||||
"version": "4.21.1",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz",
|
||||
"integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"accepts": "~1.3.8",
|
||||
@@ -10873,7 +10840,7 @@
|
||||
"body-parser": "1.20.3",
|
||||
"content-disposition": "0.5.4",
|
||||
"content-type": "~1.0.4",
|
||||
"cookie": "0.6.0",
|
||||
"cookie": "0.7.1",
|
||||
"cookie-signature": "1.0.6",
|
||||
"debug": "2.6.9",
|
||||
"depd": "2.0.0",
|
||||
@@ -10905,12 +10872,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/express-session": {
|
||||
"version": "1.18.0",
|
||||
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.0.tgz",
|
||||
"integrity": "sha512-m93QLWr0ju+rOwApSsyso838LQwgfs44QtOP/WBiwtAgPIo/SAh1a5c6nn2BR6mFNZehTpqKDESzP+fRHVbxwQ==",
|
||||
"version": "1.18.1",
|
||||
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.1.tgz",
|
||||
"integrity": "sha512-a5mtTqEaZvBCL9A9aqkrtfz+3SMDhOVUnjafjo+s7A9Txkq+SVX2DLvSp1Zrv4uCXa3lMSK3viWnh9Gg07PBUA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"cookie": "0.6.0",
|
||||
"cookie": "0.7.2",
|
||||
"cookie-signature": "1.0.7",
|
||||
"debug": "2.6.9",
|
||||
"depd": "~2.0.0",
|
||||
@@ -10944,6 +10912,15 @@
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||
"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": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
@@ -12424,6 +12401,12 @@
|
||||
"integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
|
||||
"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": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
||||
@@ -13420,13 +13403,22 @@
|
||||
"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": {
|
||||
"version": "5.13.0",
|
||||
"resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-5.13.0.tgz",
|
||||
"integrity": "sha512-9IjUN9ZyCS9pTG+KqTDEQo68Sui2lHsYBrfMyVUTTZ3XhH8PMZq7xO94Kr+eP9dhi/kcKsx4N41p2IXEBil1pQ==",
|
||||
"version": "5.14.0",
|
||||
"resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-5.14.0.tgz",
|
||||
"integrity": "sha512-aORPWntbpH5esaYpGOOmri0OHDOe3wC5M2MQxZ9dvMLZm6DnaAn0kJlcbU9hwsQgLzmZyReKwFwwPkR+nHu5kA==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"cookie": "^0.6.0",
|
||||
"cookie": "^0.7.0",
|
||||
"process-warning": "^3.0.0",
|
||||
"set-cookie-parser": "^2.4.1"
|
||||
}
|
||||
@@ -13505,6 +13497,15 @@
|
||||
"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": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
|
||||
@@ -13632,11 +13633,6 @@
|
||||
"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": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
@@ -15261,9 +15257,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
|
||||
"integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==",
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
@@ -18865,9 +18861,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "5.4.8",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz",
|
||||
"integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==",
|
||||
"version": "5.4.9",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.9.tgz",
|
||||
"integrity": "sha512-20OVpJHh0PAM0oSOELa5GaZNWeDjcAvQjGXy2Uyr+Tp+/D2/Hdz6NLgpJLsarPTA2QJ6v8mX2P1ZfbsSKvdMkg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
||||
@@ -669,6 +669,12 @@ export const RAW_SECRETS = {
|
||||
type: "The type of the secret to delete.",
|
||||
projectSlug: "The slug of the project to delete the secret in.",
|
||||
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;
|
||||
|
||||
|
||||
@@ -23,6 +23,18 @@ import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types";
|
||||
|
||||
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) => {
|
||||
server.route({
|
||||
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({
|
||||
method: "POST",
|
||||
url: "/backfill-secret-references",
|
||||
|
||||
@@ -371,6 +371,13 @@ const formatMultiValueEnv = (val?: string) => {
|
||||
return `"${val.replace(/\n/g, "\\n")}"`;
|
||||
};
|
||||
|
||||
type TSecretReferenceTraceNode = {
|
||||
key: string;
|
||||
value?: string;
|
||||
environment: string;
|
||||
secretPath: string;
|
||||
children: TSecretReferenceTraceNode[];
|
||||
};
|
||||
type TInterpolateSecretArg = {
|
||||
projectId: string;
|
||||
decryptSecretValue: (encryptedValue?: Buffer | null) => string | undefined;
|
||||
@@ -412,14 +419,21 @@ export const expandSecretReferencesFactory = ({
|
||||
return secretCache[cacheKey][secretKey] || { value: "", tags: [] };
|
||||
};
|
||||
|
||||
const recursivelyExpandSecret = async (dto: { value?: string; secretPath: string; environment: string }) => {
|
||||
if (!dto.value) return "";
|
||||
const recursivelyExpandSecret = async (dto: {
|
||||
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;
|
||||
|
||||
while (stack.length) {
|
||||
const { value, secretPath, environment, depth } = stack.pop()!;
|
||||
const { value, secretPath, environment, depth, trace } = stack.pop()!;
|
||||
|
||||
// eslint-disable-next-line no-continue
|
||||
if (depth > MAX_SECRET_REFERENCE_DEPTH) continue;
|
||||
const refs = value?.match(INTERPOLATION_SYNTAX_REG);
|
||||
@@ -432,6 +446,11 @@ export const expandSecretReferencesFactory = ({
|
||||
// eslint-disable-next-line no-continue
|
||||
if (!entities.length) continue;
|
||||
|
||||
let referredSecretPath = "";
|
||||
let referredSecretKey = "";
|
||||
let referredSecretEnvironmentSlug = "";
|
||||
let referredSecretValue = "";
|
||||
|
||||
if (entities.length === 1) {
|
||||
const [secretKey] = entities;
|
||||
|
||||
@@ -444,17 +463,11 @@ export const expandSecretReferencesFactory = ({
|
||||
|
||||
const cacheKey = getCacheUniqueKey(environment, secretPath);
|
||||
secretCache[cacheKey][secretKey] = referredValue;
|
||||
if (INTERPOLATION_SYNTAX_REG.test(referredValue.value)) {
|
||||
stack.push({
|
||||
value: referredValue.value,
|
||||
secretPath,
|
||||
environment,
|
||||
depth: depth + 1
|
||||
});
|
||||
}
|
||||
if (referredValue) {
|
||||
expandedValue = expandedValue.replaceAll(interpolationSyntax, referredValue.value);
|
||||
}
|
||||
|
||||
referredSecretValue = referredValue.value;
|
||||
referredSecretKey = secretKey;
|
||||
referredSecretPath = secretPath;
|
||||
referredSecretEnvironmentSlug = environment;
|
||||
} else {
|
||||
const secretReferenceEnvironment = entities[0];
|
||||
const secretReferencePath = path.join("/", ...entities.slice(1, entities.length - 1));
|
||||
@@ -469,24 +482,42 @@ export const expandSecretReferencesFactory = ({
|
||||
|
||||
const cacheKey = getCacheUniqueKey(secretReferenceEnvironment, secretReferencePath);
|
||||
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) {
|
||||
expandedValue = expandedValue.replaceAll(interpolationSyntax, referedValue.value);
|
||||
referredSecretValue = 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: {
|
||||
@@ -500,10 +531,21 @@ export const expandSecretReferencesFactory = ({
|
||||
const shouldExpand = Boolean(inputSecret.value?.match(INTERPOLATION_SYNTAX_REG));
|
||||
if (!shouldExpand) return inputSecret.value;
|
||||
|
||||
const expandedSecretValue = await recursivelyExpandSecret(inputSecret);
|
||||
return inputSecret.skipMultilineEncoding ? formatMultiValueEnv(expandedSecretValue) : expandedSecretValue;
|
||||
const { expandedValue } = await recursivelyExpandSecret(inputSecret);
|
||||
|
||||
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 = (
|
||||
|
||||
@@ -41,6 +41,7 @@ import {
|
||||
TDeleteManySecretDTO,
|
||||
TDeleteSecretDTO,
|
||||
TGetASecretDTO,
|
||||
TGetSecretReferencesTreeDTO,
|
||||
TGetSecretsDTO,
|
||||
TGetSecretVersionsDTO,
|
||||
TMoveSecretsDTO,
|
||||
@@ -815,7 +816,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
})
|
||||
);
|
||||
|
||||
const expandSecretReferences = expandSecretReferencesFactory({
|
||||
const { expandSecretReferences } = expandSecretReferencesFactory({
|
||||
projectId,
|
||||
folderDAL,
|
||||
secretDAL,
|
||||
@@ -965,7 +966,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
})
|
||||
);
|
||||
|
||||
const expandSecretReferences = expandSecretReferencesFactory({
|
||||
const { expandSecretReferences } = expandSecretReferencesFactory({
|
||||
projectId,
|
||||
folderDAL,
|
||||
secretDAL,
|
||||
@@ -1032,6 +1033,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
value: secretValue,
|
||||
skipMultilineEncoding: secret.skipMultilineEncoding
|
||||
});
|
||||
|
||||
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 {
|
||||
createSecret,
|
||||
deleteSecret,
|
||||
@@ -1942,6 +2015,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
moveSecrets,
|
||||
getSecretsCount,
|
||||
getSecretsCountMultiEnv,
|
||||
getSecretsMultiEnv
|
||||
getSecretsMultiEnv,
|
||||
getSecretReferenceTree
|
||||
};
|
||||
};
|
||||
|
||||
@@ -278,3 +278,10 @@ export type TAttachSecretTagsDTO = {
|
||||
secretPath: string;
|
||||
type: SecretType;
|
||||
} & 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;
|
||||
}
|
||||
const expandSecretReferences = expandSecretReferencesFactory({
|
||||
const { expandSecretReferences } = expandSecretReferencesFactory({
|
||||
decryptSecretValue: dto.decryptor,
|
||||
secretDAL: secretV2BridgeDAL,
|
||||
folderDAL,
|
||||
|
||||
@@ -38,6 +38,7 @@ import { TSecretImportDALFactory } from "../secret-import/secret-import-dal";
|
||||
import { fnSecretsFromImports } from "../secret-import/secret-import-fns";
|
||||
import { TSecretTagDALFactory } from "../secret-tag/secret-tag-dal";
|
||||
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 {
|
||||
decryptSecretRaw,
|
||||
@@ -1099,6 +1100,18 @@ export const secretServiceFactory = ({
|
||||
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 ({
|
||||
projectId,
|
||||
path,
|
||||
@@ -2857,6 +2870,7 @@ export const secretServiceFactory = ({
|
||||
startSecretV2Migration,
|
||||
getSecretsCount,
|
||||
getSecretsCountMultiEnv,
|
||||
getSecretsRawMultiEnv
|
||||
getSecretsRawMultiEnv,
|
||||
getSecretReferenceTree
|
||||
};
|
||||
};
|
||||
|
||||
@@ -8,4 +8,8 @@ export {
|
||||
useUpdateSecretBatch,
|
||||
useUpdateSecretV3
|
||||
} from "./mutations";
|
||||
export { useGetProjectSecrets, useGetProjectSecretsAllEnv, useGetSecretVersion } from "./queries";
|
||||
export {
|
||||
useGetProjectSecrets,
|
||||
useGetProjectSecretsAllEnv,
|
||||
useGetSecretReferenceTree,
|
||||
useGetSecretVersion} from "./queries";
|
||||
|
||||
@@ -17,14 +17,17 @@ import {
|
||||
SecretVersions,
|
||||
TGetProjectSecretsAllEnvDTO,
|
||||
TGetProjectSecretsDTO,
|
||||
TGetProjectSecretsKey
|
||||
TGetProjectSecretsKey,
|
||||
TGetSecretReferenceTreeDTO,
|
||||
TSecretReferenceTraceNode
|
||||
} from "./types";
|
||||
|
||||
export const secretKeys = {
|
||||
// this is also used in secretSnapshot part
|
||||
getProjectSecret: ({ workspaceId, environment, secretPath }: TGetProjectSecretsKey) =>
|
||||
[{ 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 ({
|
||||
@@ -227,3 +230,33 @@ export const useGetSecretVersion = (dto: GetSecretVersionsDTO) =>
|
||||
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[];
|
||||
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[];
|
||||
};
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
faCircleDot,
|
||||
faClock,
|
||||
faPlus,
|
||||
faRoad,
|
||||
faShare,
|
||||
faTag
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
@@ -28,6 +29,9 @@ import {
|
||||
FormControl,
|
||||
IconButton,
|
||||
Input,
|
||||
Modal,
|
||||
ModalContent,
|
||||
ModalTrigger,
|
||||
Switch,
|
||||
Tag,
|
||||
TextArea,
|
||||
@@ -41,6 +45,7 @@ import { SecretV3RawSanitized, WsTag } from "@app/hooks/api/types";
|
||||
|
||||
import { CreateReminderForm } from "./CreateReminderForm";
|
||||
import { formSchema, SecretActionType, TFormSchema } from "./SecretListView.utils";
|
||||
import { SecretReferenceTree } from "./SecretReferenceDetails";
|
||||
|
||||
type Props = {
|
||||
isOpen?: boolean;
|
||||
@@ -448,9 +453,38 @@ export const SecretDetailSidebar = ({
|
||||
)}
|
||||
/>
|
||||
</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
|
||||
className="px-2 py-1"
|
||||
className="w-full px-2 py-1"
|
||||
variant="outline_bg"
|
||||
leftIcon={<FontAwesomeIcon icon={faShare} />}
|
||||
onClick={() => {
|
||||
@@ -16,7 +16,7 @@ import { WsTag } from "@app/hooks/api/types";
|
||||
import { AddShareSecretModal } from "@app/views/ShareSecretPage/components/AddShareSecretModal";
|
||||
|
||||
import { useSelectedSecretActions, useSelectedSecrets } from "../../SecretMainPage.store";
|
||||
import { SecretDetailSidebar } from "./SecretDetaiSidebar";
|
||||
import { SecretDetailSidebar } from "./SecretDetailSidebar";
|
||||
import { SecretItem } from "./SecretItem";
|
||||
import { FontAwesomeSpriteSymbols } from "./SecretListView.utils";
|
||||
|
||||
|
||||
@@ -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