Merge remote-tracking branch 'origin' into ssh-non-interactive

This commit is contained in:
Tuan Dang
2025-04-25 09:31:39 -07:00
272 changed files with 4532 additions and 772 deletions
+713 -1
View File
@@ -104,6 +104,7 @@
"pkijs": "^3.2.4", "pkijs": "^3.2.4",
"posthog-node": "^3.6.2", "posthog-node": "^3.6.2",
"probot": "^13.3.8", "probot": "^13.3.8",
"re2": "^1.21.4",
"safe-regex": "^2.1.1", "safe-regex": "^2.1.1",
"scim-patch": "^0.8.3", "scim-patch": "^0.8.3",
"scim2-parse-filter": "^0.2.10", "scim2-parse-filter": "^0.2.10",
@@ -6860,6 +6861,79 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/@npmcli/agent": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.2.2.tgz",
"integrity": "sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==",
"license": "ISC",
"dependencies": {
"agent-base": "^7.1.0",
"http-proxy-agent": "^7.0.0",
"https-proxy-agent": "^7.0.1",
"lru-cache": "^10.0.1",
"socks-proxy-agent": "^8.0.3"
},
"engines": {
"node": "^16.14.0 || >=18.0.0"
}
},
"node_modules/@npmcli/agent/node_modules/agent-base": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
"integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
"license": "MIT",
"engines": {
"node": ">= 14"
}
},
"node_modules/@npmcli/agent/node_modules/debug": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/@npmcli/agent/node_modules/https-proxy-agent": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
"integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
"license": "MIT",
"dependencies": {
"agent-base": "^7.1.2",
"debug": "4"
},
"engines": {
"node": ">= 14"
}
},
"node_modules/@npmcli/agent/node_modules/lru-cache": {
"version": "10.4.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"license": "ISC"
},
"node_modules/@npmcli/fs": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz",
"integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==",
"license": "ISC",
"dependencies": {
"semver": "^7.3.5"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
"node_modules/@octokit/auth-app": { "node_modules/@octokit/auth-app": {
"version": "7.1.1", "version": "7.1.1",
"resolved": "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-7.1.1.tgz", "resolved": "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-7.1.1.tgz",
@@ -11863,6 +11937,115 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/cacache": {
"version": "18.0.4",
"resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz",
"integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==",
"license": "ISC",
"dependencies": {
"@npmcli/fs": "^3.1.0",
"fs-minipass": "^3.0.0",
"glob": "^10.2.2",
"lru-cache": "^10.0.1",
"minipass": "^7.0.3",
"minipass-collect": "^2.0.1",
"minipass-flush": "^1.0.5",
"minipass-pipeline": "^1.2.4",
"p-map": "^4.0.0",
"ssri": "^10.0.0",
"tar": "^6.1.11",
"unique-filename": "^3.0.0"
},
"engines": {
"node": "^16.14.0 || >=18.0.0"
}
},
"node_modules/cacache/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/cacache/node_modules/fs-minipass": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz",
"integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==",
"license": "ISC",
"dependencies": {
"minipass": "^7.0.3"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
"node_modules/cacache/node_modules/glob": {
"version": "10.4.5",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
"license": "ISC",
"dependencies": {
"foreground-child": "^3.1.0",
"jackspeak": "^3.1.2",
"minimatch": "^9.0.4",
"minipass": "^7.1.2",
"package-json-from-dist": "^1.0.0",
"path-scurry": "^1.11.1"
},
"bin": {
"glob": "dist/esm/bin.mjs"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/cacache/node_modules/jackspeak": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
"integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
"license": "BlueOak-1.0.0",
"dependencies": {
"@isaacs/cliui": "^8.0.2"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
},
"optionalDependencies": {
"@pkgjs/parseargs": "^0.11.0"
}
},
"node_modules/cacache/node_modules/lru-cache": {
"version": "10.4.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"license": "ISC"
},
"node_modules/cacache/node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/cacache/node_modules/minipass": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
"license": "ISC",
"engines": {
"node": ">=16 || 14 >=14.17"
}
},
"node_modules/call-bind": { "node_modules/call-bind": {
"version": "1.0.7", "version": "1.0.7",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
@@ -12842,6 +13025,16 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/encoding": {
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
"license": "MIT",
"optional": true,
"dependencies": {
"iconv-lite": "^0.6.2"
}
},
"node_modules/end-of-stream": { "node_modules/end-of-stream": {
"version": "1.4.4", "version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
@@ -12874,6 +13067,21 @@
"url": "https://github.com/fb55/entities?sponsor=1" "url": "https://github.com/fb55/entities?sponsor=1"
} }
}, },
"node_modules/env-paths": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
"integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/err-code": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
"integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
"license": "MIT"
},
"node_modules/error-ex": { "node_modules/error-ex": {
"version": "1.3.2", "version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@@ -13644,6 +13852,12 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/exponential-backoff": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.2.tgz",
"integrity": "sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==",
"license": "Apache-2.0"
},
"node_modules/express": { "node_modules/express": {
"version": "4.21.2", "version": "4.21.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
@@ -15221,6 +15435,12 @@
], ],
"license": "MIT" "license": "MIT"
}, },
"node_modules/http-cache-semantics": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
"integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==",
"license": "BSD-2-Clause"
},
"node_modules/http-errors": { "node_modules/http-errors": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
@@ -15403,7 +15623,6 @@
"version": "0.1.4", "version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
"integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
"dev": true,
"engines": { "engines": {
"node": ">=0.8.19" "node": ">=0.8.19"
} }
@@ -15436,6 +15655,16 @@
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
"dev": true "dev": true
}, },
"node_modules/install-artifact-from-github": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/install-artifact-from-github/-/install-artifact-from-github-1.3.5.tgz",
"integrity": "sha512-gZHC7f/cJgXz7MXlHFBxPVMsvIbev1OQN1uKQYKVJDydGNm9oYf9JstbU4Atnh/eSvk41WtEovoRm+8IF686xg==",
"license": "BSD-3-Clause",
"bin": {
"install-from-cache": "bin/install-from-cache.js",
"save-to-github-cache": "bin/save-to-github-cache.js"
}
},
"node_modules/internal-slot": { "node_modules/internal-slot": {
"version": "1.0.6", "version": "1.0.6",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz",
@@ -15518,6 +15747,19 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}, },
"node_modules/ip-address": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz",
"integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==",
"license": "MIT",
"dependencies": {
"jsbn": "1.1.0",
"sprintf-js": "^1.1.3"
},
"engines": {
"node": ">= 12"
}
},
"node_modules/ip-num": { "node_modules/ip-num": {
"version": "1.5.1", "version": "1.5.1",
"resolved": "https://registry.npmjs.org/ip-num/-/ip-num-1.5.1.tgz", "resolved": "https://registry.npmjs.org/ip-num/-/ip-num-1.5.1.tgz",
@@ -15717,6 +15959,12 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/is-lambda": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
"integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==",
"license": "MIT"
},
"node_modules/is-negative-zero": { "node_modules/is-negative-zero": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
@@ -16860,6 +17108,38 @@
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"dev": true "dev": true
}, },
"node_modules/make-fetch-happen": {
"version": "13.0.1",
"resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz",
"integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==",
"license": "ISC",
"dependencies": {
"@npmcli/agent": "^2.0.0",
"cacache": "^18.0.0",
"http-cache-semantics": "^4.1.1",
"is-lambda": "^1.0.1",
"minipass": "^7.0.2",
"minipass-fetch": "^3.0.0",
"minipass-flush": "^1.0.5",
"minipass-pipeline": "^1.2.4",
"negotiator": "^0.6.3",
"proc-log": "^4.2.0",
"promise-retry": "^2.0.1",
"ssri": "^10.0.0"
},
"engines": {
"node": "^16.14.0 || >=18.0.0"
}
},
"node_modules/make-fetch-happen/node_modules/minipass": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
"license": "ISC",
"engines": {
"node": ">=16 || 14 >=14.17"
}
},
"node_modules/math-intrinsics": { "node_modules/math-intrinsics": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
@@ -17033,6 +17313,125 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/minipass-collect": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz",
"integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==",
"license": "ISC",
"dependencies": {
"minipass": "^7.0.3"
},
"engines": {
"node": ">=16 || 14 >=14.17"
}
},
"node_modules/minipass-collect/node_modules/minipass": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
"license": "ISC",
"engines": {
"node": ">=16 || 14 >=14.17"
}
},
"node_modules/minipass-fetch": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz",
"integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==",
"license": "MIT",
"dependencies": {
"minipass": "^7.0.3",
"minipass-sized": "^1.0.3",
"minizlib": "^2.1.2"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
},
"optionalDependencies": {
"encoding": "^0.1.13"
}
},
"node_modules/minipass-fetch/node_modules/minipass": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
"license": "ISC",
"engines": {
"node": ">=16 || 14 >=14.17"
}
},
"node_modules/minipass-flush": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
"integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
"license": "ISC",
"dependencies": {
"minipass": "^3.0.0"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/minipass-flush/node_modules/minipass": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"license": "ISC",
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/minipass-pipeline": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
"integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
"license": "ISC",
"dependencies": {
"minipass": "^3.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/minipass-pipeline/node_modules/minipass": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"license": "ISC",
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/minipass-sized": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
"integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
"license": "ISC",
"dependencies": {
"minipass": "^3.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/minipass-sized/node_modules/minipass": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"license": "ISC",
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/minizlib": { "node_modules/minizlib": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
@@ -17354,6 +17753,12 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/nan": {
"version": "2.22.2",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.22.2.tgz",
"integrity": "sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ==",
"license": "MIT"
},
"node_modules/nanoid": { "node_modules/nanoid": {
"version": "3.3.8", "version": "3.3.8",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
@@ -17444,6 +17849,30 @@
} }
} }
}, },
"node_modules/node-gyp": {
"version": "10.3.1",
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.3.1.tgz",
"integrity": "sha512-Pp3nFHBThHzVtNY7U6JfPjvT/DTE8+o/4xKsLQtBoU+j2HLsGlhcfzflAoUreaJbNmYnX+LlLi0qjV8kpyO6xQ==",
"license": "MIT",
"dependencies": {
"env-paths": "^2.2.0",
"exponential-backoff": "^3.1.1",
"glob": "^10.3.10",
"graceful-fs": "^4.2.6",
"make-fetch-happen": "^13.0.0",
"nopt": "^7.0.0",
"proc-log": "^4.1.0",
"semver": "^7.3.5",
"tar": "^6.2.1",
"which": "^4.0.0"
},
"bin": {
"node-gyp": "bin/node-gyp.js"
},
"engines": {
"node": "^16.14.0 || >=18.0.0"
}
},
"node_modules/node-gyp-build": { "node_modules/node-gyp-build": {
"version": "3.9.0", "version": "3.9.0",
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.9.0.tgz", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.9.0.tgz",
@@ -17465,6 +17894,122 @@
"node-gyp-build-optional-packages-test": "build-test.js" "node-gyp-build-optional-packages-test": "build-test.js"
} }
}, },
"node_modules/node-gyp/node_modules/abbrev": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz",
"integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==",
"license": "ISC",
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
"node_modules/node-gyp/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/node-gyp/node_modules/glob": {
"version": "10.4.5",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
"license": "ISC",
"dependencies": {
"foreground-child": "^3.1.0",
"jackspeak": "^3.1.2",
"minimatch": "^9.0.4",
"minipass": "^7.1.2",
"package-json-from-dist": "^1.0.0",
"path-scurry": "^1.11.1"
},
"bin": {
"glob": "dist/esm/bin.mjs"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/node-gyp/node_modules/isexe": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz",
"integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==",
"license": "ISC",
"engines": {
"node": ">=16"
}
},
"node_modules/node-gyp/node_modules/jackspeak": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
"integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
"license": "BlueOak-1.0.0",
"dependencies": {
"@isaacs/cliui": "^8.0.2"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
},
"optionalDependencies": {
"@pkgjs/parseargs": "^0.11.0"
}
},
"node_modules/node-gyp/node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/node-gyp/node_modules/minipass": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
"license": "ISC",
"engines": {
"node": ">=16 || 14 >=14.17"
}
},
"node_modules/node-gyp/node_modules/nopt": {
"version": "7.2.1",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz",
"integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==",
"license": "ISC",
"dependencies": {
"abbrev": "^2.0.0"
},
"bin": {
"nopt": "bin/nopt.js"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
"node_modules/node-gyp/node_modules/which": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz",
"integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==",
"license": "ISC",
"dependencies": {
"isexe": "^3.1.1"
},
"bin": {
"node-which": "bin/which.js"
},
"engines": {
"node": "^16.13.0 || >=18.0.0"
}
},
"node_modules/node-releases": { "node_modules/node-releases": {
"version": "2.0.14", "version": "2.0.14",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
@@ -18125,6 +18670,21 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/p-map": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
"integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
"license": "MIT",
"dependencies": {
"aggregate-error": "^3.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/p-queue": { "node_modules/p-queue": {
"version": "6.6.2", "version": "6.6.2",
"resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz",
@@ -19202,6 +19762,15 @@
"real-require": "^0.2.0" "real-require": "^0.2.0"
} }
}, },
"node_modules/proc-log": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz",
"integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==",
"license": "ISC",
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
"node_modules/process": { "node_modules/process": {
"version": "0.11.10", "version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
@@ -19230,6 +19799,28 @@
"node": ">=0.4.0" "node": ">=0.4.0"
} }
}, },
"node_modules/promise-retry": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
"integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
"license": "MIT",
"dependencies": {
"err-code": "^2.0.2",
"retry": "^0.12.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/promise-retry/node_modules/retry": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
"integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
"license": "MIT",
"engines": {
"node": ">= 4"
}
},
"node_modules/prompt-sync": { "node_modules/prompt-sync": {
"version": "4.2.0", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/prompt-sync/-/prompt-sync-4.2.0.tgz", "resolved": "https://registry.npmjs.org/prompt-sync/-/prompt-sync-4.2.0.tgz",
@@ -19501,6 +20092,18 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/re2": {
"version": "1.21.4",
"resolved": "https://registry.npmjs.org/re2/-/re2-1.21.4.tgz",
"integrity": "sha512-MVIfXWJmsP28mRsSt8HeL750ifb8H5+oF2UDIxGaiJCr8fkMqhLZ7kcX9ADRk2dC8qeGKedB7UVYRfBVpEiLfA==",
"hasInstallScript": true,
"license": "BSD-3-Clause",
"dependencies": {
"install-artifact-from-github": "^1.3.5",
"nan": "^2.20.0",
"node-gyp": "^10.2.0"
}
},
"node_modules/react-is": { "node_modules/react-is": {
"version": "18.2.0", "version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
@@ -20422,6 +21025,16 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/smart-buffer": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
"integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
"license": "MIT",
"engines": {
"node": ">= 6.0.0",
"npm": ">= 3.0.0"
}
},
"node_modules/smee-client": { "node_modules/smee-client": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/smee-client/-/smee-client-2.0.0.tgz", "resolved": "https://registry.npmjs.org/smee-client/-/smee-client-2.0.0.tgz",
@@ -20625,6 +21238,60 @@
"uuid": "dist/bin/uuid" "uuid": "dist/bin/uuid"
} }
}, },
"node_modules/socks": {
"version": "2.8.4",
"resolved": "https://registry.npmjs.org/socks/-/socks-2.8.4.tgz",
"integrity": "sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ==",
"license": "MIT",
"dependencies": {
"ip-address": "^9.0.5",
"smart-buffer": "^4.2.0"
},
"engines": {
"node": ">= 10.0.0",
"npm": ">= 3.0.0"
}
},
"node_modules/socks-proxy-agent": {
"version": "8.0.5",
"resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz",
"integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==",
"license": "MIT",
"dependencies": {
"agent-base": "^7.1.2",
"debug": "^4.3.4",
"socks": "^2.8.3"
},
"engines": {
"node": ">= 14"
}
},
"node_modules/socks-proxy-agent/node_modules/agent-base": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
"integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
"license": "MIT",
"engines": {
"node": ">= 14"
}
},
"node_modules/socks-proxy-agent/node_modules/debug": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/sonic-boom": { "node_modules/sonic-boom": {
"version": "3.7.0", "version": "3.7.0",
"resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.7.0.tgz", "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.7.0.tgz",
@@ -20680,6 +21347,27 @@
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
"node_modules/ssri": {
"version": "10.0.6",
"resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz",
"integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==",
"license": "ISC",
"dependencies": {
"minipass": "^7.0.3"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
"node_modules/ssri/node_modules/minipass": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
"license": "ISC",
"engines": {
"node": ">=16 || 14 >=14.17"
}
},
"node_modules/stack-trace": { "node_modules/stack-trace": {
"version": "0.0.10", "version": "0.0.10",
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
@@ -22482,6 +23170,30 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/unique-filename": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz",
"integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==",
"license": "ISC",
"dependencies": {
"unique-slug": "^4.0.0"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
"node_modules/unique-slug": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz",
"integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==",
"license": "ISC",
"dependencies": {
"imurmurhash": "^0.1.4"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
"node_modules/universal-github-app-jwt": { "node_modules/universal-github-app-jwt": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/universal-github-app-jwt/-/universal-github-app-jwt-2.2.0.tgz", "resolved": "https://registry.npmjs.org/universal-github-app-jwt/-/universal-github-app-jwt-2.2.0.tgz",
+1
View File
@@ -221,6 +221,7 @@
"pkijs": "^3.2.4", "pkijs": "^3.2.4",
"posthog-node": "^3.6.2", "posthog-node": "^3.6.2",
"probot": "^13.3.8", "probot": "^13.3.8",
"re2": "^1.21.4",
"safe-regex": "^2.1.1", "safe-regex": "^2.1.1",
"scim-patch": "^0.8.3", "scim-patch": "^0.8.3",
"scim2-parse-filter": "^0.2.10", "scim2-parse-filter": "^0.2.10",
+1 -1
View File
@@ -136,7 +136,7 @@ declare module "fastify" {
rateLimits: RateLimitConfiguration; rateLimits: RateLimitConfiguration;
// passport data // passport data
passportUser: { passportUser: {
isUserCompleted: string; isUserCompleted: boolean;
providerAuthToken: string; providerAuthToken: string;
}; };
kmipUser: { kmipUser: {
@@ -0,0 +1,29 @@
import { Knex } from "knex";
import { TableName } from "@app/db/schemas";
export async function up(knex: Knex): Promise<void> {
await knex.schema.alterTable(TableName.SecretVersionV2, (table) => {
table.dropForeign(["userActorId"]);
table.dropForeign(["identityActorId"]);
});
await knex.schema.alterTable(TableName.SecretVersionV2, (table) => {
table.foreign("userActorId").references("id").inTable(TableName.Users).onDelete("SET NULL");
table.foreign("identityActorId").references("id").inTable(TableName.Identity).onDelete("SET NULL");
});
}
export async function down(knex: Knex): Promise<void> {
await knex.schema.alterTable(TableName.SecretVersionV2, (table) => {
table.dropForeign(["userActorId"]);
table.dropForeign(["identityActorId"]);
});
await knex.schema.alterTable(TableName.SecretVersionV2, (table) => {
table.foreign("userActorId").references("id").inTable(TableName.Users);
table.foreign("identityActorId").references("id").inTable(TableName.Identity);
});
}
@@ -1,7 +1,7 @@
import { z } from "zod"; import { z } from "zod";
import { DynamicSecretLeasesSchema } from "@app/db/schemas"; import { DynamicSecretLeasesSchema } from "@app/db/schemas";
import { DYNAMIC_SECRET_LEASES } from "@app/lib/api-docs"; import { ApiDocsTags, DYNAMIC_SECRET_LEASES } from "@app/lib/api-docs";
import { daysToMillisecond } from "@app/lib/dates"; import { daysToMillisecond } from "@app/lib/dates";
import { removeTrailingSlash } from "@app/lib/fn"; import { removeTrailingSlash } from "@app/lib/fn";
import { ms } from "@app/lib/ms"; import { ms } from "@app/lib/ms";
@@ -18,6 +18,8 @@ export const registerDynamicSecretLeaseRouter = async (server: FastifyZodProvide
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.DynamicSecrets],
body: z.object({ body: z.object({
dynamicSecretName: z.string().min(1).describe(DYNAMIC_SECRET_LEASES.CREATE.dynamicSecretName).toLowerCase(), dynamicSecretName: z.string().min(1).describe(DYNAMIC_SECRET_LEASES.CREATE.dynamicSecretName).toLowerCase(),
projectSlug: z.string().min(1).describe(DYNAMIC_SECRET_LEASES.CREATE.projectSlug), projectSlug: z.string().min(1).describe(DYNAMIC_SECRET_LEASES.CREATE.projectSlug),
@@ -65,6 +67,8 @@ export const registerDynamicSecretLeaseRouter = async (server: FastifyZodProvide
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.DynamicSecrets],
params: z.object({ params: z.object({
leaseId: z.string().min(1).describe(DYNAMIC_SECRET_LEASES.DELETE.leaseId) leaseId: z.string().min(1).describe(DYNAMIC_SECRET_LEASES.DELETE.leaseId)
}), }),
@@ -107,6 +111,8 @@ export const registerDynamicSecretLeaseRouter = async (server: FastifyZodProvide
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.DynamicSecrets],
params: z.object({ params: z.object({
leaseId: z.string().min(1).describe(DYNAMIC_SECRET_LEASES.RENEW.leaseId) leaseId: z.string().min(1).describe(DYNAMIC_SECRET_LEASES.RENEW.leaseId)
}), }),
@@ -160,6 +166,8 @@ export const registerDynamicSecretLeaseRouter = async (server: FastifyZodProvide
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.DynamicSecrets],
params: z.object({ params: z.object({
leaseId: z.string().min(1).describe(DYNAMIC_SECRET_LEASES.GET_BY_LEASEID.leaseId) leaseId: z.string().min(1).describe(DYNAMIC_SECRET_LEASES.GET_BY_LEASEID.leaseId)
}), }),
@@ -2,7 +2,7 @@ import { z } from "zod";
import { DynamicSecretLeasesSchema } from "@app/db/schemas"; import { DynamicSecretLeasesSchema } from "@app/db/schemas";
import { DynamicSecretProviderSchema } from "@app/ee/services/dynamic-secret/providers/models"; import { DynamicSecretProviderSchema } from "@app/ee/services/dynamic-secret/providers/models";
import { DYNAMIC_SECRETS } from "@app/lib/api-docs"; import { ApiDocsTags, DYNAMIC_SECRETS } from "@app/lib/api-docs";
import { daysToMillisecond } from "@app/lib/dates"; import { daysToMillisecond } from "@app/lib/dates";
import { removeTrailingSlash } from "@app/lib/fn"; import { removeTrailingSlash } from "@app/lib/fn";
import { ms } from "@app/lib/ms"; import { ms } from "@app/lib/ms";
@@ -21,6 +21,8 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) =>
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.DynamicSecrets],
body: z.object({ body: z.object({
projectSlug: z.string().min(1).describe(DYNAMIC_SECRETS.CREATE.projectSlug), projectSlug: z.string().min(1).describe(DYNAMIC_SECRETS.CREATE.projectSlug),
provider: DynamicSecretProviderSchema.describe(DYNAMIC_SECRETS.CREATE.provider), provider: DynamicSecretProviderSchema.describe(DYNAMIC_SECRETS.CREATE.provider),
@@ -111,6 +113,8 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) =>
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.DynamicSecrets],
params: z.object({ params: z.object({
name: z.string().toLowerCase().describe(DYNAMIC_SECRETS.UPDATE.name) name: z.string().toLowerCase().describe(DYNAMIC_SECRETS.UPDATE.name)
}), }),
@@ -179,6 +183,8 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) =>
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.DynamicSecrets],
params: z.object({ params: z.object({
name: z.string().toLowerCase().describe(DYNAMIC_SECRETS.DELETE.name) name: z.string().toLowerCase().describe(DYNAMIC_SECRETS.DELETE.name)
}), }),
@@ -215,6 +221,8 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) =>
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.DynamicSecrets],
params: z.object({ params: z.object({
name: z.string().min(1).describe(DYNAMIC_SECRETS.GET_BY_NAME.name) name: z.string().min(1).describe(DYNAMIC_SECRETS.GET_BY_NAME.name)
}), }),
@@ -253,6 +261,8 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) =>
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.DynamicSecrets],
querystring: z.object({ querystring: z.object({
projectSlug: z.string().min(1).describe(DYNAMIC_SECRETS.LIST.projectSlug), projectSlug: z.string().min(1).describe(DYNAMIC_SECRETS.LIST.projectSlug),
path: z.string().trim().default("/").transform(removeTrailingSlash).describe(DYNAMIC_SECRETS.LIST.path), path: z.string().trim().default("/").transform(removeTrailingSlash).describe(DYNAMIC_SECRETS.LIST.path),
@@ -284,18 +294,20 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) =>
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.DynamicSecrets],
params: z.object({ params: z.object({
name: z.string().min(1).describe(DYNAMIC_SECRETS.LIST_LEAES_BY_NAME.name) name: z.string().min(1).describe(DYNAMIC_SECRETS.LIST_LEASES_BY_NAME.name)
}), }),
querystring: z.object({ querystring: z.object({
projectSlug: z.string().min(1).describe(DYNAMIC_SECRETS.LIST_LEAES_BY_NAME.projectSlug), projectSlug: z.string().min(1).describe(DYNAMIC_SECRETS.LIST_LEASES_BY_NAME.projectSlug),
path: z path: z
.string() .string()
.trim() .trim()
.default("/") .default("/")
.transform(removeTrailingSlash) .transform(removeTrailingSlash)
.describe(DYNAMIC_SECRETS.LIST_LEAES_BY_NAME.path), .describe(DYNAMIC_SECRETS.LIST_LEASES_BY_NAME.path),
environmentSlug: z.string().min(1).describe(DYNAMIC_SECRETS.LIST_LEAES_BY_NAME.environmentSlug) environmentSlug: z.string().min(1).describe(DYNAMIC_SECRETS.LIST_LEASES_BY_NAME.environmentSlug)
}), }),
response: { response: {
200: z.object({ 200: z.object({
+17 -1
View File
@@ -2,7 +2,7 @@ import { z } from "zod";
import { GroupsSchema, OrgMembershipRole, UsersSchema } from "@app/db/schemas"; import { GroupsSchema, OrgMembershipRole, UsersSchema } from "@app/db/schemas";
import { EFilterReturnedUsers } from "@app/ee/services/group/group-types"; import { EFilterReturnedUsers } from "@app/ee/services/group/group-types";
import { GROUPS } from "@app/lib/api-docs"; import { ApiDocsTags, GROUPS } from "@app/lib/api-docs";
import { slugSchema } from "@app/server/lib/schemas"; import { slugSchema } from "@app/server/lib/schemas";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type"; import { AuthMode } from "@app/services/auth/auth-type";
@@ -13,6 +13,8 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => {
method: "POST", method: "POST",
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Groups],
body: z.object({ body: z.object({
name: z.string().trim().min(1).max(50).describe(GROUPS.CREATE.name), name: z.string().trim().min(1).max(50).describe(GROUPS.CREATE.name),
slug: slugSchema({ min: 5, max: 36 }).optional().describe(GROUPS.CREATE.slug), slug: slugSchema({ min: 5, max: 36 }).optional().describe(GROUPS.CREATE.slug),
@@ -40,6 +42,8 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => {
method: "GET", method: "GET",
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Groups],
params: z.object({ params: z.object({
id: z.string().trim().describe(GROUPS.GET_BY_ID.id) id: z.string().trim().describe(GROUPS.GET_BY_ID.id)
}), }),
@@ -65,6 +69,8 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => {
method: "GET", method: "GET",
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Groups],
response: { response: {
200: GroupsSchema.array() 200: GroupsSchema.array()
} }
@@ -87,6 +93,8 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => {
method: "PATCH", method: "PATCH",
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Groups],
params: z.object({ params: z.object({
id: z.string().trim().describe(GROUPS.UPDATE.id) id: z.string().trim().describe(GROUPS.UPDATE.id)
}), }),
@@ -120,6 +128,8 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => {
method: "DELETE", method: "DELETE",
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Groups],
params: z.object({ params: z.object({
id: z.string().trim().describe(GROUPS.DELETE.id) id: z.string().trim().describe(GROUPS.DELETE.id)
}), }),
@@ -145,6 +155,8 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => {
url: "/:id/users", url: "/:id/users",
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Groups],
params: z.object({ params: z.object({
id: z.string().trim().describe(GROUPS.LIST_USERS.id) id: z.string().trim().describe(GROUPS.LIST_USERS.id)
}), }),
@@ -194,6 +206,8 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => {
url: "/:id/users/:username", url: "/:id/users/:username",
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Groups],
params: z.object({ params: z.object({
id: z.string().trim().describe(GROUPS.ADD_USER.id), id: z.string().trim().describe(GROUPS.ADD_USER.id),
username: z.string().trim().describe(GROUPS.ADD_USER.username) username: z.string().trim().describe(GROUPS.ADD_USER.username)
@@ -227,6 +241,8 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => {
url: "/:id/users/:username", url: "/:id/users/:username",
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Groups],
params: z.object({ params: z.object({
id: z.string().trim().describe(GROUPS.DELETE_USER.id), id: z.string().trim().describe(GROUPS.DELETE_USER.id),
username: z.string().trim().describe(GROUPS.DELETE_USER.username) username: z.string().trim().describe(GROUPS.DELETE_USER.username)
@@ -3,7 +3,7 @@ import { z } from "zod";
import { IdentityProjectAdditionalPrivilegeTemporaryMode } from "@app/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-types"; import { IdentityProjectAdditionalPrivilegeTemporaryMode } from "@app/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-types";
import { backfillPermissionV1SchemaToV2Schema } from "@app/ee/services/permission/project-permission"; import { backfillPermissionV1SchemaToV2Schema } from "@app/ee/services/permission/project-permission";
import { IDENTITY_ADDITIONAL_PRIVILEGE } from "@app/lib/api-docs"; import { ApiDocsTags, IDENTITY_ADDITIONAL_PRIVILEGE } from "@app/lib/api-docs";
import { UnauthorizedError } from "@app/lib/errors"; import { UnauthorizedError } from "@app/lib/errors";
import { ms } from "@app/lib/ms"; import { ms } from "@app/lib/ms";
import { alphaNumericNanoId } from "@app/lib/nanoid"; import { alphaNumericNanoId } from "@app/lib/nanoid";
@@ -25,6 +25,8 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.IdentitySpecificPrivilegesV1],
description: "Create a permanent or a non expiry specific privilege for identity.", description: "Create a permanent or a non expiry specific privilege for identity.",
security: [ security: [
{ {
@@ -85,6 +87,8 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.IdentitySpecificPrivilegesV1],
description: "Create a temporary or a expiring specific privilege for identity.", description: "Create a temporary or a expiring specific privilege for identity.",
security: [ security: [
{ {
@@ -157,6 +161,8 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.IdentitySpecificPrivilegesV1],
description: "Update a specific privilege of an identity.", description: "Update a specific privilege of an identity.",
security: [ security: [
{ {
@@ -240,6 +246,8 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.IdentitySpecificPrivilegesV1],
description: "Delete a specific privilege of an identity.", description: "Delete a specific privilege of an identity.",
security: [ security: [
{ {
@@ -279,6 +287,8 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.IdentitySpecificPrivilegesV1],
description: "Retrieve details of a specific privilege by privilege slug.", description: "Retrieve details of a specific privilege by privilege slug.",
security: [ security: [
{ {
@@ -319,6 +329,8 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.IdentitySpecificPrivilegesV1],
description: "List of a specific privilege of an identity in a project.", description: "List of a specific privilege of an identity in a project.",
security: [ security: [
{ {
+3 -1
View File
@@ -2,7 +2,7 @@ import { z } from "zod";
import { AuditLogsSchema, SecretSnapshotsSchema } from "@app/db/schemas"; import { AuditLogsSchema, SecretSnapshotsSchema } from "@app/db/schemas";
import { EventType, UserAgentType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType, UserAgentType } from "@app/ee/services/audit-log/audit-log-types";
import { AUDIT_LOGS, PROJECTS } from "@app/lib/api-docs"; import { ApiDocsTags, AUDIT_LOGS, PROJECTS } from "@app/lib/api-docs";
import { getLastMidnightDateISO, removeTrailingSlash } from "@app/lib/fn"; import { getLastMidnightDateISO, removeTrailingSlash } from "@app/lib/fn";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
@@ -17,6 +17,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Projects],
description: "Return project secret snapshots ids", description: "Return project secret snapshots ids",
security: [ security: [
{ {
@@ -5,7 +5,7 @@ import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { ProjectPermissionV2Schema } from "@app/ee/services/permission/project-permission"; import { ProjectPermissionV2Schema } from "@app/ee/services/permission/project-permission";
import { ProjectTemplateDefaultEnvironments } from "@app/ee/services/project-template/project-template-constants"; import { ProjectTemplateDefaultEnvironments } from "@app/ee/services/project-template/project-template-constants";
import { isInfisicalProjectTemplate } from "@app/ee/services/project-template/project-template-fns"; import { isInfisicalProjectTemplate } from "@app/ee/services/project-template/project-template-fns";
import { ProjectTemplates } from "@app/lib/api-docs"; import { ApiDocsTags, ProjectTemplates } from "@app/lib/api-docs";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { slugSchema } from "@app/server/lib/schemas"; import { slugSchema } from "@app/server/lib/schemas";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
@@ -101,6 +101,8 @@ export const registerProjectTemplateRouter = async (server: FastifyZodProvider)
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ProjectTemplates],
description: "List project templates for the current organization.", description: "List project templates for the current organization.",
response: { response: {
200: z.object({ 200: z.object({
@@ -137,6 +139,8 @@ export const registerProjectTemplateRouter = async (server: FastifyZodProvider)
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ProjectTemplates],
description: "Get a project template by ID.", description: "Get a project template by ID.",
params: z.object({ params: z.object({
templateId: z.string().uuid() templateId: z.string().uuid()
@@ -176,6 +180,8 @@ export const registerProjectTemplateRouter = async (server: FastifyZodProvider)
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ProjectTemplates],
description: "Create a project template.", description: "Create a project template.",
body: z.object({ body: z.object({
name: slugSchema({ field: "name" }) name: slugSchema({ field: "name" })
@@ -219,6 +225,8 @@ export const registerProjectTemplateRouter = async (server: FastifyZodProvider)
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ProjectTemplates],
description: "Update a project template.", description: "Update a project template.",
params: z.object({ templateId: z.string().uuid().describe(ProjectTemplates.UPDATE.templateId) }), params: z.object({ templateId: z.string().uuid().describe(ProjectTemplates.UPDATE.templateId) }),
body: z.object({ body: z.object({
@@ -269,6 +277,8 @@ export const registerProjectTemplateRouter = async (server: FastifyZodProvider)
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ProjectTemplates],
description: "Delete a project template.", description: "Delete a project template.",
params: z.object({ templateId: z.string().uuid().describe(ProjectTemplates.DELETE.templateId) }), params: z.object({ templateId: z.string().uuid().describe(ProjectTemplates.DELETE.templateId) }),
+12 -6
View File
@@ -223,12 +223,18 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => {
samlConfigId: z.string().trim() samlConfigId: z.string().trim()
}) })
}, },
preValidation: passport.authenticate("saml", { preValidation: passport.authenticate(
session: false, "saml",
failureFlash: true, {
failureRedirect: "/login/provider/error" session: false
// this is due to zod type difference },
}) as any, async (req, res, err, user) => {
if (err) {
throw new BadRequestError({ message: `Saml authentication failed. ${err?.message}`, error: err });
}
req.passportUser = user as { isUserCompleted: boolean; providerAuthToken: string };
}
) as any, // this is due to zod type difference
handler: (req, res) => { handler: (req, res) => {
if (req.passportUser.isUserCompleted) { if (req.passportUser.isUserCompleted) {
return res.redirect( return res.redirect(
+3 -1
View File
@@ -1,7 +1,7 @@
import { z } from "zod"; import { z } from "zod";
import { SecretSnapshotsSchema } from "@app/db/schemas"; import { SecretSnapshotsSchema } from "@app/db/schemas";
import { PROJECTS } from "@app/lib/api-docs"; import { ApiDocsTags, PROJECTS } from "@app/lib/api-docs";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { SanitizedTagSchema, secretRawSchema } from "@app/server/routes/sanitizedSchemas"; import { SanitizedTagSchema, secretRawSchema } from "@app/server/routes/sanitizedSchemas";
@@ -65,6 +65,8 @@ export const registerSnapshotRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Projects],
description: "Roll back project secrets to those captured in a secret snapshot version.", description: "Roll back project secrets to those captured in a secret snapshot version.",
security: [ security: [
{ {
@@ -6,7 +6,7 @@ import { sanitizedSshCa } from "@app/ee/services/ssh/ssh-certificate-authority-s
import { SshCaKeySource, SshCaStatus } from "@app/ee/services/ssh/ssh-certificate-authority-types"; import { SshCaKeySource, SshCaStatus } from "@app/ee/services/ssh/ssh-certificate-authority-types";
import { SshCertKeyAlgorithm } from "@app/ee/services/ssh-certificate/ssh-certificate-types"; import { SshCertKeyAlgorithm } from "@app/ee/services/ssh-certificate/ssh-certificate-types";
import { sanitizedSshCertificateTemplate } from "@app/ee/services/ssh-certificate-template/ssh-certificate-template-schema"; import { sanitizedSshCertificateTemplate } from "@app/ee/services/ssh-certificate-template/ssh-certificate-template-schema";
import { SSH_CERTIFICATE_AUTHORITIES } from "@app/lib/api-docs"; import { ApiDocsTags, SSH_CERTIFICATE_AUTHORITIES } from "@app/lib/api-docs";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type"; import { AuthMode } from "@app/services/auth/auth-type";
@@ -20,6 +20,8 @@ export const registerSshCaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SshCertificateAuthorities],
description: "Create SSH CA", description: "Create SSH CA",
body: z body: z
.object({ .object({
@@ -92,6 +94,8 @@ export const registerSshCaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SshCertificateAuthorities],
description: "Get SSH CA", description: "Get SSH CA",
params: z.object({ params: z.object({
sshCaId: z.string().trim().describe(SSH_CERTIFICATE_AUTHORITIES.GET.sshCaId) sshCaId: z.string().trim().describe(SSH_CERTIFICATE_AUTHORITIES.GET.sshCaId)
@@ -138,6 +142,8 @@ export const registerSshCaRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SshCertificateAuthorities],
description: "Get public key of SSH CA", description: "Get public key of SSH CA",
params: z.object({ params: z.object({
sshCaId: z.string().trim().describe(SSH_CERTIFICATE_AUTHORITIES.GET_PUBLIC_KEY.sshCaId) sshCaId: z.string().trim().describe(SSH_CERTIFICATE_AUTHORITIES.GET_PUBLIC_KEY.sshCaId)
@@ -163,6 +169,8 @@ export const registerSshCaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SshCertificateAuthorities],
description: "Update SSH CA", description: "Update SSH CA",
params: z.object({ params: z.object({
sshCaId: z.string().trim().describe(SSH_CERTIFICATE_AUTHORITIES.UPDATE.sshCaId) sshCaId: z.string().trim().describe(SSH_CERTIFICATE_AUTHORITIES.UPDATE.sshCaId)
@@ -216,6 +224,8 @@ export const registerSshCaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SshCertificateAuthorities],
description: "Delete SSH CA", description: "Delete SSH CA",
params: z.object({ params: z.object({
sshCaId: z.string().trim().describe(SSH_CERTIFICATE_AUTHORITIES.DELETE.sshCaId) sshCaId: z.string().trim().describe(SSH_CERTIFICATE_AUTHORITIES.DELETE.sshCaId)
@@ -261,6 +271,8 @@ export const registerSshCaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SshCertificateAuthorities],
description: "Get list of certificate templates for the SSH CA", description: "Get list of certificate templates for the SSH CA",
params: z.object({ params: z.object({
sshCaId: z.string().trim().describe(SSH_CERTIFICATE_AUTHORITIES.GET_CERTIFICATE_TEMPLATES.sshCaId) sshCaId: z.string().trim().describe(SSH_CERTIFICATE_AUTHORITIES.GET_CERTIFICATE_TEMPLATES.sshCaId)
@@ -3,7 +3,7 @@ import { z } from "zod";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { SshCertType } from "@app/ee/services/ssh/ssh-certificate-authority-types"; import { SshCertType } from "@app/ee/services/ssh/ssh-certificate-authority-types";
import { SshCertKeyAlgorithm } from "@app/ee/services/ssh-certificate/ssh-certificate-types"; import { SshCertKeyAlgorithm } from "@app/ee/services/ssh-certificate/ssh-certificate-types";
import { SSH_CERTIFICATE_AUTHORITIES } from "@app/lib/api-docs"; import { ApiDocsTags, SSH_CERTIFICATE_AUTHORITIES } from "@app/lib/api-docs";
import { ms } from "@app/lib/ms"; import { ms } from "@app/lib/ms";
import { writeLimit } from "@app/server/config/rateLimiter"; import { writeLimit } from "@app/server/config/rateLimiter";
import { getTelemetryDistinctId } from "@app/server/lib/telemetry"; import { getTelemetryDistinctId } from "@app/server/lib/telemetry";
@@ -20,6 +20,8 @@ export const registerSshCertRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SshCertificates],
description: "Sign SSH public key", description: "Sign SSH public key",
body: z.object({ body: z.object({
certificateTemplateId: z certificateTemplateId: z
@@ -100,6 +102,8 @@ export const registerSshCertRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SshCertificates],
description: "Issue SSH credentials (certificate + key)", description: "Issue SSH credentials (certificate + key)",
body: z.object({ body: z.object({
certificateTemplateId: z certificateTemplateId: z
@@ -8,7 +8,7 @@ import {
isValidHostPattern, isValidHostPattern,
isValidUserPattern isValidUserPattern
} from "@app/ee/services/ssh-certificate-template/ssh-certificate-template-validators"; } from "@app/ee/services/ssh-certificate-template/ssh-certificate-template-validators";
import { SSH_CERTIFICATE_TEMPLATES } from "@app/lib/api-docs"; import { ApiDocsTags, SSH_CERTIFICATE_TEMPLATES } from "@app/lib/api-docs";
import { ms } from "@app/lib/ms"; import { ms } from "@app/lib/ms";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
@@ -22,6 +22,8 @@ export const registerSshCertificateTemplateRouter = async (server: FastifyZodPro
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SshCertificateTemplates],
params: z.object({ params: z.object({
certificateTemplateId: z.string().describe(SSH_CERTIFICATE_TEMPLATES.GET.certificateTemplateId) certificateTemplateId: z.string().describe(SSH_CERTIFICATE_TEMPLATES.GET.certificateTemplateId)
}), }),
@@ -61,6 +63,8 @@ export const registerSshCertificateTemplateRouter = async (server: FastifyZodPro
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SshCertificateTemplates],
body: z body: z
.object({ .object({
sshCaId: z.string().describe(SSH_CERTIFICATE_TEMPLATES.CREATE.sshCaId), sshCaId: z.string().describe(SSH_CERTIFICATE_TEMPLATES.CREATE.sshCaId),
@@ -141,6 +145,8 @@ export const registerSshCertificateTemplateRouter = async (server: FastifyZodPro
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SshCertificateTemplates],
body: z.object({ body: z.object({
status: z.nativeEnum(SshCertTemplateStatus).optional(), status: z.nativeEnum(SshCertTemplateStatus).optional(),
name: z name: z
@@ -224,6 +230,8 @@ export const registerSshCertificateTemplateRouter = async (server: FastifyZodPro
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SshCertificateTemplates],
params: z.object({ params: z.object({
certificateTemplateId: z.string().describe(SSH_CERTIFICATE_TEMPLATES.DELETE.certificateTemplateId) certificateTemplateId: z.string().describe(SSH_CERTIFICATE_TEMPLATES.DELETE.certificateTemplateId)
}), }),
@@ -4,7 +4,7 @@ import { z } from "zod";
import { IdentityProjectAdditionalPrivilegeTemporaryMode } from "@app/ee/services/identity-project-additional-privilege-v2/identity-project-additional-privilege-v2-types"; import { IdentityProjectAdditionalPrivilegeTemporaryMode } from "@app/ee/services/identity-project-additional-privilege-v2/identity-project-additional-privilege-v2-types";
import { checkForInvalidPermissionCombination } from "@app/ee/services/permission/permission-fns"; import { checkForInvalidPermissionCombination } from "@app/ee/services/permission/permission-fns";
import { ProjectPermissionV2Schema } from "@app/ee/services/permission/project-permission"; import { ProjectPermissionV2Schema } from "@app/ee/services/permission/project-permission";
import { IDENTITY_ADDITIONAL_PRIVILEGE_V2 } from "@app/lib/api-docs"; import { ApiDocsTags, IDENTITY_ADDITIONAL_PRIVILEGE_V2 } from "@app/lib/api-docs";
import { ms } from "@app/lib/ms"; import { ms } from "@app/lib/ms";
import { alphaNumericNanoId } from "@app/lib/nanoid"; import { alphaNumericNanoId } from "@app/lib/nanoid";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
@@ -21,6 +21,8 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.IdentitySpecificPrivilegesV2],
description: "Add an additional privilege for identity.", description: "Add an additional privilege for identity.",
security: [ security: [
{ {
@@ -84,6 +86,8 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.IdentitySpecificPrivilegesV2],
description: "Update a specific identity privilege.", description: "Update a specific identity privilege.",
security: [ security: [
{ {
@@ -148,6 +152,8 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.IdentitySpecificPrivilegesV2],
description: "Delete the specified identity privilege.", description: "Delete the specified identity privilege.",
security: [ security: [
{ {
@@ -183,6 +189,8 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.IdentitySpecificPrivilegesV2],
description: "Retrieve details of a specific privilege by id.", description: "Retrieve details of a specific privilege by id.",
security: [ security: [
{ {
@@ -218,6 +226,8 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.IdentitySpecificPrivilegesV2],
description: "Retrieve details of a specific privilege by slug.", description: "Retrieve details of a specific privilege by slug.",
security: [ security: [
{ {
@@ -258,6 +268,8 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.IdentitySpecificPrivilegesV2],
description: "List privileges for the specified identity by project.", description: "List privileges for the specified identity by project.",
security: [ security: [
{ {
@@ -4,7 +4,7 @@ import { z } from "zod";
import { ProjectMembershipRole, ProjectRolesSchema } from "@app/db/schemas"; import { ProjectMembershipRole, ProjectRolesSchema } from "@app/db/schemas";
import { checkForInvalidPermissionCombination } from "@app/ee/services/permission/permission-fns"; import { checkForInvalidPermissionCombination } from "@app/ee/services/permission/permission-fns";
import { ProjectPermissionV2Schema } from "@app/ee/services/permission/project-permission"; import { ProjectPermissionV2Schema } from "@app/ee/services/permission/project-permission";
import { PROJECT_ROLE } from "@app/lib/api-docs"; import { ApiDocsTags, PROJECT_ROLE } from "@app/lib/api-docs";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { slugSchema } from "@app/server/lib/schemas"; import { slugSchema } from "@app/server/lib/schemas";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
@@ -20,6 +20,8 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ProjectRoles],
description: "Create a project role", description: "Create a project role",
security: [ security: [
{ {
@@ -75,6 +77,8 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ProjectRoles],
description: "Update a project role", description: "Update a project role",
security: [ security: [
{ {
@@ -130,6 +134,8 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ProjectRoles],
description: "Delete a project role", description: "Delete a project role",
security: [ security: [
{ {
@@ -166,6 +172,8 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ProjectRoles],
description: "List project role", description: "List project role",
security: [ security: [
{ {
@@ -204,6 +212,8 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ProjectRoles],
params: z.object({ params: z.object({
projectId: z.string().trim().describe(PROJECT_ROLE.GET_ROLE_BY_SLUG.projectId), projectId: z.string().trim().describe(PROJECT_ROLE.GET_ROLE_BY_SLUG.projectId),
roleSlug: z.string().trim().describe(PROJECT_ROLE.GET_ROLE_BY_SLUG.roleSlug) roleSlug: z.string().trim().describe(PROJECT_ROLE.GET_ROLE_BY_SLUG.roleSlug)
@@ -9,7 +9,7 @@ import {
TSecretRotationV2GeneratedCredentials, TSecretRotationV2GeneratedCredentials,
TSecretRotationV2Input TSecretRotationV2Input
} from "@app/ee/services/secret-rotation-v2/secret-rotation-v2-types"; } from "@app/ee/services/secret-rotation-v2/secret-rotation-v2-types";
import { SecretRotations } from "@app/lib/api-docs"; import { ApiDocsTags, SecretRotations } from "@app/lib/api-docs";
import { startsWithVowel } from "@app/lib/fn"; import { startsWithVowel } from "@app/lib/fn";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
@@ -66,6 +66,8 @@ export const registerSecretRotationEndpoints = <
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretRotations],
description: `List the ${rotationType} Rotations for the specified project.`, description: `List the ${rotationType} Rotations for the specified project.`,
querystring: z.object({ querystring: z.object({
projectId: z.string().trim().min(1, "Project ID required").describe(SecretRotations.LIST(type).projectId) projectId: z.string().trim().min(1, "Project ID required").describe(SecretRotations.LIST(type).projectId)
@@ -109,6 +111,8 @@ export const registerSecretRotationEndpoints = <
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretRotations],
description: `Get the specified ${rotationType} Rotation by ID.`, description: `Get the specified ${rotationType} Rotation by ID.`,
params: z.object({ params: z.object({
rotationId: z.string().uuid().describe(SecretRotations.GET_BY_ID(type).rotationId) rotationId: z.string().uuid().describe(SecretRotations.GET_BY_ID(type).rotationId)
@@ -151,6 +155,8 @@ export const registerSecretRotationEndpoints = <
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretRotations],
description: `Get the specified ${rotationType} Rotation by name, secret path, environment and project ID.`, description: `Get the specified ${rotationType} Rotation by name, secret path, environment and project ID.`,
params: z.object({ params: z.object({
rotationName: z rotationName: z
@@ -215,6 +221,8 @@ export const registerSecretRotationEndpoints = <
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretRotations],
description: `Create ${ description: `Create ${
startsWithVowel(rotationType) ? "an" : "a" startsWithVowel(rotationType) ? "an" : "a"
} ${rotationType} Rotation for the specified project.`, } ${rotationType} Rotation for the specified project.`,
@@ -254,6 +262,8 @@ export const registerSecretRotationEndpoints = <
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretRotations],
description: `Update the specified ${rotationType} Rotation.`, description: `Update the specified ${rotationType} Rotation.`,
params: z.object({ params: z.object({
rotationId: z.string().uuid().describe(SecretRotations.UPDATE(type).rotationId) rotationId: z.string().uuid().describe(SecretRotations.UPDATE(type).rotationId)
@@ -296,6 +306,8 @@ export const registerSecretRotationEndpoints = <
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretRotations],
description: `Delete the specified ${rotationType} Rotation.`, description: `Delete the specified ${rotationType} Rotation.`,
params: z.object({ params: z.object({
rotationId: z.string().uuid().describe(SecretRotations.DELETE(type).rotationId) rotationId: z.string().uuid().describe(SecretRotations.DELETE(type).rotationId)
@@ -349,6 +361,8 @@ export const registerSecretRotationEndpoints = <
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretRotations],
description: `Get the generated credentials for the specified ${rotationType} Rotation.`, description: `Get the generated credentials for the specified ${rotationType} Rotation.`,
params: z.object({ params: z.object({
rotationId: z.string().uuid().describe(SecretRotations.GET_GENERATED_CREDENTIALS_BY_ID(type).rotationId) rotationId: z.string().uuid().describe(SecretRotations.GET_GENERATED_CREDENTIALS_BY_ID(type).rotationId)
@@ -402,6 +416,8 @@ export const registerSecretRotationEndpoints = <
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretRotations],
description: `Rotate the generated credentials for the specified ${rotationType} Rotation.`, description: `Rotate the generated credentials for the specified ${rotationType} Rotation.`,
params: z.object({ params: z.object({
rotationId: z.string().uuid().describe(SecretRotations.ROTATE(type).rotationId) rotationId: z.string().uuid().describe(SecretRotations.ROTATE(type).rotationId)
@@ -5,7 +5,7 @@ import { Auth0ClientSecretRotationListItemSchema } from "@app/ee/services/secret
import { MsSqlCredentialsRotationListItemSchema } from "@app/ee/services/secret-rotation-v2/mssql-credentials"; import { MsSqlCredentialsRotationListItemSchema } from "@app/ee/services/secret-rotation-v2/mssql-credentials";
import { PostgresCredentialsRotationListItemSchema } from "@app/ee/services/secret-rotation-v2/postgres-credentials"; import { PostgresCredentialsRotationListItemSchema } from "@app/ee/services/secret-rotation-v2/postgres-credentials";
import { SecretRotationV2Schema } from "@app/ee/services/secret-rotation-v2/secret-rotation-v2-union-schema"; import { SecretRotationV2Schema } from "@app/ee/services/secret-rotation-v2/secret-rotation-v2-union-schema";
import { SecretRotations } from "@app/lib/api-docs"; import { ApiDocsTags, SecretRotations } from "@app/lib/api-docs";
import { readLimit } from "@app/server/config/rateLimiter"; import { readLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type"; import { AuthMode } from "@app/services/auth/auth-type";
@@ -24,6 +24,8 @@ export const registerSecretRotationV2Router = async (server: FastifyZodProvider)
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretRotations],
description: "List the available Secret Rotation Options.", description: "List the available Secret Rotation Options.",
response: { response: {
200: z.object({ 200: z.object({
@@ -45,6 +47,8 @@ export const registerSecretRotationV2Router = async (server: FastifyZodProvider)
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretRotations],
description: "List all the Secret Rotations for the specified project.", description: "List all the Secret Rotations for the specified project.",
querystring: z.object({ querystring: z.object({
projectId: z.string().trim().min(1, "Project ID required").describe(SecretRotations.LIST().projectId) projectId: z.string().trim().min(1, "Project ID required").describe(SecretRotations.LIST().projectId)
@@ -234,6 +234,7 @@ export enum EventType {
GET_PROJECT_KMS_BACKUP = "get-project-kms-backup", GET_PROJECT_KMS_BACKUP = "get-project-kms-backup",
LOAD_PROJECT_KMS_BACKUP = "load-project-kms-backup", LOAD_PROJECT_KMS_BACKUP = "load-project-kms-backup",
ORG_ADMIN_ACCESS_PROJECT = "org-admin-accessed-project", ORG_ADMIN_ACCESS_PROJECT = "org-admin-accessed-project",
ORG_ADMIN_BYPASS_SSO = "org-admin-bypassed-sso",
CREATE_CERTIFICATE_TEMPLATE = "create-certificate-template", CREATE_CERTIFICATE_TEMPLATE = "create-certificate-template",
UPDATE_CERTIFICATE_TEMPLATE = "update-certificate-template", UPDATE_CERTIFICATE_TEMPLATE = "update-certificate-template",
DELETE_CERTIFICATE_TEMPLATE = "delete-certificate-template", DELETE_CERTIFICATE_TEMPLATE = "delete-certificate-template",
@@ -1909,6 +1910,11 @@ interface OrgAdminAccessProjectEvent {
}; // no metadata yet }; // no metadata yet
} }
interface OrgAdminBypassSSOEvent {
type: EventType.ORG_ADMIN_BYPASS_SSO;
metadata: Record<string, string>; // no metadata yet
}
interface CreateCertificateTemplateEstConfig { interface CreateCertificateTemplateEstConfig {
type: EventType.CREATE_CERTIFICATE_TEMPLATE_EST_CONFIG; type: EventType.CREATE_CERTIFICATE_TEMPLATE_EST_CONFIG;
metadata: { metadata: {
@@ -2677,6 +2683,7 @@ export type Event =
| GetProjectKmsBackupEvent | GetProjectKmsBackupEvent
| LoadProjectKmsBackupEvent | LoadProjectKmsBackupEvent
| OrgAdminAccessProjectEvent | OrgAdminAccessProjectEvent
| OrgAdminBypassSSOEvent
| CreateCertificateTemplate | CreateCertificateTemplate
| UpdateCertificateTemplate | UpdateCertificateTemplate
| GetCertificateTemplate | GetCertificateTemplate
@@ -130,7 +130,17 @@ export const dynamicSecretLeaseServiceFactory = ({
if (expireAt > maxExpiryDate) throw new BadRequestError({ message: "TTL cannot be larger than max TTL" }); if (expireAt > maxExpiryDate) throw new BadRequestError({ message: "TTL cannot be larger than max TTL" });
} }
const { entityId, data } = await selectedProvider.create(decryptedStoredInput, expireAt.getTime()); let result;
try {
result = await selectedProvider.create(decryptedStoredInput, expireAt.getTime());
} catch (error: unknown) {
if (error && typeof error === "object" && error !== null && "sqlMessage" in error) {
throw new BadRequestError({ message: error.sqlMessage as string });
}
throw error;
}
const { entityId, data } = result;
const dynamicSecretLease = await dynamicSecretLeaseDAL.create({ const dynamicSecretLease = await dynamicSecretLeaseDAL.create({
expireAt, expireAt,
version: 1, version: 1,
@@ -2,6 +2,7 @@ import handlebars from "handlebars";
import ldapjs from "ldapjs"; import ldapjs from "ldapjs";
import ldif from "ldif"; import ldif from "ldif";
import { customAlphabet } from "nanoid"; import { customAlphabet } from "nanoid";
import RE2 from "re2";
import { z } from "zod"; import { z } from "zod";
import { BadRequestError } from "@app/lib/errors"; import { BadRequestError } from "@app/lib/errors";
@@ -194,7 +195,8 @@ export const LdapProvider = (): TDynamicProviderFns => {
const client = await $getClient(providerInputs); const client = await $getClient(providerInputs);
if (providerInputs.credentialType === LdapCredentialType.Static) { if (providerInputs.credentialType === LdapCredentialType.Static) {
const dnMatch = providerInputs.rotationLdif.match(/^dn:\s*(.+)/m); const dnRegex = new RE2("^dn:\\s*(.+)", "m");
const dnMatch = dnRegex.exec(providerInputs.rotationLdif);
if (dnMatch) { if (dnMatch) {
const username = dnMatch[1]; const username = dnMatch[1];
@@ -238,7 +240,8 @@ export const LdapProvider = (): TDynamicProviderFns => {
const client = await $getClient(providerInputs); const client = await $getClient(providerInputs);
if (providerInputs.credentialType === LdapCredentialType.Static) { if (providerInputs.credentialType === LdapCredentialType.Static) {
const dnMatch = providerInputs.rotationLdif.match(/^dn:\s*(.+)/m); const dnRegex = new RE2("^dn:\\s*(.+)", "m");
const dnMatch = dnRegex.exec(providerInputs.rotationLdif);
if (dnMatch) { if (dnMatch) {
const username = dnMatch[1]; const username = dnMatch[1];
@@ -1,6 +1,5 @@
import { TDbClient } from "@app/db"; import { TDbClient } from "@app/db";
import { TableName } from "@app/db/schemas"; import { TableName } from "@app/db/schemas";
import { DatabaseError } from "@app/lib/errors";
import { ormify } from "@app/lib/knex"; import { ormify } from "@app/lib/knex";
export type TOidcConfigDALFactory = ReturnType<typeof oidcConfigDALFactory>; export type TOidcConfigDALFactory = ReturnType<typeof oidcConfigDALFactory>;
@@ -8,22 +7,5 @@ export type TOidcConfigDALFactory = ReturnType<typeof oidcConfigDALFactory>;
export const oidcConfigDALFactory = (db: TDbClient) => { export const oidcConfigDALFactory = (db: TDbClient) => {
const oidcCfgOrm = ormify(db, TableName.OidcConfig); const oidcCfgOrm = ormify(db, TableName.OidcConfig);
const findEnforceableOidcCfg = async (orgId: string) => { return oidcCfgOrm;
try {
const oidcCfg = await db
.replicaNode()(TableName.OidcConfig)
.where({
orgId,
isActive: true
})
.whereNotNull("lastUsed")
.first();
return oidcCfg;
} catch (error) {
throw new DatabaseError({ error, name: "Find org by id" });
}
};
return { ...oidcCfgOrm, findEnforceableOidcCfg };
}; };
@@ -1,6 +1,5 @@
import { TDbClient } from "@app/db"; import { TDbClient } from "@app/db";
import { TableName } from "@app/db/schemas"; import { TableName } from "@app/db/schemas";
import { DatabaseError } from "@app/lib/errors";
import { ormify } from "@app/lib/knex"; import { ormify } from "@app/lib/knex";
export type TSamlConfigDALFactory = ReturnType<typeof samlConfigDALFactory>; export type TSamlConfigDALFactory = ReturnType<typeof samlConfigDALFactory>;
@@ -8,25 +7,5 @@ export type TSamlConfigDALFactory = ReturnType<typeof samlConfigDALFactory>;
export const samlConfigDALFactory = (db: TDbClient) => { export const samlConfigDALFactory = (db: TDbClient) => {
const samlCfgOrm = ormify(db, TableName.SamlConfig); const samlCfgOrm = ormify(db, TableName.SamlConfig);
const findEnforceableSamlCfg = async (orgId: string) => { return samlCfgOrm;
try {
const samlCfg = await db
.replicaNode()(TableName.SamlConfig)
.where({
orgId,
isActive: true
})
.whereNotNull("lastUsed")
.first();
return samlCfg;
} catch (error) {
throw new DatabaseError({ error, name: "Find org by id" });
}
};
return {
...samlCfgOrm,
findEnforceableSamlCfg
};
}; };
@@ -267,7 +267,6 @@ export const secretReplicationServiceFactory = ({
const sourceLocalSecrets = await secretV2BridgeDAL.find({ folderId: folder.id, type: SecretType.Shared }); const sourceLocalSecrets = await secretV2BridgeDAL.find({ folderId: folder.id, type: SecretType.Shared });
const sourceSecretImports = await secretImportDAL.find({ folderId: folder.id }); const sourceSecretImports = await secretImportDAL.find({ folderId: folder.id });
const sourceImportedSecrets = await fnSecretsV2FromImports({ const sourceImportedSecrets = await fnSecretsV2FromImports({
projectId,
secretImports: sourceSecretImports, secretImports: sourceSecretImports,
secretDAL: secretV2BridgeDAL, secretDAL: secretV2BridgeDAL,
folderDAL, folderDAL,
@@ -1,4 +1,5 @@
import { isIP } from "net"; import { isIP } from "net";
import RE2 from "re2";
import { isFQDN } from "@app/lib/validator/validate-url"; import { isFQDN } from "@app/lib/validator/validate-url";
@@ -10,7 +11,7 @@ export const isValidUserPattern = (value: string): boolean => {
if (value === "*") return true; // Handle wildcard separately if (value === "*") return true; // Handle wildcard separately
// Simpler, more specific pattern for usernames // Simpler, more specific pattern for usernames
const userRegex = /^[a-z_][a-z0-9_-]*$/i; const userRegex = new RE2(/^[a-z_][a-z0-9_-]*$/i);
return userRegex.test(value); return userRegex.test(value);
}; };
@@ -4,6 +4,7 @@ import { promises as fs } from "fs";
import { Knex } from "knex"; import { Knex } from "knex";
import os from "os"; import os from "os";
import path from "path"; import path from "path";
import RE2 from "re2";
import { promisify } from "util"; import { promisify } from "util";
import { TSshCertificateTemplates } from "@app/db/schemas"; import { TSshCertificateTemplates } from "@app/db/schemas";
@@ -156,14 +157,14 @@ export const validateSshCertificatePrincipals = (
}); });
} }
if (/\r|\n|\t|\0/.test(sanitized)) { if (new RE2(/\r|\n|\t|\0/).test(sanitized)) {
throw new BadRequestError({ throw new BadRequestError({
message: `Principal '${sanitized}' contains invalid whitespace or control characters.` message: `Principal '${sanitized}' contains invalid whitespace or control characters.`
}); });
} }
// disallow whitespace anywhere // disallow whitespace anywhere
if (/\s/.test(sanitized)) { if (new RE2(/\s/).test(sanitized)) {
throw new BadRequestError({ throw new BadRequestError({
message: `Principal '${sanitized}' cannot contain whitespace.` message: `Principal '${sanitized}' cannot contain whitespace.`
}); });
+54 -1
View File
@@ -8,6 +8,51 @@ import { APP_CONNECTION_NAME_MAP } from "@app/services/app-connection/app-connec
import { SecretSync } from "@app/services/secret-sync/secret-sync-enums"; import { SecretSync } from "@app/services/secret-sync/secret-sync-enums";
import { SECRET_SYNC_CONNECTION_MAP, SECRET_SYNC_NAME_MAP } from "@app/services/secret-sync/secret-sync-maps"; import { SECRET_SYNC_CONNECTION_MAP, SECRET_SYNC_NAME_MAP } from "@app/services/secret-sync/secret-sync-maps";
export enum ApiDocsTags {
Identities = "Identities",
TokenAuth = "Token Auth",
UniversalAuth = "Universal Auth",
GcpAuth = "GCP Auth",
AwsAuth = "AWS Auth",
AzureAuth = "Azure Auth",
KubernetesAuth = "Kubernetes Auth",
JwtAuth = "JWT Auth",
OidcAuth = "OIDC Auth",
Groups = "Groups",
Organizations = "Organizations",
Projects = "Projects",
ProjectUsers = "Project Users",
ProjectGroups = "Project Groups",
ProjectIdentities = "Project Identities",
ProjectRoles = "Project Roles",
ProjectTemplates = "Project Templates",
Environments = "Environments",
Folders = "Folders",
SecretTags = "Secret Tags",
Secrets = "Secrets",
DynamicSecrets = "Dynamic Secrets",
SecretImports = "Secret Imports",
SecretRotations = "Secret Rotations",
IdentitySpecificPrivilegesV1 = "Identity Specific Privileges",
IdentitySpecificPrivilegesV2 = "Identity Specific Privileges V2",
AppConnections = "App Connections",
SecretSyncs = "Secret Syncs",
Integrations = "Integrations",
ServiceTokens = "Service Tokens",
AuditLogs = "Audit Logs",
PkiCertificateAuthorities = "PKI Certificate Authorities",
PkiCertificates = "PKI Certificates",
PkiCertificateTemplates = "PKI Certificate Templates",
PkiCertificateCollections = "PKI Certificate Collections",
PkiAlerting = "PKI Alerting",
SshCertificates = "SSH Certificates",
SshCertificateAuthorities = "SSH Certificate Authorities",
SshCertificateTemplates = "SSH Certificate Templates",
KmsKeys = "KMS Keys",
KmsEncryption = "KMS Encryption",
KmsSigning = "KMS Signing"
}
export const GROUPS = { export const GROUPS = {
CREATE: { CREATE: {
name: "The name of the group to create.", name: "The name of the group to create.",
@@ -888,7 +933,7 @@ export const DYNAMIC_SECRETS = {
environmentSlug: "The slug of the environment to list folders from.", environmentSlug: "The slug of the environment to list folders from.",
path: "The path to list folders from." path: "The path to list folders from."
}, },
LIST_LEAES_BY_NAME: { LIST_LEASES_BY_NAME: {
projectSlug: "The slug of the project to create dynamic secret in.", projectSlug: "The slug of the project to create dynamic secret in.",
environmentSlug: "The slug of the environment to list folders from.", environmentSlug: "The slug of the environment to list folders from.",
path: "The path to list folders from.", path: "The path to list folders from.",
@@ -1808,6 +1853,10 @@ export const AppConnections = {
CAMUNDA: { CAMUNDA: {
clientId: "The client ID used to authenticate with Camunda.", clientId: "The client ID used to authenticate with Camunda.",
clientSecret: "The client secret used to authenticate with Camunda." clientSecret: "The client secret used to authenticate with Camunda."
},
WINDMILL: {
instanceUrl: "The Windmill instance URL to connect with (defaults to https://app.windmill.dev).",
accessToken: "The access token to use to connect with Windmill."
} }
} }
}; };
@@ -1943,6 +1992,10 @@ export const SecretSyncs = {
env: "The ID of the Vercel environment to sync secrets to.", env: "The ID of the Vercel environment to sync secrets to.",
branch: "The branch to sync preview secrets to.", branch: "The branch to sync preview secrets to.",
teamId: "The ID of the Vercel team to sync secrets to." teamId: "The ID of the Vercel team to sync secrets to."
},
WINDMILL: {
workspace: "The Windmill workspace to sync secrets to.",
path: "The Windmill workspace path to sync secrets to."
} }
} }
}; };
+8 -4
View File
@@ -1,12 +1,16 @@
import RE2 from "re2";
type Base64Options = { type Base64Options = {
urlSafe?: boolean; urlSafe?: boolean;
padding?: boolean; padding?: boolean;
}; };
const base64WithPadding = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$/; const base64WithPadding = new RE2(/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$/);
const base64WithoutPadding = /^[A-Za-z0-9+/]+$/; const base64WithoutPadding = new RE2(/^[A-Za-z0-9+/]+$/);
const base64UrlWithPadding = /^(?:[A-Za-z0-9_-]{4})*(?:[A-Za-z0-9_-]{2}==|[A-Za-z0-9_-]{3}=|[A-Za-z0-9_-]{4})$/; const base64UrlWithPadding = new RE2(
const base64UrlWithoutPadding = /^[A-Za-z0-9_-]+$/; /^(?:[A-Za-z0-9_-]{4})*(?:[A-Za-z0-9_-]{2}==|[A-Za-z0-9_-]{3}=|[A-Za-z0-9_-]{4})$/
);
const base64UrlWithoutPadding = new RE2(/^[A-Za-z0-9_-]+$/);
export const isBase64 = (str: string, options: Base64Options = {}): boolean => { export const isBase64 = (str: string, options: Base64Options = {}): boolean => {
if (typeof str !== "string") { if (typeof str !== "string") {
+4 -1
View File
@@ -1,4 +1,5 @@
import path from "path"; import path from "path";
import RE2 from "re2";
// given two paths irrespective of ending with / or not // given two paths irrespective of ending with / or not
// this will return true if its equal // this will return true if its equal
@@ -15,4 +16,6 @@ export const prefixWithSlash = (str: string) => {
return `/${str}`; return `/${str}`;
}; };
export const startsWithVowel = (str: string) => /^[aeiou]/i.test(str); const vowelRegex = new RE2(/^[aeiou]/i);
export const startsWithVowel = (str: string) => vowelRegex.test(str);
+2 -1
View File
@@ -1,3 +1,4 @@
import RE2 from "re2";
import { z } from "zod"; import { z } from "zod";
export enum CharacterType { export enum CharacterType {
@@ -92,7 +93,7 @@ export const characterValidator = (allowedCharacters: CharacterType[]) => {
const combinedPattern = allowedCharacters.map((char) => patternMap[char]).join(""); const combinedPattern = allowedCharacters.map((char) => patternMap[char]).join("");
// Create a regex that matches only the allowed characters // Create a regex that matches only the allowed characters
const regex = new RegExp(`^[${combinedPattern}]+$`); const regex = new RE2(`^[${combinedPattern}]+$`);
/** /**
* Validates if the input string contains only the allowed character types * Validates if the input string contains only the allowed character types
+13 -7
View File
@@ -1,6 +1,7 @@
import dns from "node:dns/promises"; import dns from "node:dns/promises";
import { isIPv4 } from "net"; import { isIPv4 } from "net";
import RE2 from "re2";
import { getConfig } from "@app/lib/config/env"; import { getConfig } from "@app/lib/config/env";
@@ -80,42 +81,47 @@ export const isFQDN = (str: string, options: FQDNOptions = {}): boolean => {
if ( if (
!opts.allow_numeric_tld && !opts.allow_numeric_tld &&
!/^([a-z\u00A1-\u00A8\u00AA-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{2,}|xn[a-z0-9-]{2,})$/i.test(tld) !new RE2(/^([a-z\u00A1-\u00A8\u00AA-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{2,}|xn[a-z0-9-]{2,})$/i).test(tld)
) { ) {
return false; return false;
} }
// disallow spaces // disallow spaces
if (/\s/.test(tld)) { if (new RE2(/\s/).test(tld)) {
return false; return false;
} }
} }
// reject numeric TLDs // reject numeric TLDs
if (!opts.allow_numeric_tld && /^\d+$/.test(tld)) { if (!opts.allow_numeric_tld && new RE2(/^\d+$/).test(tld)) {
return false; return false;
} }
const partRegex = new RE2(/^[a-z_\u00a1-\uffff0-9-]+$/i);
const fullWidthRegex = new RE2(/[\uff01-\uff5e]/);
const hyphenRegex = new RE2(/^-|-$/);
const underscoreRegex = new RE2(/_/);
return parts.every((part) => { return parts.every((part) => {
if (part.length > 63 && !opts.ignore_max_length) { if (part.length > 63 && !opts.ignore_max_length) {
return false; return false;
} }
if (!/^[a-z_\u00a1-\uffff0-9-]+$/i.test(part)) { if (!partRegex.test(part)) {
return false; return false;
} }
// disallow full-width chars // disallow full-width chars
if (/[\uff01-\uff5e]/.test(part)) { if (fullWidthRegex.test(part)) {
return false; return false;
} }
// disallow parts starting or ending with hyphen // disallow parts starting or ending with hyphen
if (/^-|-$/.test(part)) { if (hyphenRegex.test(part)) {
return false; return false;
} }
if (!opts.allow_underscores && /_/.test(part)) { if (!opts.allow_underscores && underscoreRegex.test(part)) {
return false; return false;
} }
+6
View File
@@ -1,3 +1,4 @@
import RE2 from "re2";
import { z, ZodTypeAny } from "zod"; import { z, ZodTypeAny } from "zod";
// this is a patched zod string to remove empty string to undefined // this is a patched zod string to remove empty string to undefined
@@ -11,3 +12,8 @@ export const zpStr = <T extends ZodTypeAny>(schema: T, opt: { stripNull: boolean
export const zodBuffer = z.custom<Buffer>((data) => Buffer.isBuffer(data) || data instanceof Uint8Array, { export const zodBuffer = z.custom<Buffer>((data) => Buffer.isBuffer(data) || data instanceof Uint8Array, {
message: "Expected binary data (Buffer Or Uint8Array)" message: "Expected binary data (Buffer Or Uint8Array)"
}); });
export const re2Validator = (pattern: string | RegExp) => {
const re2Pattern = new RE2(pattern);
return (value: string) => re2Pattern.test(value);
};
+10 -6
View File
@@ -73,6 +73,7 @@ const run = async () => {
// eslint-disable-next-line // eslint-disable-next-line
process.on("SIGINT", async () => { process.on("SIGINT", async () => {
await server.close(); await server.close();
await queue.shutdown();
await db.destroy(); await db.destroy();
await removeTemporaryBaseDirectory(); await removeTemporaryBaseDirectory();
hsmModule.finalize(); hsmModule.finalize();
@@ -82,19 +83,22 @@ const run = async () => {
// eslint-disable-next-line // eslint-disable-next-line
process.on("SIGTERM", async () => { process.on("SIGTERM", async () => {
await server.close(); await server.close();
await queue.shutdown();
await db.destroy(); await db.destroy();
await removeTemporaryBaseDirectory(); await removeTemporaryBaseDirectory();
hsmModule.finalize(); hsmModule.finalize();
process.exit(0); process.exit(0);
}); });
process.on("uncaughtException", (error) => { if (!envConfig.isDevelopmentMode) {
logger.error(error, "CRITICAL ERROR: Uncaught Exception"); process.on("uncaughtException", (error) => {
}); logger.error(error, "CRITICAL ERROR: Uncaught Exception");
});
process.on("unhandledRejection", (error) => { process.on("unhandledRejection", (error) => {
logger.error(error, "CRITICAL ERROR: Unhandled Promise Rejection"); logger.error(error, "CRITICAL ERROR: Unhandled Promise Rejection");
}); });
}
await server.listen({ await server.listen({
port: envConfig.PORT, port: envConfig.PORT,
+5 -2
View File
@@ -49,14 +49,17 @@ function resolveSchema(maybeSchema: ZodAny | { properties: ZodAny }): Pick<ZodAn
} }
export const createJsonSchemaTransform = ({ skipList }: { skipList: readonly string[] }) => { export const createJsonSchemaTransform = ({ skipList }: { skipList: readonly string[] }) => {
return ({ schema, url }: { schema: Schema; url: string }) => { return ({ schema = {}, url }: { schema: Schema; url: string }) => {
if (!schema) { if (!schema) {
return { return {
schema, schema: { hide: true },
url url
}; };
} }
if (typeof schema.hide === "undefined") {
schema.hide = true;
}
const { response, headers, querystring, body, params, hide, ...rest } = schema; const { response, headers, querystring, body, params, hide, ...rest } = schema;
const transformed: FreeformRecord = {}; const transformed: FreeformRecord = {};
+10 -2
View File
@@ -596,7 +596,14 @@ export const registerRoutes = async (
kmsService kmsService
}); });
const loginService = authLoginServiceFactory({ userDAL, smtpService, tokenService, orgDAL, totpService }); const loginService = authLoginServiceFactory({
userDAL,
smtpService,
tokenService,
orgDAL,
totpService,
auditLogService
});
const passwordService = authPaswordServiceFactory({ const passwordService = authPaswordServiceFactory({
tokenService, tokenService,
smtpService, smtpService,
@@ -1089,7 +1096,8 @@ export const registerRoutes = async (
secretApprovalRequestSecretDAL, secretApprovalRequestSecretDAL,
kmsService, kmsService,
snapshotService, snapshotService,
resourceMetadataDAL resourceMetadataDAL,
keyStore
}); });
const secretApprovalRequestService = secretApprovalRequestServiceFactory({ const secretApprovalRequestService = secretApprovalRequestServiceFactory({
@@ -1,7 +1,7 @@
import { z } from "zod"; import { z } from "zod";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { AppConnections } from "@app/lib/api-docs"; import { ApiDocsTags, AppConnections } from "@app/lib/api-docs";
import { startsWithVowel } from "@app/lib/fn"; import { startsWithVowel } from "@app/lib/fn";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
@@ -43,6 +43,8 @@ export const registerAppConnectionEndpoints = <T extends TAppConnection, I exten
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.AppConnections],
description: `List the ${appName} Connections for the current organization.`, description: `List the ${appName} Connections for the current organization.`,
response: { response: {
200: z.object({ appConnections: sanitizedResponseSchema.array() }) 200: z.object({ appConnections: sanitizedResponseSchema.array() })
@@ -76,6 +78,8 @@ export const registerAppConnectionEndpoints = <T extends TAppConnection, I exten
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.AppConnections],
description: `List the ${appName} Connections the current user has permission to establish connections with.`, description: `List the ${appName} Connections the current user has permission to establish connections with.`,
response: { response: {
200: z.object({ 200: z.object({
@@ -120,6 +124,8 @@ export const registerAppConnectionEndpoints = <T extends TAppConnection, I exten
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.AppConnections],
description: `Get the specified ${appName} Connection by ID.`, description: `Get the specified ${appName} Connection by ID.`,
params: z.object({ params: z.object({
connectionId: z.string().uuid().describe(AppConnections.GET_BY_ID(app).connectionId) connectionId: z.string().uuid().describe(AppConnections.GET_BY_ID(app).connectionId)
@@ -160,6 +166,8 @@ export const registerAppConnectionEndpoints = <T extends TAppConnection, I exten
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.AppConnections],
description: `Get the specified ${appName} Connection by name.`, description: `Get the specified ${appName} Connection by name.`,
params: z.object({ params: z.object({
connectionName: z connectionName: z
@@ -204,6 +212,8 @@ export const registerAppConnectionEndpoints = <T extends TAppConnection, I exten
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.AppConnections],
description: `Create ${ description: `Create ${
startsWithVowel(appName) ? "an" : "a" startsWithVowel(appName) ? "an" : "a"
} ${appName} Connection for the current organization.`, } ${appName} Connection for the current organization.`,
@@ -247,6 +257,8 @@ export const registerAppConnectionEndpoints = <T extends TAppConnection, I exten
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.AppConnections],
description: `Update the specified ${appName} Connection.`, description: `Update the specified ${appName} Connection.`,
params: z.object({ params: z.object({
connectionId: z.string().uuid().describe(AppConnections.UPDATE(app).connectionId) connectionId: z.string().uuid().describe(AppConnections.UPDATE(app).connectionId)
@@ -292,6 +304,8 @@ export const registerAppConnectionEndpoints = <T extends TAppConnection, I exten
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.AppConnections],
description: `Delete the specified ${appName} Connection.`, description: `Delete the specified ${appName} Connection.`,
params: z.object({ params: z.object({
connectionId: z.string().uuid().describe(AppConnections.DELETE(app).connectionId) connectionId: z.string().uuid().describe(AppConnections.DELETE(app).connectionId)
@@ -1,6 +1,7 @@
import { z } from "zod"; import { z } from "zod";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { ApiDocsTags } from "@app/lib/api-docs";
import { readLimit } from "@app/server/config/rateLimiter"; import { readLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { Auth0ConnectionListItemSchema, SanitizedAuth0ConnectionSchema } from "@app/services/app-connection/auth0"; import { Auth0ConnectionListItemSchema, SanitizedAuth0ConnectionSchema } from "@app/services/app-connection/auth0";
@@ -37,6 +38,10 @@ import {
TerraformCloudConnectionListItemSchema TerraformCloudConnectionListItemSchema
} from "@app/services/app-connection/terraform-cloud"; } from "@app/services/app-connection/terraform-cloud";
import { SanitizedVercelConnectionSchema, VercelConnectionListItemSchema } from "@app/services/app-connection/vercel"; import { SanitizedVercelConnectionSchema, VercelConnectionListItemSchema } from "@app/services/app-connection/vercel";
import {
SanitizedWindmillConnectionSchema,
WindmillConnectionListItemSchema
} from "@app/services/app-connection/windmill";
import { AuthMode } from "@app/services/auth/auth-type"; import { AuthMode } from "@app/services/auth/auth-type";
// can't use discriminated due to multiple schemas for certain apps // can't use discriminated due to multiple schemas for certain apps
@@ -53,6 +58,7 @@ const SanitizedAppConnectionSchema = z.union([
...SanitizedPostgresConnectionSchema.options, ...SanitizedPostgresConnectionSchema.options,
...SanitizedMsSqlConnectionSchema.options, ...SanitizedMsSqlConnectionSchema.options,
...SanitizedCamundaConnectionSchema.options, ...SanitizedCamundaConnectionSchema.options,
...SanitizedWindmillConnectionSchema.options,
...SanitizedAuth0ConnectionSchema.options ...SanitizedAuth0ConnectionSchema.options
]); ]);
@@ -69,6 +75,7 @@ const AppConnectionOptionsSchema = z.discriminatedUnion("app", [
PostgresConnectionListItemSchema, PostgresConnectionListItemSchema,
MsSqlConnectionListItemSchema, MsSqlConnectionListItemSchema,
CamundaConnectionListItemSchema, CamundaConnectionListItemSchema,
WindmillConnectionListItemSchema,
Auth0ConnectionListItemSchema Auth0ConnectionListItemSchema
]); ]);
@@ -80,6 +87,8 @@ export const registerAppConnectionRouter = async (server: FastifyZodProvider) =>
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.AppConnections],
description: "List the available App Connection Options.", description: "List the available App Connection Options.",
response: { response: {
200: z.object({ 200: z.object({
@@ -101,6 +110,8 @@ export const registerAppConnectionRouter = async (server: FastifyZodProvider) =>
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.AppConnections],
description: "List all the App Connections for the current organization.", description: "List all the App Connections for the current organization.",
response: { response: {
200: z.object({ appConnections: SanitizedAppConnectionSchema.array() }) 200: z.object({ appConnections: SanitizedAppConnectionSchema.array() })
@@ -13,6 +13,7 @@ import { registerMsSqlConnectionRouter } from "./mssql-connection-router";
import { registerPostgresConnectionRouter } from "./postgres-connection-router"; import { registerPostgresConnectionRouter } from "./postgres-connection-router";
import { registerTerraformCloudConnectionRouter } from "./terraform-cloud-router"; import { registerTerraformCloudConnectionRouter } from "./terraform-cloud-router";
import { registerVercelConnectionRouter } from "./vercel-connection-router"; import { registerVercelConnectionRouter } from "./vercel-connection-router";
import { registerWindmillConnectionRouter } from "./windmill-connection-router";
export * from "./app-connection-router"; export * from "./app-connection-router";
@@ -30,5 +31,6 @@ export const APP_CONNECTION_REGISTER_ROUTER_MAP: Record<AppConnection, (server:
[AppConnection.Postgres]: registerPostgresConnectionRouter, [AppConnection.Postgres]: registerPostgresConnectionRouter,
[AppConnection.MsSql]: registerMsSqlConnectionRouter, [AppConnection.MsSql]: registerMsSqlConnectionRouter,
[AppConnection.Camunda]: registerCamundaConnectionRouter, [AppConnection.Camunda]: registerCamundaConnectionRouter,
[AppConnection.Windmill]: registerWindmillConnectionRouter,
[AppConnection.Auth0]: registerAuth0ConnectionRouter [AppConnection.Auth0]: registerAuth0ConnectionRouter
}; };
@@ -0,0 +1,53 @@
import z from "zod";
import { readLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
import {
CreateWindmillConnectionSchema,
SanitizedWindmillConnectionSchema,
UpdateWindmillConnectionSchema
} from "@app/services/app-connection/windmill";
import { AuthMode } from "@app/services/auth/auth-type";
import { registerAppConnectionEndpoints } from "./app-connection-endpoints";
export const registerWindmillConnectionRouter = async (server: FastifyZodProvider) => {
registerAppConnectionEndpoints({
app: AppConnection.Windmill,
server,
sanitizedResponseSchema: SanitizedWindmillConnectionSchema,
createSchema: CreateWindmillConnectionSchema,
updateSchema: UpdateWindmillConnectionSchema
});
// The below endpoints are not exposed and for Infisical App use
server.route({
method: "GET",
url: `/:connectionId/workspaces`,
config: {
rateLimit: readLimit
},
schema: {
params: z.object({
connectionId: z.string().uuid()
}),
response: {
200: z
.object({
id: z.string(),
name: z.string()
})
.array()
}
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => {
const { connectionId } = req.params;
const workspaces = await server.services.appConnection.windmill.listWorkspaces(connectionId, req.permission);
return workspaces;
}
});
};
@@ -3,7 +3,7 @@ import { z } from "zod";
import { CertificateAuthoritiesSchema, CertificateTemplatesSchema } from "@app/db/schemas"; import { CertificateAuthoritiesSchema, CertificateTemplatesSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { CERTIFICATE_AUTHORITIES } from "@app/lib/api-docs"; import { ApiDocsTags, CERTIFICATE_AUTHORITIES } from "@app/lib/api-docs";
import { ms } from "@app/lib/ms"; import { ms } from "@app/lib/ms";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { getTelemetryDistinctId } from "@app/server/lib/telemetry"; import { getTelemetryDistinctId } from "@app/server/lib/telemetry";
@@ -26,6 +26,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateAuthorities],
description: "Create CA", description: "Create CA",
body: z body: z
.object({ .object({
@@ -105,6 +107,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateAuthorities],
description: "Get CA", description: "Get CA",
params: z.object({ params: z.object({
caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.GET.caId) caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.GET.caId)
@@ -151,6 +155,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateAuthorities],
description: "Get DER-encoded certificate of CA", description: "Get DER-encoded certificate of CA",
params: z.object({ params: z.object({
caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.GET_CERT_BY_ID.caId), caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.GET_CERT_BY_ID.caId),
@@ -177,6 +183,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateAuthorities],
description: "Update CA", description: "Update CA",
params: z.object({ params: z.object({
caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.UPDATE.caId) caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.UPDATE.caId)
@@ -231,6 +239,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateAuthorities],
description: "Delete CA", description: "Delete CA",
params: z.object({ params: z.object({
caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.DELETE.caId) caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.DELETE.caId)
@@ -276,6 +286,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateAuthorities],
description: "Get CA CSR", description: "Get CA CSR",
params: z.object({ params: z.object({
caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.GET_CSR.caId) caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.GET_CSR.caId)
@@ -321,6 +333,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateAuthorities],
description: "Perform CA certificate renewal", description: "Perform CA certificate renewal",
params: z.object({ params: z.object({
caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.RENEW_CA_CERT.caId) caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.RENEW_CA_CERT.caId)
@@ -376,6 +390,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateAuthorities],
description: "Get list of past and current CA certificates for a CA", description: "Get list of past and current CA certificates for a CA",
params: z.object({ params: z.object({
caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.GET_CA_CERTS.caId) caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.GET_CA_CERTS.caId)
@@ -424,6 +440,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateAuthorities],
description: "Get current CA cert and cert chain of a CA", description: "Get current CA cert and cert chain of a CA",
params: z.object({ params: z.object({
caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.GET_CERT.caId) caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.GET_CERT.caId)
@@ -473,6 +491,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateAuthorities],
description: "Create intermediate CA certificate from parent CA", description: "Create intermediate CA certificate from parent CA",
params: z.object({ params: z.object({
caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.SIGN_INTERMEDIATE.caId) caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.SIGN_INTERMEDIATE.caId)
@@ -536,6 +556,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateAuthorities],
description: "Import certificate and chain to CA", description: "Import certificate and chain to CA",
params: z.object({ params: z.object({
caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.IMPORT_CERT.caId) caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.IMPORT_CERT.caId)
@@ -588,6 +610,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateAuthorities],
description: "Issue certificate from CA", description: "Issue certificate from CA",
params: z.object({ params: z.object({
caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.ISSUE_CERT.caId) caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.ISSUE_CERT.caId)
@@ -679,6 +703,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateAuthorities],
description: "Sign certificate from CA", description: "Sign certificate from CA",
params: z.object({ params: z.object({
caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.SIGN_CERT.caId) caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.SIGN_CERT.caId)
@@ -770,6 +796,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateAuthorities],
description: "Get list of certificate templates for the CA", description: "Get list of certificate templates for the CA",
params: z.object({ params: z.object({
caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.SIGN_CERT.caId) caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.SIGN_CERT.caId)
@@ -815,6 +843,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateAuthorities],
description: "Get list of CRLs of the CA", description: "Get list of CRLs of the CA",
params: z.object({ params: z.object({
caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.GET_CRLS.caId) caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.GET_CRLS.caId)
@@ -2,7 +2,7 @@ import { z } from "zod";
import { CertificatesSchema } from "@app/db/schemas"; import { CertificatesSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { CERTIFICATE_AUTHORITIES, CERTIFICATES } from "@app/lib/api-docs"; import { ApiDocsTags, CERTIFICATE_AUTHORITIES, CERTIFICATES } from "@app/lib/api-docs";
import { ms } from "@app/lib/ms"; import { ms } from "@app/lib/ms";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { getTelemetryDistinctId } from "@app/server/lib/telemetry"; import { getTelemetryDistinctId } from "@app/server/lib/telemetry";
@@ -24,6 +24,8 @@ export const registerCertRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificates],
description: "Get certificate", description: "Get certificate",
params: z.object({ params: z.object({
serialNumber: z.string().trim().describe(CERTIFICATES.GET.serialNumber) serialNumber: z.string().trim().describe(CERTIFICATES.GET.serialNumber)
@@ -70,6 +72,8 @@ export const registerCertRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificates],
description: "Issue certificate", description: "Issue certificate",
body: z body: z
.object({ .object({
@@ -181,6 +185,8 @@ export const registerCertRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificates],
description: "Sign certificate", description: "Sign certificate",
body: z body: z
.object({ .object({
@@ -292,6 +298,8 @@ export const registerCertRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificates],
description: "Revoke", description: "Revoke",
params: z.object({ params: z.object({
serialNumber: z.string().trim().describe(CERTIFICATES.REVOKE.serialNumber) serialNumber: z.string().trim().describe(CERTIFICATES.REVOKE.serialNumber)
@@ -346,6 +354,8 @@ export const registerCertRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificates],
description: "Delete certificate", description: "Delete certificate",
params: z.object({ params: z.object({
serialNumber: z.string().trim().describe(CERTIFICATES.DELETE.serialNumber) serialNumber: z.string().trim().describe(CERTIFICATES.DELETE.serialNumber)
@@ -392,6 +402,8 @@ export const registerCertRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificates],
description: "Get certificate body of certificate", description: "Get certificate body of certificate",
params: z.object({ params: z.object({
serialNumber: z.string().trim().describe(CERTIFICATES.GET_CERT.serialNumber) serialNumber: z.string().trim().describe(CERTIFICATES.GET_CERT.serialNumber)
@@ -2,7 +2,7 @@ import { z } from "zod";
import { CertificateTemplateEstConfigsSchema } from "@app/db/schemas"; import { CertificateTemplateEstConfigsSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { CERTIFICATE_TEMPLATES } from "@app/lib/api-docs"; import { ApiDocsTags, CERTIFICATE_TEMPLATES } from "@app/lib/api-docs";
import { ms } from "@app/lib/ms"; import { ms } from "@app/lib/ms";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
@@ -26,6 +26,8 @@ export const registerCertificateTemplateRouter = async (server: FastifyZodProvid
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateTemplates],
params: z.object({ params: z.object({
certificateTemplateId: z.string().describe(CERTIFICATE_TEMPLATES.GET.certificateTemplateId) certificateTemplateId: z.string().describe(CERTIFICATE_TEMPLATES.GET.certificateTemplateId)
}), }),
@@ -65,6 +67,8 @@ export const registerCertificateTemplateRouter = async (server: FastifyZodProvid
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateTemplates],
body: z.object({ body: z.object({
caId: z.string().describe(CERTIFICATE_TEMPLATES.CREATE.caId), caId: z.string().describe(CERTIFICATE_TEMPLATES.CREATE.caId),
pkiCollectionId: z.string().optional().describe(CERTIFICATE_TEMPLATES.CREATE.pkiCollectionId), pkiCollectionId: z.string().optional().describe(CERTIFICATE_TEMPLATES.CREATE.pkiCollectionId),
@@ -132,6 +136,8 @@ export const registerCertificateTemplateRouter = async (server: FastifyZodProvid
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateTemplates],
body: z.object({ body: z.object({
caId: z.string().optional().describe(CERTIFICATE_TEMPLATES.UPDATE.caId), caId: z.string().optional().describe(CERTIFICATE_TEMPLATES.UPDATE.caId),
pkiCollectionId: z.string().optional().describe(CERTIFICATE_TEMPLATES.UPDATE.pkiCollectionId), pkiCollectionId: z.string().optional().describe(CERTIFICATE_TEMPLATES.UPDATE.pkiCollectionId),
@@ -198,6 +204,8 @@ export const registerCertificateTemplateRouter = async (server: FastifyZodProvid
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateTemplates],
params: z.object({ params: z.object({
certificateTemplateId: z.string().describe(CERTIFICATE_TEMPLATES.DELETE.certificateTemplateId) certificateTemplateId: z.string().describe(CERTIFICATE_TEMPLATES.DELETE.certificateTemplateId)
}), }),
@@ -238,6 +246,8 @@ export const registerCertificateTemplateRouter = async (server: FastifyZodProvid
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateTemplates],
description: "Create Certificate Template EST configuration", description: "Create Certificate Template EST configuration",
params: z.object({ params: z.object({
certificateTemplateId: z.string().trim() certificateTemplateId: z.string().trim()
@@ -292,6 +302,8 @@ export const registerCertificateTemplateRouter = async (server: FastifyZodProvid
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateTemplates],
description: "Update Certificate Template EST configuration", description: "Update Certificate Template EST configuration",
params: z.object({ params: z.object({
certificateTemplateId: z.string().trim() certificateTemplateId: z.string().trim()
@@ -340,6 +352,8 @@ export const registerCertificateTemplateRouter = async (server: FastifyZodProvid
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateTemplates],
description: "Get Certificate Template EST configuration", description: "Get Certificate Template EST configuration",
params: z.object({ params: z.object({
certificateTemplateId: z.string().trim() certificateTemplateId: z.string().trim()
+25 -1
View File
@@ -2,7 +2,7 @@ import { z } from "zod";
import { InternalKmsSchema, KmsKeysSchema } from "@app/db/schemas"; import { InternalKmsSchema, KmsKeysSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { KMS } from "@app/lib/api-docs"; import { ApiDocsTags, KMS } from "@app/lib/api-docs";
import { getBase64SizeInBytes, isBase64 } from "@app/lib/base64"; import { getBase64SizeInBytes, isBase64 } from "@app/lib/base64";
import { AllowedEncryptionKeyAlgorithms, SymmetricKeyAlgorithm } from "@app/lib/crypto/cipher"; import { AllowedEncryptionKeyAlgorithms, SymmetricKeyAlgorithm } from "@app/lib/crypto/cipher";
import { AsymmetricKeyAlgorithm, SigningAlgorithm } from "@app/lib/crypto/sign"; import { AsymmetricKeyAlgorithm, SigningAlgorithm } from "@app/lib/crypto/sign";
@@ -46,6 +46,8 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.KmsKeys],
description: "Create KMS key", description: "Create KMS key",
body: z body: z
.object({ .object({
@@ -138,6 +140,8 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.KmsKeys],
description: "Update KMS key", description: "Update KMS key",
params: z.object({ params: z.object({
keyId: z.string().uuid().describe(KMS.UPDATE_KEY.keyId) keyId: z.string().uuid().describe(KMS.UPDATE_KEY.keyId)
@@ -187,6 +191,8 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.KmsKeys],
description: "Delete KMS key", description: "Delete KMS key",
params: z.object({ params: z.object({
keyId: z.string().uuid().describe(KMS.DELETE_KEY.keyId) keyId: z.string().uuid().describe(KMS.DELETE_KEY.keyId)
@@ -229,6 +235,8 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.KmsKeys],
description: "List KMS keys", description: "List KMS keys",
querystring: z.object({ querystring: z.object({
projectId: z.string().describe(KMS.LIST_KEYS.projectId), projectId: z.string().describe(KMS.LIST_KEYS.projectId),
@@ -280,6 +288,8 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.KmsKeys],
description: "Get KMS key by ID", description: "Get KMS key by ID",
params: z.object({ params: z.object({
keyId: z.string().uuid().describe(KMS.GET_KEY_BY_ID.keyId) keyId: z.string().uuid().describe(KMS.GET_KEY_BY_ID.keyId)
@@ -321,6 +331,8 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.KmsKeys],
description: "Get KMS key by name", description: "Get KMS key by name",
params: z.object({ params: z.object({
keyName: slugSchema({ field: "Key name" }).describe(KMS.GET_KEY_BY_NAME.keyName) keyName: slugSchema({ field: "Key name" }).describe(KMS.GET_KEY_BY_NAME.keyName)
@@ -367,6 +379,8 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.KmsEncryption],
description: "Encrypt data with KMS key", description: "Encrypt data with KMS key",
params: z.object({ params: z.object({
keyId: z.string().uuid().describe(KMS.ENCRYPT.keyId) keyId: z.string().uuid().describe(KMS.ENCRYPT.keyId)
@@ -412,6 +426,8 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.KmsSigning],
description: description:
"Get the public key for a KMS key that is used for signing and verifying data. This endpoint is only available for asymmetric keys.", "Get the public key for a KMS key that is used for signing and verifying data. This endpoint is only available for asymmetric keys.",
params: z.object({ params: z.object({
@@ -454,6 +470,8 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.KmsSigning],
description: "List all available signing algorithms for a KMS key", description: "List all available signing algorithms for a KMS key",
params: z.object({ params: z.object({
keyId: z.string().uuid().describe(KMS.LIST_SIGNING_ALGORITHMS.keyId) keyId: z.string().uuid().describe(KMS.LIST_SIGNING_ALGORITHMS.keyId)
@@ -495,6 +513,8 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.KmsSigning],
description: "Sign data with a KMS key.", description: "Sign data with a KMS key.",
params: z.object({ params: z.object({
keyId: z.string().uuid().describe(KMS.SIGN.keyId) keyId: z.string().uuid().describe(KMS.SIGN.keyId)
@@ -548,6 +568,8 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.KmsSigning],
description: "Verify data signatures with a KMS key.", description: "Verify data signatures with a KMS key.",
params: z.object({ params: z.object({
keyId: z.string().uuid().describe(KMS.VERIFY.keyId) keyId: z.string().uuid().describe(KMS.VERIFY.keyId)
@@ -604,6 +626,8 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.KmsEncryption],
description: "Decrypt data with KMS key", description: "Decrypt data with KMS key",
params: z.object({ params: z.object({
keyId: z.string().uuid().describe(KMS.DECRYPT.keyId) keyId: z.string().uuid().describe(KMS.DECRYPT.keyId)
@@ -1,6 +1,6 @@
import { z } from "zod"; import { z } from "zod";
import { UNIVERSAL_AUTH } from "@app/lib/api-docs"; import { ApiDocsTags, UNIVERSAL_AUTH } from "@app/lib/api-docs";
import { writeLimit } from "@app/server/config/rateLimiter"; import { writeLimit } from "@app/server/config/rateLimiter";
export const registerIdentityAccessTokenRouter = async (server: FastifyZodProvider) => { export const registerIdentityAccessTokenRouter = async (server: FastifyZodProvider) => {
@@ -11,6 +11,8 @@ export const registerIdentityAccessTokenRouter = async (server: FastifyZodProvid
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.UniversalAuth],
description: "Renew access token", description: "Renew access token",
body: z.object({ body: z.object({
accessToken: z.string().trim().describe(UNIVERSAL_AUTH.RENEW_ACCESS_TOKEN.accessToken) accessToken: z.string().trim().describe(UNIVERSAL_AUTH.RENEW_ACCESS_TOKEN.accessToken)
@@ -44,6 +46,8 @@ export const registerIdentityAccessTokenRouter = async (server: FastifyZodProvid
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.UniversalAuth],
description: "Revoke access token", description: "Revoke access token",
body: z.object({ body: z.object({
accessToken: z.string().trim().describe(UNIVERSAL_AUTH.REVOKE_ACCESS_TOKEN.accessToken) accessToken: z.string().trim().describe(UNIVERSAL_AUTH.REVOKE_ACCESS_TOKEN.accessToken)
@@ -2,7 +2,7 @@ import { z } from "zod";
import { IdentityAwsAuthsSchema } from "@app/db/schemas"; import { IdentityAwsAuthsSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { AWS_AUTH } from "@app/lib/api-docs"; import { ApiDocsTags, AWS_AUTH } from "@app/lib/api-docs";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type"; import { AuthMode } from "@app/services/auth/auth-type";
@@ -21,6 +21,8 @@ export const registerIdentityAwsAuthRouter = async (server: FastifyZodProvider)
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.AwsAuth],
description: "Login with AWS Auth", description: "Login with AWS Auth",
body: z.object({ body: z.object({
identityId: z.string().trim().describe(AWS_AUTH.LOGIN.identityId), identityId: z.string().trim().describe(AWS_AUTH.LOGIN.identityId),
@@ -71,6 +73,8 @@ export const registerIdentityAwsAuthRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.AwsAuth],
description: "Attach AWS Auth configuration onto identity", description: "Attach AWS Auth configuration onto identity",
security: [ security: [
{ {
@@ -165,6 +169,8 @@ export const registerIdentityAwsAuthRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.AwsAuth],
description: "Update AWS Auth configuration on identity", description: "Update AWS Auth configuration on identity",
security: [ security: [
{ {
@@ -247,6 +253,8 @@ export const registerIdentityAwsAuthRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.AwsAuth],
description: "Retrieve AWS Auth configuration on identity", description: "Retrieve AWS Auth configuration on identity",
security: [ security: [
{ {
@@ -293,6 +301,8 @@ export const registerIdentityAwsAuthRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.AwsAuth],
description: "Delete AWS Auth configuration on identity", description: "Delete AWS Auth configuration on identity",
security: [ security: [
{ {
@@ -2,7 +2,7 @@ import { z } from "zod";
import { IdentityAzureAuthsSchema } from "@app/db/schemas"; import { IdentityAzureAuthsSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { AZURE_AUTH } from "@app/lib/api-docs"; import { ApiDocsTags, AZURE_AUTH } from "@app/lib/api-docs";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type"; import { AuthMode } from "@app/services/auth/auth-type";
@@ -18,6 +18,8 @@ export const registerIdentityAzureAuthRouter = async (server: FastifyZodProvider
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.AzureAuth],
description: "Login with Azure Auth", description: "Login with Azure Auth",
body: z.object({ body: z.object({
identityId: z.string().trim().describe(AZURE_AUTH.LOGIN.identityId), identityId: z.string().trim().describe(AZURE_AUTH.LOGIN.identityId),
@@ -66,6 +68,8 @@ export const registerIdentityAzureAuthRouter = async (server: FastifyZodProvider
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.AzureAuth],
description: "Attach Azure Auth configuration onto identity", description: "Attach Azure Auth configuration onto identity",
security: [ security: [
{ {
@@ -159,6 +163,8 @@ export const registerIdentityAzureAuthRouter = async (server: FastifyZodProvider
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.AzureAuth],
description: "Update Azure Auth configuration on identity", description: "Update Azure Auth configuration on identity",
security: [ security: [
{ {
@@ -247,6 +253,8 @@ export const registerIdentityAzureAuthRouter = async (server: FastifyZodProvider
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.AzureAuth],
description: "Retrieve Azure Auth configuration on identity", description: "Retrieve Azure Auth configuration on identity",
security: [ security: [
{ {
@@ -294,6 +302,8 @@ export const registerIdentityAzureAuthRouter = async (server: FastifyZodProvider
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.AzureAuth],
description: "Delete Azure Auth configuration on identity", description: "Delete Azure Auth configuration on identity",
security: [ security: [
{ {
@@ -2,7 +2,7 @@ import { z } from "zod";
import { IdentityGcpAuthsSchema } from "@app/db/schemas"; import { IdentityGcpAuthsSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { GCP_AUTH } from "@app/lib/api-docs"; import { ApiDocsTags, GCP_AUTH } from "@app/lib/api-docs";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type"; import { AuthMode } from "@app/services/auth/auth-type";
@@ -18,9 +18,11 @@ export const registerIdentityGcpAuthRouter = async (server: FastifyZodProvider)
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.GcpAuth],
description: "Login with GCP Auth", description: "Login with GCP Auth",
body: z.object({ body: z.object({
identityId: z.string().trim().describe(GCP_AUTH.LOGIN.identityId).trim(), identityId: z.string().trim().describe(GCP_AUTH.LOGIN.identityId),
jwt: z.string() jwt: z.string()
}), }),
response: { response: {
@@ -66,6 +68,8 @@ export const registerIdentityGcpAuthRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.GcpAuth],
description: "Attach GCP Auth configuration onto identity", description: "Attach GCP Auth configuration onto identity",
security: [ security: [
{ {
@@ -157,6 +161,8 @@ export const registerIdentityGcpAuthRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.GcpAuth],
description: "Update GCP Auth configuration on identity", description: "Update GCP Auth configuration on identity",
security: [ security: [
{ {
@@ -241,6 +247,8 @@ export const registerIdentityGcpAuthRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.GcpAuth],
description: "Retrieve GCP Auth configuration on identity", description: "Retrieve GCP Auth configuration on identity",
security: [ security: [
{ {
@@ -288,6 +296,8 @@ export const registerIdentityGcpAuthRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.GcpAuth],
description: "Delete GCP Auth configuration on identity", description: "Delete GCP Auth configuration on identity",
security: [ security: [
{ {
@@ -2,7 +2,7 @@ import { z } from "zod";
import { IdentityJwtAuthsSchema } from "@app/db/schemas"; import { IdentityJwtAuthsSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { JWT_AUTH } from "@app/lib/api-docs"; import { ApiDocsTags, JWT_AUTH } from "@app/lib/api-docs";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type"; import { AuthMode } from "@app/services/auth/auth-type";
@@ -94,6 +94,8 @@ export const registerIdentityJwtAuthRouter = async (server: FastifyZodProvider)
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.JwtAuth],
description: "Login with JWT Auth", description: "Login with JWT Auth",
body: z.object({ body: z.object({
identityId: z.string().trim().describe(JWT_AUTH.LOGIN.identityId), identityId: z.string().trim().describe(JWT_AUTH.LOGIN.identityId),
@@ -144,6 +146,8 @@ export const registerIdentityJwtAuthRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.JwtAuth],
description: "Attach JWT Auth configuration onto identity", description: "Attach JWT Auth configuration onto identity",
security: [ security: [
{ {
@@ -211,6 +215,8 @@ export const registerIdentityJwtAuthRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.JwtAuth],
description: "Update JWT Auth configuration on identity", description: "Update JWT Auth configuration on identity",
security: [ security: [
{ {
@@ -275,6 +281,8 @@ export const registerIdentityJwtAuthRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.JwtAuth],
description: "Retrieve JWT Auth configuration on identity", description: "Retrieve JWT Auth configuration on identity",
security: [ security: [
{ {
@@ -322,6 +330,8 @@ export const registerIdentityJwtAuthRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.JwtAuth],
description: "Delete JWT Auth configuration on identity", description: "Delete JWT Auth configuration on identity",
security: [ security: [
{ {
@@ -2,7 +2,7 @@ import { z } from "zod";
import { IdentityKubernetesAuthsSchema } from "@app/db/schemas"; import { IdentityKubernetesAuthsSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { KUBERNETES_AUTH } from "@app/lib/api-docs"; import { ApiDocsTags, KUBERNETES_AUTH } from "@app/lib/api-docs";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type"; import { AuthMode } from "@app/services/auth/auth-type";
@@ -35,6 +35,8 @@ export const registerIdentityKubernetesRouter = async (server: FastifyZodProvide
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.KubernetesAuth],
description: "Login with Kubernetes Auth", description: "Login with Kubernetes Auth",
body: z.object({ body: z.object({
identityId: z.string().trim().describe(KUBERNETES_AUTH.LOGIN.identityId), identityId: z.string().trim().describe(KUBERNETES_AUTH.LOGIN.identityId),
@@ -85,6 +87,8 @@ export const registerIdentityKubernetesRouter = async (server: FastifyZodProvide
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.KubernetesAuth],
description: "Attach Kubernetes Auth configuration onto identity", description: "Attach Kubernetes Auth configuration onto identity",
security: [ security: [
{ {
@@ -182,6 +186,8 @@ export const registerIdentityKubernetesRouter = async (server: FastifyZodProvide
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.KubernetesAuth],
description: "Update Kubernetes Auth configuration on identity", description: "Update Kubernetes Auth configuration on identity",
security: [ security: [
{ {
@@ -278,6 +284,8 @@ export const registerIdentityKubernetesRouter = async (server: FastifyZodProvide
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.KubernetesAuth],
description: "Retrieve Kubernetes Auth configuration on identity", description: "Retrieve Kubernetes Auth configuration on identity",
security: [ security: [
{ {
@@ -325,6 +333,8 @@ export const registerIdentityKubernetesRouter = async (server: FastifyZodProvide
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.KubernetesAuth],
description: "Delete Kubernetes Auth configuration on identity", description: "Delete Kubernetes Auth configuration on identity",
security: [ security: [
{ {
@@ -2,7 +2,7 @@ import { z } from "zod";
import { IdentityOidcAuthsSchema } from "@app/db/schemas"; import { IdentityOidcAuthsSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { OIDC_AUTH } from "@app/lib/api-docs"; import { ApiDocsTags, OIDC_AUTH } from "@app/lib/api-docs";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type"; import { AuthMode } from "@app/services/auth/auth-type";
@@ -42,6 +42,8 @@ export const registerIdentityOidcAuthRouter = async (server: FastifyZodProvider)
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.OidcAuth],
description: "Login with OIDC Auth", description: "Login with OIDC Auth",
body: z.object({ body: z.object({
identityId: z.string().trim().describe(OIDC_AUTH.LOGIN.identityId), identityId: z.string().trim().describe(OIDC_AUTH.LOGIN.identityId),
@@ -96,6 +98,8 @@ export const registerIdentityOidcAuthRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.OidcAuth],
description: "Attach OIDC Auth configuration onto identity", description: "Attach OIDC Auth configuration onto identity",
security: [ security: [
{ {
@@ -195,6 +199,8 @@ export const registerIdentityOidcAuthRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.OidcAuth],
description: "Update OIDC Auth configuration on identity", description: "Update OIDC Auth configuration on identity",
security: [ security: [
{ {
@@ -292,6 +298,8 @@ export const registerIdentityOidcAuthRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.OidcAuth],
description: "Retrieve OIDC Auth configuration on identity", description: "Retrieve OIDC Auth configuration on identity",
security: [ security: [
{ {
@@ -339,6 +347,8 @@ export const registerIdentityOidcAuthRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.OidcAuth],
description: "Delete OIDC Auth configuration on identity", description: "Delete OIDC Auth configuration on identity",
security: [ security: [
{ {
@@ -2,7 +2,7 @@ import { z } from "zod";
import { IdentitiesSchema, IdentityOrgMembershipsSchema, OrgMembershipRole, OrgRolesSchema } from "@app/db/schemas"; import { IdentitiesSchema, IdentityOrgMembershipsSchema, OrgMembershipRole, OrgRolesSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { IDENTITIES } from "@app/lib/api-docs"; import { ApiDocsTags, IDENTITIES } from "@app/lib/api-docs";
import { buildSearchZodSchema, SearchResourceOperators } from "@app/lib/search-resource/search"; import { buildSearchZodSchema, SearchResourceOperators } from "@app/lib/search-resource/search";
import { OrderByDirection } from "@app/lib/types"; import { OrderByDirection } from "@app/lib/types";
import { CharacterType, zodValidateCharacters } from "@app/lib/validator/validate-string"; import { CharacterType, zodValidateCharacters } from "@app/lib/validator/validate-string";
@@ -32,6 +32,8 @@ export const registerIdentityRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Identities],
description: "Create identity", description: "Create identity",
security: [ security: [
{ {
@@ -100,6 +102,8 @@ export const registerIdentityRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Identities],
description: "Update identity", description: "Update identity",
security: [ security: [
{ {
@@ -158,6 +162,8 @@ export const registerIdentityRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Identities],
description: "Delete identity", description: "Delete identity",
security: [ security: [
{ {
@@ -205,6 +211,8 @@ export const registerIdentityRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Identities],
description: "Get an identity by id", description: "Get an identity by id",
security: [ security: [
{ {
@@ -260,6 +268,8 @@ export const registerIdentityRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Identities],
description: "List identities", description: "List identities",
security: [ security: [
{ {
@@ -308,6 +318,8 @@ export const registerIdentityRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Identities],
description: "Search identities", description: "Search identities",
security: [ security: [
{ {
@@ -2,7 +2,7 @@ import { z } from "zod";
import { IdentityAccessTokensSchema, IdentityTokenAuthsSchema } from "@app/db/schemas"; import { IdentityAccessTokensSchema, IdentityTokenAuthsSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { TOKEN_AUTH } from "@app/lib/api-docs"; import { ApiDocsTags, TOKEN_AUTH } from "@app/lib/api-docs";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type"; import { AuthMode } from "@app/services/auth/auth-type";
@@ -18,6 +18,8 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.TokenAuth],
description: "Attach Token Auth configuration onto identity", description: "Attach Token Auth configuration onto identity",
security: [ security: [
{ {
@@ -108,6 +110,8 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.TokenAuth],
description: "Update Token Auth configuration on identity", description: "Update Token Auth configuration on identity",
security: [ security: [
{ {
@@ -192,6 +196,8 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.TokenAuth],
description: "Retrieve Token Auth configuration on identity", description: "Retrieve Token Auth configuration on identity",
security: [ security: [
{ {
@@ -239,6 +245,8 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.TokenAuth],
description: "Delete Token Auth configuration on identity", description: "Delete Token Auth configuration on identity",
security: [ security: [
{ {
@@ -287,6 +295,8 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.TokenAuth],
description: "Create token for identity with Token Auth", description: "Create token for identity with Token Auth",
security: [ security: [
{ {
@@ -349,6 +359,8 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.TokenAuth],
description: "Get tokens for identity with Token Auth", description: "Get tokens for identity with Token Auth",
security: [ security: [
{ {
@@ -402,6 +414,8 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.TokenAuth],
description: "Update token for identity with Token Auth", description: "Update token for identity with Token Auth",
security: [ security: [
{ {
@@ -456,6 +470,8 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.TokenAuth],
description: "Revoke token for identity with Token Auth", description: "Revoke token for identity with Token Auth",
security: [ security: [
{ {
@@ -2,7 +2,7 @@ import { z } from "zod";
import { IdentityUaClientSecretsSchema, IdentityUniversalAuthsSchema } from "@app/db/schemas"; import { IdentityUaClientSecretsSchema, IdentityUniversalAuthsSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { UNIVERSAL_AUTH } from "@app/lib/api-docs"; import { ApiDocsTags, UNIVERSAL_AUTH } from "@app/lib/api-docs";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type"; import { AuthMode } from "@app/services/auth/auth-type";
@@ -30,6 +30,8 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.UniversalAuth],
description: "Login with Universal Auth", description: "Login with Universal Auth",
body: z.object({ body: z.object({
clientId: z.string().trim().describe(UNIVERSAL_AUTH.LOGIN.clientId), clientId: z.string().trim().describe(UNIVERSAL_AUTH.LOGIN.clientId),
@@ -78,6 +80,8 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.UniversalAuth],
description: "Attach Universal Auth configuration onto identity", description: "Attach Universal Auth configuration onto identity",
security: [ security: [
{ {
@@ -175,6 +179,8 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.UniversalAuth],
description: "Update Universal Auth configuration on identity", description: "Update Universal Auth configuration on identity",
security: [ security: [
{ {
@@ -271,6 +277,8 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.UniversalAuth],
description: "Retrieve Universal Auth configuration on identity", description: "Retrieve Universal Auth configuration on identity",
security: [ security: [
{ {
@@ -318,6 +326,8 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.UniversalAuth],
description: "Delete Universal Auth configuration on identity", description: "Delete Universal Auth configuration on identity",
security: [ security: [
{ {
@@ -365,6 +375,8 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.UniversalAuth],
description: "Create Universal Auth Client Secret for identity", description: "Create Universal Auth Client Secret for identity",
security: [ security: [
{ {
@@ -421,6 +433,8 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.UniversalAuth],
description: "List Universal Auth Client Secrets for identity", description: "List Universal Auth Client Secrets for identity",
security: [ security: [
{ {
@@ -469,6 +483,8 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.UniversalAuth],
description: "Get Universal Auth Client Secret for identity", description: "Get Universal Auth Client Secret for identity",
security: [ security: [
{ {
@@ -519,6 +535,8 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.UniversalAuth],
description: "Revoke Universal Auth Client Secrets for identity", description: "Revoke Universal Auth Client Secrets for identity",
security: [ security: [
{ {
@@ -1,7 +1,7 @@
import { z } from "zod"; import { z } from "zod";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { INTEGRATION_AUTH } from "@app/lib/api-docs"; import { ApiDocsTags, INTEGRATION_AUTH } from "@app/lib/api-docs";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type"; import { AuthMode } from "@app/services/auth/auth-type";
@@ -19,6 +19,8 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Integrations],
description: "List of integrations available.", description: "List of integrations available.",
security: [ security: [
{ {
@@ -57,6 +59,8 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Integrations],
description: "Get details of an integration authorization by auth object id.", description: "Get details of an integration authorization by auth object id.",
security: [ security: [
{ {
@@ -92,6 +96,8 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Integrations],
description: "Update the integration authentication object required for syncing secrets.", description: "Update the integration authentication object required for syncing secrets.",
security: [ security: [
{ {
@@ -153,6 +159,8 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Integrations],
description: "Remove all integration's auth object from the project.", description: "Remove all integration's auth object from the project.",
security: [ security: [
{ {
@@ -202,6 +210,8 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Integrations],
description: "Remove an integration auth object by object id.", description: "Remove an integration auth object by object id.",
security: [ security: [
{ {
@@ -294,6 +304,8 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Integrations],
description: "Create the integration authentication object required for syncing secrets.", description: "Create the integration authentication object required for syncing secrets.",
security: [ security: [
{ {
@@ -2,7 +2,7 @@ import { z } from "zod";
import { IntegrationsSchema } from "@app/db/schemas"; import { IntegrationsSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { INTEGRATION } from "@app/lib/api-docs"; import { ApiDocsTags, INTEGRATION } from "@app/lib/api-docs";
import { removeTrailingSlash, shake } from "@app/lib/fn"; import { removeTrailingSlash, shake } from "@app/lib/fn";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { getTelemetryDistinctId } from "@app/server/lib/telemetry"; import { getTelemetryDistinctId } from "@app/server/lib/telemetry";
@@ -22,6 +22,8 @@ export const registerIntegrationRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Integrations],
description: "Create an integration to sync secrets.", description: "Create an integration to sync secrets.",
security: [ security: [
{ {
@@ -119,6 +121,8 @@ export const registerIntegrationRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Integrations],
description: "Update an integration by integration id", description: "Update an integration by integration id",
security: [ security: [
{ {
@@ -178,6 +182,8 @@ export const registerIntegrationRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Integrations],
description: "Get an integration by integration id", description: "Get an integration by integration id",
security: [ security: [
{ {
@@ -247,6 +253,8 @@ export const registerIntegrationRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Integrations],
description: "Remove an integration using the integration object ID", description: "Remove an integration using the integration object ID",
security: [ security: [
{ {
@@ -315,6 +323,8 @@ export const registerIntegrationRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Integrations],
description: "Manually trigger sync of an integration by integration id", description: "Manually trigger sync of an integration by integration id",
security: [ security: [
{ {
@@ -9,7 +9,7 @@ import {
UsersSchema UsersSchema
} from "@app/db/schemas"; } from "@app/db/schemas";
import { EventType, UserAgentType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType, UserAgentType } from "@app/ee/services/audit-log/audit-log-types";
import { AUDIT_LOGS, ORGANIZATIONS } from "@app/lib/api-docs"; import { ApiDocsTags, AUDIT_LOGS, ORGANIZATIONS } from "@app/lib/api-docs";
import { getLastMidnightDateISO, removeTrailingSlash } from "@app/lib/fn"; import { getLastMidnightDateISO, removeTrailingSlash } from "@app/lib/fn";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { GenericResourceNameSchema, slugSchema } from "@app/server/lib/schemas"; import { GenericResourceNameSchema, slugSchema } from "@app/server/lib/schemas";
@@ -109,6 +109,8 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.AuditLogs],
description: "Get all audit logs for an organization", description: "Get all audit logs for an organization",
querystring: z.object({ querystring: z.object({
projectId: z.string().optional().describe(AUDIT_LOGS.EXPORT.projectId), projectId: z.string().optional().describe(AUDIT_LOGS.EXPORT.projectId),
@@ -2,7 +2,7 @@ import { z } from "zod";
import { PkiAlertsSchema } from "@app/db/schemas"; import { PkiAlertsSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { ALERTS } from "@app/lib/api-docs"; import { ALERTS, ApiDocsTags } from "@app/lib/api-docs";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type"; import { AuthMode } from "@app/services/auth/auth-type";
@@ -16,6 +16,8 @@ export const registerPkiAlertRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiAlerting],
description: "Create PKI alert", description: "Create PKI alert",
body: z.object({ body: z.object({
projectId: z.string().trim().describe(ALERTS.CREATE.projectId), projectId: z.string().trim().describe(ALERTS.CREATE.projectId),
@@ -68,6 +70,8 @@ export const registerPkiAlertRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiAlerting],
description: "Get PKI alert", description: "Get PKI alert",
params: z.object({ params: z.object({
alertId: z.string().trim().describe(ALERTS.GET.alertId) alertId: z.string().trim().describe(ALERTS.GET.alertId)
@@ -108,6 +112,8 @@ export const registerPkiAlertRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiAlerting],
description: "Update PKI alert", description: "Update PKI alert",
params: z.object({ params: z.object({
alertId: z.string().trim().describe(ALERTS.UPDATE.alertId) alertId: z.string().trim().describe(ALERTS.UPDATE.alertId)
@@ -164,6 +170,8 @@ export const registerPkiAlertRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiAlerting],
description: "Delete PKI alert", description: "Delete PKI alert",
params: z.object({ params: z.object({
alertId: z.string().trim().describe(ALERTS.DELETE.alertId) alertId: z.string().trim().describe(ALERTS.DELETE.alertId)
@@ -2,7 +2,7 @@ import { z } from "zod";
import { PkiCollectionItemsSchema, PkiCollectionsSchema } from "@app/db/schemas"; import { PkiCollectionItemsSchema, PkiCollectionsSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { PKI_COLLECTIONS } from "@app/lib/api-docs"; import { ApiDocsTags, PKI_COLLECTIONS } from "@app/lib/api-docs";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type"; import { AuthMode } from "@app/services/auth/auth-type";
@@ -17,6 +17,8 @@ export const registerPkiCollectionRouter = async (server: FastifyZodProvider) =>
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateCollections],
description: "Create PKI collection", description: "Create PKI collection",
body: z.object({ body: z.object({
projectId: z.string().trim().describe(PKI_COLLECTIONS.CREATE.projectId), projectId: z.string().trim().describe(PKI_COLLECTIONS.CREATE.projectId),
@@ -60,6 +62,8 @@ export const registerPkiCollectionRouter = async (server: FastifyZodProvider) =>
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateCollections],
description: "Get PKI collection", description: "Get PKI collection",
params: z.object({ params: z.object({
collectionId: z.string().trim().describe(PKI_COLLECTIONS.GET.collectionId) collectionId: z.string().trim().describe(PKI_COLLECTIONS.GET.collectionId)
@@ -100,6 +104,8 @@ export const registerPkiCollectionRouter = async (server: FastifyZodProvider) =>
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateCollections],
description: "Update PKI collection", description: "Update PKI collection",
params: z.object({ params: z.object({
collectionId: z.string().trim().describe(PKI_COLLECTIONS.UPDATE.collectionId) collectionId: z.string().trim().describe(PKI_COLLECTIONS.UPDATE.collectionId)
@@ -146,6 +152,8 @@ export const registerPkiCollectionRouter = async (server: FastifyZodProvider) =>
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateCollections],
description: "Delete PKI collection", description: "Delete PKI collection",
params: z.object({ params: z.object({
collectionId: z.string().trim().describe(PKI_COLLECTIONS.DELETE.collectionId) collectionId: z.string().trim().describe(PKI_COLLECTIONS.DELETE.collectionId)
@@ -186,6 +194,8 @@ export const registerPkiCollectionRouter = async (server: FastifyZodProvider) =>
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateCollections],
description: "Get items in PKI collection", description: "Get items in PKI collection",
params: z.object({ params: z.object({
collectionId: z.string().trim().describe(PKI_COLLECTIONS.LIST_ITEMS.collectionId) collectionId: z.string().trim().describe(PKI_COLLECTIONS.LIST_ITEMS.collectionId)
@@ -247,6 +257,8 @@ export const registerPkiCollectionRouter = async (server: FastifyZodProvider) =>
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateCollections],
description: "Add item to PKI collection", description: "Add item to PKI collection",
params: z.object({ params: z.object({
collectionId: z.string().trim().describe(PKI_COLLECTIONS.ADD_ITEM.collectionId) collectionId: z.string().trim().describe(PKI_COLLECTIONS.ADD_ITEM.collectionId)
@@ -298,6 +310,8 @@ export const registerPkiCollectionRouter = async (server: FastifyZodProvider) =>
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateCollections],
description: "Remove item from PKI collection", description: "Remove item from PKI collection",
params: z.object({ params: z.object({
collectionId: z.string().trim().describe(PKI_COLLECTIONS.DELETE_ITEM.collectionId), collectionId: z.string().trim().describe(PKI_COLLECTIONS.DELETE_ITEM.collectionId),
@@ -2,7 +2,7 @@ import { z } from "zod";
import { ProjectEnvironmentsSchema } from "@app/db/schemas"; import { ProjectEnvironmentsSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { ENVIRONMENTS } from "@app/lib/api-docs"; import { ApiDocsTags, ENVIRONMENTS } from "@app/lib/api-docs";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { slugSchema } from "@app/server/lib/schemas"; import { slugSchema } from "@app/server/lib/schemas";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
@@ -13,9 +13,11 @@ export const registerProjectEnvRouter = async (server: FastifyZodProvider) => {
method: "GET", method: "GET",
url: "/:workspaceId/environments/:envId", url: "/:workspaceId/environments/:envId",
config: { config: {
rateLimit: writeLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Environments],
description: "Get Environment", description: "Get Environment",
security: [ security: [
{ {
@@ -65,6 +67,8 @@ export const registerProjectEnvRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Environments],
description: "Get Environment by ID", description: "Get Environment by ID",
security: [ security: [
{ {
@@ -112,6 +116,8 @@ export const registerProjectEnvRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Environments],
description: "Create environment", description: "Create environment",
security: [ security: [
{ {
@@ -171,6 +177,8 @@ export const registerProjectEnvRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Environments],
description: "Update environment", description: "Update environment",
security: [ security: [
{ {
@@ -237,6 +245,8 @@ export const registerProjectEnvRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Environments],
description: "Delete environment", description: "Delete environment",
security: [ security: [
{ {
@@ -8,7 +8,7 @@ import {
UsersSchema UsersSchema
} from "@app/db/schemas"; } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { PROJECT_USERS } from "@app/lib/api-docs"; import { ApiDocsTags, PROJECT_USERS } from "@app/lib/api-docs";
import { ms } from "@app/lib/ms"; import { ms } from "@app/lib/ms";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
@@ -23,6 +23,8 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ProjectUsers],
description: "Return project user memberships", description: "Return project user memberships",
security: [ security: [
{ {
@@ -141,6 +143,8 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ProjectUsers],
description: "Return project user memberships", description: "Return project user memberships",
security: [ security: [
{ {
@@ -255,6 +259,8 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ProjectUsers],
description: "Update project user membership", description: "Update project user membership",
security: [ security: [
{ {
+16 -5
View File
@@ -14,8 +14,9 @@ import {
UsersSchema UsersSchema
} from "@app/db/schemas"; } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { PROJECTS } from "@app/lib/api-docs"; import { ApiDocsTags, PROJECTS } from "@app/lib/api-docs";
import { CharacterType, characterValidator } from "@app/lib/validator/validate-string"; import { CharacterType, characterValidator } from "@app/lib/validator/validate-string";
import { re2Validator } from "@app/lib/zod";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { ActorType, AuthMode } from "@app/services/auth/auth-type"; import { ActorType, AuthMode } from "@app/services/auth/auth-type";
@@ -177,6 +178,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Projects],
description: "Get project", description: "Get project",
security: [ security: [
{ {
@@ -215,6 +218,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Projects],
description: "Delete project", description: "Delete project",
security: [ security: [
{ {
@@ -290,6 +295,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Projects],
description: "Update project", description: "Update project",
security: [ security: [
{ {
@@ -317,11 +324,11 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
slug: z slug: z
.string() .string()
.trim() .trim()
.regex(
/^[a-z0-9]+(?:[_-][a-z0-9]+)*$/,
"Project slug can only contain lowercase letters and numbers, with optional single hyphens (-) or underscores (_) between words. Cannot start or end with a hyphen or underscore."
)
.max(64, { message: "Slug must be 64 characters or fewer" }) .max(64, { message: "Slug must be 64 characters or fewer" })
.refine(re2Validator(/^[a-z0-9]+(?:[_-][a-z0-9]+)*$/), {
message:
"Project slug can only contain lowercase letters and numbers, with optional single hyphens (-) or underscores (_) between words. Cannot start or end with a hyphen or underscore."
})
.optional() .optional()
.describe(PROJECTS.UPDATE.slug) .describe(PROJECTS.UPDATE.slug)
}), }),
@@ -513,6 +520,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Integrations],
description: "List integrations for a project.", description: "List integrations for a project.",
security: [ security: [
{ {
@@ -556,6 +565,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Integrations],
description: "List integration auth objects for a workspace.", description: "List integration auth objects for a workspace.",
security: [ security: [
{ {
@@ -2,7 +2,7 @@ import { z } from "zod";
import { SecretFoldersSchema } from "@app/db/schemas"; import { SecretFoldersSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { FOLDERS } from "@app/lib/api-docs"; import { ApiDocsTags, FOLDERS } from "@app/lib/api-docs";
import { prefixWithSlash, removeTrailingSlash } from "@app/lib/fn"; import { prefixWithSlash, removeTrailingSlash } from "@app/lib/fn";
import { isValidFolderName } from "@app/lib/validator"; import { isValidFolderName } from "@app/lib/validator";
import { readLimit, secretsLimit } from "@app/server/config/rateLimiter"; import { readLimit, secretsLimit } from "@app/server/config/rateLimiter";
@@ -19,6 +19,8 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
rateLimit: secretsLimit rateLimit: secretsLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Folders],
description: "Create folders", description: "Create folders",
security: [ security: [
{ {
@@ -98,6 +100,8 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
rateLimit: secretsLimit rateLimit: secretsLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Folders],
description: "Update folder", description: "Update folder",
security: [ security: [
{ {
@@ -181,6 +185,8 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
rateLimit: secretsLimit rateLimit: secretsLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Folders],
description: "Update folders by batch", description: "Update folders by batch",
security: [ security: [
{ {
@@ -259,6 +265,8 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
rateLimit: secretsLimit rateLimit: secretsLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Folders],
description: "Delete a folder", description: "Delete a folder",
security: [ security: [
{ {
@@ -332,6 +340,8 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Folders],
description: "Get folders", description: "Get folders",
security: [ security: [
{ {
@@ -390,6 +400,8 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Folders],
description: "Get folder by id", description: "Get folder by id",
security: [ security: [
{ {
@@ -2,7 +2,7 @@ import { z } from "zod";
import { SecretImportsSchema, SecretsSchema } from "@app/db/schemas"; import { SecretImportsSchema, SecretsSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { SECRET_IMPORTS } from "@app/lib/api-docs"; import { ApiDocsTags, SECRET_IMPORTS } from "@app/lib/api-docs";
import { removeTrailingSlash } from "@app/lib/fn"; import { removeTrailingSlash } from "@app/lib/fn";
import { readLimit, secretsLimit } from "@app/server/config/rateLimiter"; import { readLimit, secretsLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
@@ -18,6 +18,8 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
rateLimit: secretsLimit rateLimit: secretsLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretImports],
description: "Create secret imports", description: "Create secret imports",
security: [ security: [
{ {
@@ -83,6 +85,8 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
rateLimit: secretsLimit rateLimit: secretsLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretImports],
description: "Update secret imports", description: "Update secret imports",
security: [ security: [
{ {
@@ -157,6 +161,8 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
rateLimit: secretsLimit rateLimit: secretsLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretImports],
description: "Delete secret imports", description: "Delete secret imports",
security: [ security: [
{ {
@@ -263,6 +269,8 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretImports],
description: "Get secret imports", description: "Get secret imports",
security: [ security: [
{ {
@@ -319,6 +327,8 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretImports],
description: "Get single secret import", description: "Get single secret import",
security: [ security: [
{ {
@@ -421,6 +431,8 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
rateLimit: secretsLimit rateLimit: secretsLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretImports],
querystring: z.object({ querystring: z.object({
workspaceId: z.string().trim(), workspaceId: z.string().trim(),
environment: z.string().trim(), environment: z.string().trim(),
@@ -11,6 +11,7 @@ import { registerGitHubSyncRouter } from "./github-sync-router";
import { registerHumanitecSyncRouter } from "./humanitec-sync-router"; import { registerHumanitecSyncRouter } from "./humanitec-sync-router";
import { registerTerraformCloudSyncRouter } from "./terraform-cloud-sync-router"; import { registerTerraformCloudSyncRouter } from "./terraform-cloud-sync-router";
import { registerVercelSyncRouter } from "./vercel-sync-router"; import { registerVercelSyncRouter } from "./vercel-sync-router";
import { registerWindmillSyncRouter } from "./windmill-sync-router";
export * from "./secret-sync-router"; export * from "./secret-sync-router";
@@ -25,5 +26,6 @@ export const SECRET_SYNC_REGISTER_ROUTER_MAP: Record<SecretSync, (server: Fastif
[SecretSync.Humanitec]: registerHumanitecSyncRouter, [SecretSync.Humanitec]: registerHumanitecSyncRouter,
[SecretSync.TerraformCloud]: registerTerraformCloudSyncRouter, [SecretSync.TerraformCloud]: registerTerraformCloudSyncRouter,
[SecretSync.Camunda]: registerCamundaSyncRouter, [SecretSync.Camunda]: registerCamundaSyncRouter,
[SecretSync.Vercel]: registerVercelSyncRouter [SecretSync.Vercel]: registerVercelSyncRouter,
[SecretSync.Windmill]: registerWindmillSyncRouter
}; };
@@ -1,7 +1,7 @@
import { z } from "zod"; import { z } from "zod";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { SecretSyncs } from "@app/lib/api-docs"; import { ApiDocsTags, SecretSyncs } from "@app/lib/api-docs";
import { startsWithVowel } from "@app/lib/fn"; import { startsWithVowel } from "@app/lib/fn";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
@@ -51,6 +51,8 @@ export const registerSyncSecretsEndpoints = <T extends TSecretSync, I extends TS
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretSyncs],
description: `List the ${destinationName} Syncs for the specified project.`, description: `List the ${destinationName} Syncs for the specified project.`,
querystring: z.object({ querystring: z.object({
projectId: z.string().trim().min(1, "Project ID required").describe(SecretSyncs.LIST(destination).projectId) projectId: z.string().trim().min(1, "Project ID required").describe(SecretSyncs.LIST(destination).projectId)
@@ -94,6 +96,8 @@ export const registerSyncSecretsEndpoints = <T extends TSecretSync, I extends TS
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretSyncs],
description: `Get the specified ${destinationName} Sync by ID.`, description: `Get the specified ${destinationName} Sync by ID.`,
params: z.object({ params: z.object({
syncId: z.string().uuid().describe(SecretSyncs.GET_BY_ID(destination).syncId) syncId: z.string().uuid().describe(SecretSyncs.GET_BY_ID(destination).syncId)
@@ -134,6 +138,8 @@ export const registerSyncSecretsEndpoints = <T extends TSecretSync, I extends TS
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretSyncs],
description: `Get the specified ${destinationName} Sync by name and project ID.`, description: `Get the specified ${destinationName} Sync by name and project ID.`,
params: z.object({ params: z.object({
syncName: z.string().trim().min(1, "Sync name required").describe(SecretSyncs.GET_BY_NAME(destination).syncName) syncName: z.string().trim().min(1, "Sync name required").describe(SecretSyncs.GET_BY_NAME(destination).syncName)
@@ -182,6 +188,8 @@ export const registerSyncSecretsEndpoints = <T extends TSecretSync, I extends TS
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretSyncs],
description: `Create ${ description: `Create ${
startsWithVowel(destinationName) ? "an" : "a" startsWithVowel(destinationName) ? "an" : "a"
} ${destinationName} Sync for the specified project environment.`, } ${destinationName} Sync for the specified project environment.`,
@@ -221,6 +229,8 @@ export const registerSyncSecretsEndpoints = <T extends TSecretSync, I extends TS
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretSyncs],
description: `Update the specified ${destinationName} Sync.`, description: `Update the specified ${destinationName} Sync.`,
params: z.object({ params: z.object({
syncId: z.string().uuid().describe(SecretSyncs.UPDATE(destination).syncId) syncId: z.string().uuid().describe(SecretSyncs.UPDATE(destination).syncId)
@@ -263,6 +273,8 @@ export const registerSyncSecretsEndpoints = <T extends TSecretSync, I extends TS
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretSyncs],
description: `Delete the specified ${destinationName} Sync.`, description: `Delete the specified ${destinationName} Sync.`,
params: z.object({ params: z.object({
syncId: z.string().uuid().describe(SecretSyncs.DELETE(destination).syncId) syncId: z.string().uuid().describe(SecretSyncs.DELETE(destination).syncId)
@@ -312,6 +324,8 @@ export const registerSyncSecretsEndpoints = <T extends TSecretSync, I extends TS
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretSyncs],
description: `Trigger a sync for the specified ${destinationName} Sync.`, description: `Trigger a sync for the specified ${destinationName} Sync.`,
params: z.object({ params: z.object({
syncId: z.string().uuid().describe(SecretSyncs.SYNC_SECRETS(destination).syncId) syncId: z.string().uuid().describe(SecretSyncs.SYNC_SECRETS(destination).syncId)
@@ -344,6 +358,8 @@ export const registerSyncSecretsEndpoints = <T extends TSecretSync, I extends TS
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretSyncs],
description: `Import secrets from the specified ${destinationName} Sync destination.`, description: `Import secrets from the specified ${destinationName} Sync destination.`,
params: z.object({ params: z.object({
syncId: z.string().uuid().describe(SecretSyncs.IMPORT_SECRETS(destination).syncId) syncId: z.string().uuid().describe(SecretSyncs.IMPORT_SECRETS(destination).syncId)
@@ -382,6 +398,8 @@ export const registerSyncSecretsEndpoints = <T extends TSecretSync, I extends TS
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretSyncs],
description: `Remove previously synced secrets from the specified ${destinationName} Sync destination.`, description: `Remove previously synced secrets from the specified ${destinationName} Sync destination.`,
params: z.object({ params: z.object({
syncId: z.string().uuid().describe(SecretSyncs.REMOVE_SECRETS(destination).syncId) syncId: z.string().uuid().describe(SecretSyncs.REMOVE_SECRETS(destination).syncId)
@@ -1,7 +1,7 @@
import { z } from "zod"; import { z } from "zod";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { SecretSyncs } from "@app/lib/api-docs"; import { ApiDocsTags, SecretSyncs } from "@app/lib/api-docs";
import { readLimit } from "@app/server/config/rateLimiter"; import { readLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type"; import { AuthMode } from "@app/services/auth/auth-type";
@@ -25,6 +25,7 @@ import { GitHubSyncListItemSchema, GitHubSyncSchema } from "@app/services/secret
import { HumanitecSyncListItemSchema, HumanitecSyncSchema } from "@app/services/secret-sync/humanitec"; import { HumanitecSyncListItemSchema, HumanitecSyncSchema } from "@app/services/secret-sync/humanitec";
import { TerraformCloudSyncListItemSchema, TerraformCloudSyncSchema } from "@app/services/secret-sync/terraform-cloud"; import { TerraformCloudSyncListItemSchema, TerraformCloudSyncSchema } from "@app/services/secret-sync/terraform-cloud";
import { VercelSyncListItemSchema, VercelSyncSchema } from "@app/services/secret-sync/vercel"; import { VercelSyncListItemSchema, VercelSyncSchema } from "@app/services/secret-sync/vercel";
import { WindmillSyncListItemSchema, WindmillSyncSchema } from "@app/services/secret-sync/windmill";
const SecretSyncSchema = z.discriminatedUnion("destination", [ const SecretSyncSchema = z.discriminatedUnion("destination", [
AwsParameterStoreSyncSchema, AwsParameterStoreSyncSchema,
@@ -37,7 +38,8 @@ const SecretSyncSchema = z.discriminatedUnion("destination", [
HumanitecSyncSchema, HumanitecSyncSchema,
TerraformCloudSyncSchema, TerraformCloudSyncSchema,
CamundaSyncSchema, CamundaSyncSchema,
VercelSyncSchema VercelSyncSchema,
WindmillSyncSchema
]); ]);
const SecretSyncOptionsSchema = z.discriminatedUnion("destination", [ const SecretSyncOptionsSchema = z.discriminatedUnion("destination", [
@@ -51,7 +53,8 @@ const SecretSyncOptionsSchema = z.discriminatedUnion("destination", [
HumanitecSyncListItemSchema, HumanitecSyncListItemSchema,
TerraformCloudSyncListItemSchema, TerraformCloudSyncListItemSchema,
CamundaSyncListItemSchema, CamundaSyncListItemSchema,
VercelSyncListItemSchema VercelSyncListItemSchema,
WindmillSyncListItemSchema
]); ]);
export const registerSecretSyncRouter = async (server: FastifyZodProvider) => { export const registerSecretSyncRouter = async (server: FastifyZodProvider) => {
@@ -62,6 +65,8 @@ export const registerSecretSyncRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretSyncs],
description: "List the available Secret Sync Options.", description: "List the available Secret Sync Options.",
response: { response: {
200: z.object({ 200: z.object({
@@ -83,6 +88,8 @@ export const registerSecretSyncRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SecretSyncs],
description: "List all the Secret Syncs for the specified project.", description: "List all the Secret Syncs for the specified project.",
querystring: z.object({ querystring: z.object({
projectId: z.string().trim().min(1, "Project ID required").describe(SecretSyncs.LIST().projectId) projectId: z.string().trim().min(1, "Project ID required").describe(SecretSyncs.LIST().projectId)
@@ -0,0 +1,17 @@
import { SecretSync } from "@app/services/secret-sync/secret-sync-enums";
import {
CreateWindmillSyncSchema,
UpdateWindmillSyncSchema,
WindmillSyncSchema
} from "@app/services/secret-sync/windmill";
import { registerSyncSecretsEndpoints } from "./secret-sync-endpoints";
export const registerWindmillSyncRouter = async (server: FastifyZodProvider) =>
registerSyncSecretsEndpoints({
destination: SecretSync.Windmill,
server,
responseSchema: WindmillSyncSchema,
createSchema: CreateWindmillSyncSchema,
updateSchema: UpdateWindmillSyncSchema
});
@@ -1,7 +1,7 @@
import { z } from "zod"; import { z } from "zod";
import { SecretTagsSchema } from "@app/db/schemas"; import { SecretTagsSchema } from "@app/db/schemas";
import { SECRET_TAGS } from "@app/lib/api-docs"; import { ApiDocsTags, SECRET_TAGS } from "@app/lib/api-docs";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { slugSchema } from "@app/server/lib/schemas"; import { slugSchema } from "@app/server/lib/schemas";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
@@ -15,6 +15,8 @@ export const registerSecretTagRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Folders],
params: z.object({ params: z.object({
projectId: z.string().trim().describe(SECRET_TAGS.LIST.projectId) projectId: z.string().trim().describe(SECRET_TAGS.LIST.projectId)
}), }),
@@ -44,6 +46,8 @@ export const registerSecretTagRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Folders],
params: z.object({ params: z.object({
projectId: z.string().trim().describe(SECRET_TAGS.GET_TAG_BY_ID.projectId), projectId: z.string().trim().describe(SECRET_TAGS.GET_TAG_BY_ID.projectId),
tagId: z.string().trim().describe(SECRET_TAGS.GET_TAG_BY_ID.tagId) tagId: z.string().trim().describe(SECRET_TAGS.GET_TAG_BY_ID.tagId)
@@ -75,6 +79,8 @@ export const registerSecretTagRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Folders],
params: z.object({ params: z.object({
projectId: z.string().trim().describe(SECRET_TAGS.GET_TAG_BY_SLUG.projectId), projectId: z.string().trim().describe(SECRET_TAGS.GET_TAG_BY_SLUG.projectId),
tagSlug: z.string().trim().describe(SECRET_TAGS.GET_TAG_BY_SLUG.tagSlug) tagSlug: z.string().trim().describe(SECRET_TAGS.GET_TAG_BY_SLUG.tagSlug)
@@ -107,6 +113,8 @@ export const registerSecretTagRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Folders],
params: z.object({ params: z.object({
projectId: z.string().trim().describe(SECRET_TAGS.CREATE.projectId) projectId: z.string().trim().describe(SECRET_TAGS.CREATE.projectId)
}), }),
@@ -141,6 +149,8 @@ export const registerSecretTagRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Folders],
params: z.object({ params: z.object({
projectId: z.string().trim().describe(SECRET_TAGS.UPDATE.projectId), projectId: z.string().trim().describe(SECRET_TAGS.UPDATE.projectId),
tagId: z.string().trim().describe(SECRET_TAGS.UPDATE.tagId) tagId: z.string().trim().describe(SECRET_TAGS.UPDATE.tagId)
@@ -176,6 +186,8 @@ export const registerSecretTagRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Folders],
params: z.object({ params: z.object({
projectId: z.string().trim().describe(SECRET_TAGS.DELETE.projectId), projectId: z.string().trim().describe(SECRET_TAGS.DELETE.projectId),
tagId: z.string().trim().describe(SECRET_TAGS.DELETE.tagId) tagId: z.string().trim().describe(SECRET_TAGS.DELETE.tagId)
@@ -6,7 +6,7 @@ import {
ProjectMembershipRole, ProjectMembershipRole,
ProjectUserMembershipRolesSchema ProjectUserMembershipRolesSchema
} from "@app/db/schemas"; } from "@app/db/schemas";
import { PROJECTS } from "@app/lib/api-docs"; import { ApiDocsTags, PROJECTS } from "@app/lib/api-docs";
import { ms } from "@app/lib/ms"; import { ms } from "@app/lib/ms";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
@@ -22,6 +22,8 @@ export const registerGroupProjectRouter = async (server: FastifyZodProvider) =>
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ProjectGroups],
description: "Add group to project", description: "Add group to project",
security: [ security: [
{ {
@@ -88,6 +90,8 @@ export const registerGroupProjectRouter = async (server: FastifyZodProvider) =>
url: "/:projectId/groups/:groupId", url: "/:projectId/groups/:groupId",
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ProjectGroups],
description: "Update group in project", description: "Update group in project",
security: [ security: [
{ {
@@ -147,6 +151,8 @@ export const registerGroupProjectRouter = async (server: FastifyZodProvider) =>
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ProjectGroups],
description: "Remove group from project", description: "Remove group from project",
security: [ security: [
{ {
@@ -185,6 +191,8 @@ export const registerGroupProjectRouter = async (server: FastifyZodProvider) =>
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ProjectGroups],
description: "Return list of groups in project", description: "Return list of groups in project",
security: [ security: [
{ {
@@ -243,6 +251,8 @@ export const registerGroupProjectRouter = async (server: FastifyZodProvider) =>
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ProjectGroups],
description: "Return project group", description: "Return project group",
security: [ security: [
{ {
@@ -1,7 +1,7 @@
import { z } from "zod"; import { z } from "zod";
import { IdentitiesSchema, IdentityOrgMembershipsSchema, OrgRolesSchema } from "@app/db/schemas"; import { IdentitiesSchema, IdentityOrgMembershipsSchema, OrgRolesSchema } from "@app/db/schemas";
import { ORGANIZATIONS } from "@app/lib/api-docs"; import { ApiDocsTags, ORGANIZATIONS } from "@app/lib/api-docs";
import { OrderByDirection } from "@app/lib/types"; import { OrderByDirection } from "@app/lib/types";
import { readLimit } from "@app/server/config/rateLimiter"; import { readLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
@@ -17,6 +17,8 @@ export const registerIdentityOrgRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Organizations],
description: "Return organization identity memberships", description: "Return organization identity memberships",
security: [ security: [
{ {
@@ -6,7 +6,7 @@ import {
ProjectMembershipRole, ProjectMembershipRole,
ProjectUserMembershipRolesSchema ProjectUserMembershipRolesSchema
} from "@app/db/schemas"; } from "@app/db/schemas";
import { ORGANIZATIONS, PROJECT_IDENTITIES } from "@app/lib/api-docs"; import { ApiDocsTags, ORGANIZATIONS, PROJECT_IDENTITIES } from "@app/lib/api-docs";
import { BadRequestError } from "@app/lib/errors"; import { BadRequestError } from "@app/lib/errors";
import { ms } from "@app/lib/ms"; import { ms } from "@app/lib/ms";
import { OrderByDirection } from "@app/lib/types"; import { OrderByDirection } from "@app/lib/types";
@@ -27,6 +27,8 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ProjectIdentities],
description: "Create project identity membership", description: "Create project identity membership",
security: [ security: [
{ {
@@ -101,6 +103,8 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ProjectIdentities],
description: "Update project identity memberships", description: "Update project identity memberships",
security: [ security: [
{ {
@@ -170,6 +174,8 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ProjectIdentities],
description: "Delete project identity memberships", description: "Delete project identity memberships",
security: [ security: [
{ {
@@ -207,6 +213,8 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ProjectIdentities],
description: "Return project identity memberships", description: "Return project identity memberships",
security: [ security: [
{ {
@@ -300,6 +308,8 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ProjectIdentities],
description: "Return project identity membership", description: "Return project identity membership",
security: [ security: [
{ {
@@ -360,6 +370,8 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider)
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ProjectIdentities],
params: z.object({ params: z.object({
identityMembershipId: z.string().trim() identityMembershipId: z.string().trim()
}), }),
@@ -8,7 +8,7 @@ import {
UserEncryptionKeysSchema, UserEncryptionKeysSchema,
UsersSchema UsersSchema
} from "@app/db/schemas"; } from "@app/db/schemas";
import { ORGANIZATIONS } from "@app/lib/api-docs"; import { ApiDocsTags, ORGANIZATIONS } from "@app/lib/api-docs";
import { getConfig } from "@app/lib/config/env"; import { getConfig } from "@app/lib/config/env";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { GenericResourceNameSchema } from "@app/server/lib/schemas"; import { GenericResourceNameSchema } from "@app/server/lib/schemas";
@@ -24,6 +24,8 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Organizations],
description: "Return organization user memberships", description: "Return organization user memberships",
security: [ security: [
{ {
@@ -72,6 +74,8 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Organizations],
description: "Return projects in organization that user is apart of", description: "Return projects in organization that user is apart of",
security: [ security: [
{ {
@@ -179,6 +183,8 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Organizations],
description: "Update organization user memberships", description: "Update organization user memberships",
security: [ security: [
{ {
@@ -229,6 +235,8 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Organizations],
description: "Delete organization user memberships", description: "Delete organization user memberships",
security: [ security: [
{ {
@@ -2,7 +2,7 @@ import { z } from "zod";
import { OrgMembershipRole, ProjectMembershipRole, ProjectMembershipsSchema } from "@app/db/schemas"; import { OrgMembershipRole, ProjectMembershipRole, ProjectMembershipsSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { PROJECT_USERS } from "@app/lib/api-docs"; import { ApiDocsTags, PROJECT_USERS } from "@app/lib/api-docs";
import { writeLimit } from "@app/server/config/rateLimiter"; import { writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type"; import { AuthMode } from "@app/services/auth/auth-type";
@@ -15,6 +15,8 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ProjectUsers],
description: "Invite members to project", description: "Invite members to project",
security: [ security: [
{ {
@@ -78,6 +80,8 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ProjectUsers],
description: "Remove members from project", description: "Remove members from project",
security: [ security: [
{ {
+15 -2
View File
@@ -14,7 +14,7 @@ import { sanitizedSshCa } from "@app/ee/services/ssh/ssh-certificate-authority-s
import { sanitizedSshCertificate } from "@app/ee/services/ssh-certificate/ssh-certificate-schema"; import { sanitizedSshCertificate } from "@app/ee/services/ssh-certificate/ssh-certificate-schema";
import { sanitizedSshCertificateTemplate } from "@app/ee/services/ssh-certificate-template/ssh-certificate-template-schema"; import { sanitizedSshCertificateTemplate } from "@app/ee/services/ssh-certificate-template/ssh-certificate-template-schema";
import { loginMappingSchema, sanitizedSshHost } from "@app/ee/services/ssh-host/ssh-host-schema"; import { loginMappingSchema, sanitizedSshHost } from "@app/ee/services/ssh-host/ssh-host-schema";
import { PROJECTS } from "@app/lib/api-docs"; import { ApiDocsTags, PROJECTS } from "@app/lib/api-docs";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { slugSchema } from "@app/server/lib/schemas"; import { slugSchema } from "@app/server/lib/schemas";
import { getTelemetryDistinctId } from "@app/server/lib/telemetry"; import { getTelemetryDistinctId } from "@app/server/lib/telemetry";
@@ -29,7 +29,8 @@ import { SanitizedProjectSchema } from "../sanitizedSchemas";
const projectWithEnv = SanitizedProjectSchema.extend({ const projectWithEnv = SanitizedProjectSchema.extend({
_id: z.string(), _id: z.string(),
environments: z.object({ name: z.string(), slug: z.string(), id: z.string() }).array() environments: z.object({ name: z.string(), slug: z.string(), id: z.string() }).array(),
kmsSecretManagerKeyId: z.string().nullable().optional()
}); });
export const registerProjectRouter = async (server: FastifyZodProvider) => { export const registerProjectRouter = async (server: FastifyZodProvider) => {
@@ -150,6 +151,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Projects],
description: "Create a new project", description: "Create a new project",
security: [ security: [
{ {
@@ -224,6 +227,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Projects],
description: "Delete project", description: "Delete project",
security: [ security: [
{ {
@@ -342,6 +347,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateAuthorities],
params: z.object({ params: z.object({
slug: slugSchema({ min: 5, max: 36 }).describe(PROJECTS.LIST_CAS.slug) slug: slugSchema({ min: 5, max: 36 }).describe(PROJECTS.LIST_CAS.slug)
}), }),
@@ -383,6 +390,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificates],
params: z.object({ params: z.object({
slug: slugSchema({ min: 5, max: 36 }).describe(PROJECTS.LIST_CERTIFICATES.slug) slug: slugSchema({ min: 5, max: 36 }).describe(PROJECTS.LIST_CERTIFICATES.slug)
}), }),
@@ -551,6 +560,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SshCertificateTemplates],
params: z.object({ params: z.object({
projectId: z.string().trim().describe(PROJECTS.LIST_SSH_CERTIFICATE_TEMPLATES.projectId) projectId: z.string().trim().describe(PROJECTS.LIST_SSH_CERTIFICATE_TEMPLATES.projectId)
}), }),
@@ -581,6 +592,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.SshCertificateAuthorities],
params: z.object({ params: z.object({
projectId: z.string().trim().describe(PROJECTS.LIST_SSH_CAS.projectId) projectId: z.string().trim().describe(PROJECTS.LIST_SSH_CAS.projectId)
}), }),
@@ -2,6 +2,7 @@ import { z } from "zod";
import { ServiceTokensSchema } from "@app/db/schemas"; import { ServiceTokensSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { ApiDocsTags } from "@app/lib/api-docs";
import { removeTrailingSlash } from "@app/lib/fn"; import { removeTrailingSlash } from "@app/lib/fn";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
@@ -25,6 +26,8 @@ export const registerServiceTokenRouter = async (server: FastifyZodProvider) =>
}, },
onRequest: verifyAuth([AuthMode.SERVICE_TOKEN]), onRequest: verifyAuth([AuthMode.SERVICE_TOKEN]),
schema: { schema: {
hide: false,
tags: [ApiDocsTags.ServiceTokens],
description: "Return Infisical Token data", description: "Return Infisical Token data",
security: [ security: [
{ {
@@ -252,6 +252,31 @@ export const registerUserRouter = async (server: FastifyZodProvider) => {
} }
}); });
server.route({
method: "DELETE",
url: "/me/sessions/:sessionId",
config: {
rateLimit: writeLimit
},
schema: {
params: z.object({
sessionId: z.string().trim()
}),
response: {
200: z.object({
message: z.string()
})
}
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => {
await server.services.authToken.revokeMySessionById(req.permission.id, req.params.sessionId);
return {
message: "Successfully revoked session"
};
}
});
server.route({ server.route({
method: "GET", method: "GET",
url: "/me", url: "/me",
+27 -1
View File
@@ -3,7 +3,7 @@ import { z } from "zod";
import { SecretApprovalRequestsSchema, SecretsSchema, SecretType, ServiceTokenScopes } from "@app/db/schemas"; import { SecretApprovalRequestsSchema, SecretsSchema, SecretType, ServiceTokenScopes } from "@app/db/schemas";
import { EventType, UserAgentType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType, UserAgentType } from "@app/ee/services/audit-log/audit-log-types";
import { RAW_SECRETS, SECRETS } from "@app/lib/api-docs"; import { ApiDocsTags, RAW_SECRETS, SECRETS } from "@app/lib/api-docs";
import { BadRequestError, NotFoundError } from "@app/lib/errors"; import { BadRequestError, NotFoundError } from "@app/lib/errors";
import { removeTrailingSlash } from "@app/lib/fn"; import { removeTrailingSlash } from "@app/lib/fn";
import { secretsLimit, writeLimit } from "@app/server/config/rateLimiter"; import { secretsLimit, writeLimit } from "@app/server/config/rateLimiter";
@@ -48,6 +48,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Secrets],
description: "Attach tags to a secret", description: "Attach tags to a secret",
security: [ security: [
{ {
@@ -103,6 +105,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Secrets],
description: "Detach tags from a secret", description: "Detach tags from a secret",
security: [ security: [
{ {
@@ -158,6 +162,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
rateLimit: secretsLimit rateLimit: secretsLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Secrets],
description: "List secrets", description: "List secrets",
security: [ security: [
{ {
@@ -355,6 +361,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
rateLimit: secretsLimit rateLimit: secretsLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Secrets],
params: z.object({ params: z.object({
secretId: z.string() secretId: z.string()
}), }),
@@ -390,6 +398,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
rateLimit: secretsLimit rateLimit: secretsLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Secrets],
description: "Get a secret by name", description: "Get a secret by name",
security: [ security: [
{ {
@@ -496,6 +506,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
rateLimit: secretsLimit rateLimit: secretsLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Secrets],
description: "Create secret", description: "Create secret",
security: [ security: [
{ {
@@ -609,6 +621,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
rateLimit: secretsLimit rateLimit: secretsLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Secrets],
description: "Update secret", description: "Update secret",
security: [ security: [
{ {
@@ -729,6 +743,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
rateLimit: secretsLimit rateLimit: secretsLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Secrets],
description: "Delete secret", description: "Delete secret",
security: [ security: [
{ {
@@ -1486,6 +1502,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
rateLimit: secretsLimit rateLimit: secretsLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Secrets],
body: z.object({ body: z.object({
projectSlug: z.string().trim(), projectSlug: z.string().trim(),
sourceEnvironment: z.string().trim(), sourceEnvironment: z.string().trim(),
@@ -1911,6 +1929,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
rateLimit: secretsLimit rateLimit: secretsLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Secrets],
description: "Create many secrets", description: "Create many secrets",
security: [ security: [
{ {
@@ -2017,6 +2037,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
rateLimit: secretsLimit rateLimit: secretsLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Secrets],
description: "Update many secrets", description: "Update many secrets",
security: [ security: [
{ {
@@ -2170,6 +2192,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
rateLimit: secretsLimit rateLimit: secretsLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Secrets],
description: "Delete many secrets", description: "Delete many secrets",
security: [ security: [
{ {
@@ -2266,6 +2290,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
rateLimit: secretsLimit rateLimit: secretsLimit
}, },
schema: { schema: {
hide: false,
tags: [ApiDocsTags.Secrets],
description: "Get secret reference tree", description: "Get secret reference tree",
security: [ security: [
{ {
@@ -11,6 +11,7 @@ export enum AppConnection {
Postgres = "postgres", Postgres = "postgres",
MsSql = "mssql", MsSql = "mssql",
Camunda = "camunda", Camunda = "camunda",
Windmill = "windmill",
Auth0 = "auth0" Auth0 = "auth0"
} }
@@ -50,6 +50,11 @@ import {
} from "./terraform-cloud"; } from "./terraform-cloud";
import { VercelConnectionMethod } from "./vercel"; import { VercelConnectionMethod } from "./vercel";
import { getVercelConnectionListItem, validateVercelConnectionCredentials } from "./vercel/vercel-connection-fns"; import { getVercelConnectionListItem, validateVercelConnectionCredentials } from "./vercel/vercel-connection-fns";
import {
getWindmillConnectionListItem,
validateWindmillConnectionCredentials,
WindmillConnectionMethod
} from "./windmill";
export const listAppConnectionOptions = () => { export const listAppConnectionOptions = () => {
return [ return [
@@ -65,6 +70,7 @@ export const listAppConnectionOptions = () => {
getPostgresConnectionListItem(), getPostgresConnectionListItem(),
getMsSqlConnectionListItem(), getMsSqlConnectionListItem(),
getCamundaConnectionListItem(), getCamundaConnectionListItem(),
getWindmillConnectionListItem(),
getAuth0ConnectionListItem() getAuth0ConnectionListItem()
].sort((a, b) => a.name.localeCompare(b.name)); ].sort((a, b) => a.name.localeCompare(b.name));
}; };
@@ -128,7 +134,8 @@ export const validateAppConnectionCredentials = async (
[AppConnection.Camunda]: validateCamundaConnectionCredentials as TAppConnectionCredentialsValidator, [AppConnection.Camunda]: validateCamundaConnectionCredentials as TAppConnectionCredentialsValidator,
[AppConnection.Vercel]: validateVercelConnectionCredentials as TAppConnectionCredentialsValidator, [AppConnection.Vercel]: validateVercelConnectionCredentials as TAppConnectionCredentialsValidator,
[AppConnection.TerraformCloud]: validateTerraformCloudConnectionCredentials as TAppConnectionCredentialsValidator, [AppConnection.TerraformCloud]: validateTerraformCloudConnectionCredentials as TAppConnectionCredentialsValidator,
[AppConnection.Auth0]: validateAuth0ConnectionCredentials as TAppConnectionCredentialsValidator [AppConnection.Auth0]: validateAuth0ConnectionCredentials as TAppConnectionCredentialsValidator,
[AppConnection.Windmill]: validateWindmillConnectionCredentials as TAppConnectionCredentialsValidator
}; };
return VALIDATE_APP_CONNECTION_CREDENTIALS_MAP[appConnection.app](appConnection); return VALIDATE_APP_CONNECTION_CREDENTIALS_MAP[appConnection.app](appConnection);
@@ -159,6 +166,8 @@ export const getAppConnectionMethodName = (method: TAppConnection["method"]) =>
case PostgresConnectionMethod.UsernameAndPassword: case PostgresConnectionMethod.UsernameAndPassword:
case MsSqlConnectionMethod.UsernameAndPassword: case MsSqlConnectionMethod.UsernameAndPassword:
return "Username & Password"; return "Username & Password";
case WindmillConnectionMethod.AccessToken:
return "Access Token";
case Auth0ConnectionMethod.ClientCredentials: case Auth0ConnectionMethod.ClientCredentials:
return "Client Credentials"; return "Client Credentials";
default: default:
@@ -204,5 +213,6 @@ export const TRANSITION_CONNECTION_CREDENTIALS_TO_PLATFORM: Record<
[AppConnection.TerraformCloud]: platformManagedCredentialsNotSupported, [AppConnection.TerraformCloud]: platformManagedCredentialsNotSupported,
[AppConnection.Camunda]: platformManagedCredentialsNotSupported, [AppConnection.Camunda]: platformManagedCredentialsNotSupported,
[AppConnection.Vercel]: platformManagedCredentialsNotSupported, [AppConnection.Vercel]: platformManagedCredentialsNotSupported,
[AppConnection.Windmill]: platformManagedCredentialsNotSupported,
[AppConnection.Auth0]: platformManagedCredentialsNotSupported [AppConnection.Auth0]: platformManagedCredentialsNotSupported
}; };
@@ -13,5 +13,6 @@ export const APP_CONNECTION_NAME_MAP: Record<AppConnection, string> = {
[AppConnection.Postgres]: "PostgreSQL", [AppConnection.Postgres]: "PostgreSQL",
[AppConnection.MsSql]: "Microsoft SQL Server", [AppConnection.MsSql]: "Microsoft SQL Server",
[AppConnection.Camunda]: "Camunda", [AppConnection.Camunda]: "Camunda",
[AppConnection.Windmill]: "Windmill",
[AppConnection.Auth0]: "Auth0" [AppConnection.Auth0]: "Auth0"
}; };
@@ -49,6 +49,8 @@ import { ValidateTerraformCloudConnectionCredentialsSchema } from "./terraform-c
import { terraformCloudConnectionService } from "./terraform-cloud/terraform-cloud-connection-service"; import { terraformCloudConnectionService } from "./terraform-cloud/terraform-cloud-connection-service";
import { ValidateVercelConnectionCredentialsSchema } from "./vercel"; import { ValidateVercelConnectionCredentialsSchema } from "./vercel";
import { vercelConnectionService } from "./vercel/vercel-connection-service"; import { vercelConnectionService } from "./vercel/vercel-connection-service";
import { ValidateWindmillConnectionCredentialsSchema } from "./windmill";
import { windmillConnectionService } from "./windmill/windmill-connection-service";
export type TAppConnectionServiceFactoryDep = { export type TAppConnectionServiceFactoryDep = {
appConnectionDAL: TAppConnectionDALFactory; appConnectionDAL: TAppConnectionDALFactory;
@@ -71,6 +73,7 @@ const VALIDATE_APP_CONNECTION_CREDENTIALS_MAP: Record<AppConnection, TValidateAp
[AppConnection.Postgres]: ValidatePostgresConnectionCredentialsSchema, [AppConnection.Postgres]: ValidatePostgresConnectionCredentialsSchema,
[AppConnection.MsSql]: ValidateMsSqlConnectionCredentialsSchema, [AppConnection.MsSql]: ValidateMsSqlConnectionCredentialsSchema,
[AppConnection.Camunda]: ValidateCamundaConnectionCredentialsSchema, [AppConnection.Camunda]: ValidateCamundaConnectionCredentialsSchema,
[AppConnection.Windmill]: ValidateWindmillConnectionCredentialsSchema,
[AppConnection.Auth0]: ValidateAuth0ConnectionCredentialsSchema [AppConnection.Auth0]: ValidateAuth0ConnectionCredentialsSchema
}; };
@@ -446,6 +449,7 @@ export const appConnectionServiceFactory = ({
terraformCloud: terraformCloudConnectionService(connectAppConnectionById), terraformCloud: terraformCloudConnectionService(connectAppConnectionById),
camunda: camundaConnectionService(connectAppConnectionById, appConnectionDAL, kmsService), camunda: camundaConnectionService(connectAppConnectionById, appConnectionDAL, kmsService),
vercel: vercelConnectionService(connectAppConnectionById), vercel: vercelConnectionService(connectAppConnectionById),
windmill: windmillConnectionService(connectAppConnectionById),
auth0: auth0ConnectionService(connectAppConnectionById, appConnectionDAL, kmsService) auth0: auth0ConnectionService(connectAppConnectionById, appConnectionDAL, kmsService)
}; };
}; };
@@ -75,6 +75,12 @@ import {
TVercelConnectionConfig, TVercelConnectionConfig,
TVercelConnectionInput TVercelConnectionInput
} from "./vercel"; } from "./vercel";
import {
TValidateWindmillConnectionCredentialsSchema,
TWindmillConnection,
TWindmillConnectionConfig,
TWindmillConnectionInput
} from "./windmill";
export type TAppConnection = { id: string } & ( export type TAppConnection = { id: string } & (
| TAwsConnection | TAwsConnection
@@ -89,6 +95,7 @@ export type TAppConnection = { id: string } & (
| TPostgresConnection | TPostgresConnection
| TMsSqlConnection | TMsSqlConnection
| TCamundaConnection | TCamundaConnection
| TWindmillConnection
| TAuth0Connection | TAuth0Connection
); );
@@ -109,6 +116,7 @@ export type TAppConnectionInput = { id: string } & (
| TPostgresConnectionInput | TPostgresConnectionInput
| TMsSqlConnectionInput | TMsSqlConnectionInput
| TCamundaConnectionInput | TCamundaConnectionInput
| TWindmillConnectionInput
| TAuth0ConnectionInput | TAuth0ConnectionInput
); );
@@ -132,9 +140,10 @@ export type TAppConnectionConfig =
| TDatabricksConnectionConfig | TDatabricksConnectionConfig
| THumanitecConnectionConfig | THumanitecConnectionConfig
| TTerraformCloudConnectionConfig | TTerraformCloudConnectionConfig
| TVercelConnectionConfig
| TSqlConnectionConfig | TSqlConnectionConfig
| TCamundaConnectionConfig | TCamundaConnectionConfig
| TVercelConnectionConfig | TWindmillConnectionConfig
| TAuth0ConnectionConfig; | TAuth0ConnectionConfig;
export type TValidateAppConnectionCredentialsSchema = export type TValidateAppConnectionCredentialsSchema =
@@ -148,8 +157,9 @@ export type TValidateAppConnectionCredentialsSchema =
| TValidatePostgresConnectionCredentialsSchema | TValidatePostgresConnectionCredentialsSchema
| TValidateMsSqlConnectionCredentialsSchema | TValidateMsSqlConnectionCredentialsSchema
| TValidateCamundaConnectionCredentialsSchema | TValidateCamundaConnectionCredentialsSchema
| TValidateVercelConnectionCredentialsSchema
| TValidateTerraformCloudConnectionCredentialsSchema | TValidateTerraformCloudConnectionCredentialsSchema
| TValidateVercelConnectionCredentialsSchema
| TValidateWindmillConnectionCredentialsSchema
| TValidateAuth0ConnectionCredentialsSchema; | TValidateAuth0ConnectionCredentialsSchema;
export type TListAwsConnectionKmsKeys = { export type TListAwsConnectionKmsKeys = {
@@ -77,20 +77,22 @@ export const getSqlConnectionClient = async (appConnection: Pick<TSqlConnection,
export const validateSqlConnectionCredentials = async (config: TSqlConnectionConfig) => { export const validateSqlConnectionCredentials = async (config: TSqlConnectionConfig) => {
const { credentials, app } = config; const { credentials, app } = config;
const client = await getSqlConnectionClient({ app, credentials }); let client: Knex | undefined;
try { try {
client = await getSqlConnectionClient({ app, credentials });
await client.raw(`Select 1`); await client.raw(`Select 1`);
return credentials; return credentials;
} catch (error) { } catch (error) {
throw new BadRequestError({ throw new BadRequestError({
message: message: `Unable to validate connection: ${
(error as Error)?.message?.replaceAll(credentials.password, "********************") ?? (error as Error)?.message?.replaceAll(credentials.password, "********************") ?? "verify credentials"
"Unable to validate connection: verify credentials" }`
}); });
} finally { } finally {
await client.destroy(); await client?.destroy();
} }
}; };
@@ -44,7 +44,7 @@ export const validateTerraformCloudConnectionCredentials = async (config: TTerra
}); });
} }
throw new BadRequestError({ throw new BadRequestError({
message: "Unable to validate connection - verify credentials" message: "Unable to validate connection: verify credentials"
}); });
} }
@@ -1,5 +1,5 @@
/* eslint-disable no-await-in-loop */ /* eslint-disable no-await-in-loop */
import { AxiosError, AxiosResponse } from "axios"; import { AxiosError } from "axios";
import { request } from "@app/lib/config/request"; import { request } from "@app/lib/config/request";
import { BadRequestError, InternalServerError } from "@app/lib/errors"; import { BadRequestError, InternalServerError } from "@app/lib/errors";
@@ -27,10 +27,8 @@ export const getVercelConnectionListItem = () => {
export const validateVercelConnectionCredentials = async (config: TVercelConnectionConfig) => { export const validateVercelConnectionCredentials = async (config: TVercelConnectionConfig) => {
const { credentials: inputCredentials } = config; const { credentials: inputCredentials } = config;
let response: AxiosResponse<VercelApp[]> | null = null;
try { try {
response = await request.get<VercelApp[]>(`${IntegrationUrls.VERCEL_API_URL}/v9/projects`, { await request.get(`${IntegrationUrls.VERCEL_API_URL}/v2/user`, {
headers: { headers: {
Authorization: `Bearer ${inputCredentials.apiToken}` Authorization: `Bearer ${inputCredentials.apiToken}`
} }
@@ -38,17 +36,14 @@ export const validateVercelConnectionCredentials = async (config: TVercelConnect
} catch (error: unknown) { } catch (error: unknown) {
if (error instanceof AxiosError) { if (error instanceof AxiosError) {
throw new BadRequestError({ throw new BadRequestError({
message: `Failed to validate credentials: ${error.message || "Unknown error"}` // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
message: `Failed to validate credentials: ${
error.response?.data ? JSON.stringify(error.response?.data) : error.message || "Unknown error"
}`
}); });
} }
throw new BadRequestError({ throw new BadRequestError({
message: "Unable to validate connection - verify credentials" message: `Unable to validate connection: ${(error as Error).message || "Verify credentials"}`
});
}
if (!response?.data) {
throw new InternalServerError({
message: "Failed to get organizations: Response was empty"
}); });
} }
@@ -0,0 +1,4 @@
export * from "./windmill-connection-enums";
export * from "./windmill-connection-fns";
export * from "./windmill-connection-schemas";
export * from "./windmill-connection-types";
@@ -0,0 +1,3 @@
export enum WindmillConnectionMethod {
AccessToken = "access-token"
}
@@ -0,0 +1,65 @@
import { AxiosError } from "axios";
import { request } from "@app/lib/config/request";
import { BadRequestError } from "@app/lib/errors";
import { removeTrailingSlash } from "@app/lib/fn";
import { blockLocalAndPrivateIpAddresses } from "@app/lib/validator";
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
import { WindmillConnectionMethod } from "./windmill-connection-enums";
import { TWindmillConnection, TWindmillConnectionConfig, TWindmillWorkspace } from "./windmill-connection-types";
export const getWindmillInstanceUrl = async (config: TWindmillConnectionConfig) => {
const instanceUrl = config.credentials.instanceUrl
? removeTrailingSlash(config.credentials.instanceUrl)
: "https://app.windmill.dev";
await blockLocalAndPrivateIpAddresses(instanceUrl);
return instanceUrl;
};
export const getWindmillConnectionListItem = () => {
return {
name: "Windmill" as const,
app: AppConnection.Windmill as const,
methods: Object.values(WindmillConnectionMethod) as [WindmillConnectionMethod.AccessToken]
};
};
export const validateWindmillConnectionCredentials = async (config: TWindmillConnectionConfig) => {
const instanceUrl = await getWindmillInstanceUrl(config);
const { accessToken } = config.credentials;
try {
await request.get(`${instanceUrl}/api/workspaces/list`, {
headers: {
Authorization: `Bearer ${accessToken}`
}
});
} catch (error: unknown) {
if (error instanceof AxiosError) {
throw new BadRequestError({
message: `Failed to validate credentials: ${error.message || "Unknown error"}`
});
}
throw new BadRequestError({
message: "Unable to validate connection: verify credentials"
});
}
return config.credentials;
};
export const listWindmillWorkspaces = async (appConnection: TWindmillConnection) => {
const instanceUrl = await getWindmillInstanceUrl(appConnection);
const { accessToken } = appConnection.credentials;
const resp = await request.get<TWindmillWorkspace[]>(`${instanceUrl}/api/workspaces/list`, {
headers: {
Authorization: `Bearer ${accessToken}`
}
});
return resp.data.filter((workspace) => !workspace.deleted);
};
@@ -0,0 +1,70 @@
import z from "zod";
import { AppConnections } from "@app/lib/api-docs";
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
import {
BaseAppConnectionSchema,
GenericCreateAppConnectionFieldsSchema,
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { WindmillConnectionMethod } from "./windmill-connection-enums";
export const WindmillConnectionAccessTokenCredentialsSchema = z.object({
accessToken: z
.string()
.trim()
.min(1, "Access Token required")
.describe(AppConnections.CREDENTIALS.WINDMILL.accessToken),
instanceUrl: z
.string()
.trim()
.url("Invalid Instance URL")
.optional()
.describe(AppConnections.CREDENTIALS.WINDMILL.instanceUrl)
});
const BaseWindmillConnectionSchema = BaseAppConnectionSchema.extend({ app: z.literal(AppConnection.Windmill) });
export const WindmillConnectionSchema = BaseWindmillConnectionSchema.extend({
method: z.literal(WindmillConnectionMethod.AccessToken),
credentials: WindmillConnectionAccessTokenCredentialsSchema
});
export const SanitizedWindmillConnectionSchema = z.discriminatedUnion("method", [
BaseWindmillConnectionSchema.extend({
method: z.literal(WindmillConnectionMethod.AccessToken),
credentials: WindmillConnectionAccessTokenCredentialsSchema.pick({
instanceUrl: true
})
})
]);
export const ValidateWindmillConnectionCredentialsSchema = z.discriminatedUnion("method", [
z.object({
method: z
.literal(WindmillConnectionMethod.AccessToken)
.describe(AppConnections.CREATE(AppConnection.Windmill).method),
credentials: WindmillConnectionAccessTokenCredentialsSchema.describe(
AppConnections.CREATE(AppConnection.Windmill).credentials
)
})
]);
export const CreateWindmillConnectionSchema = ValidateWindmillConnectionCredentialsSchema.and(
GenericCreateAppConnectionFieldsSchema(AppConnection.Windmill)
);
export const UpdateWindmillConnectionSchema = z
.object({
credentials: WindmillConnectionAccessTokenCredentialsSchema.optional().describe(
AppConnections.UPDATE(AppConnection.Windmill).credentials
)
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Windmill));
export const WindmillConnectionListItemSchema = z.object({
name: z.literal("Windmill"),
app: z.literal(AppConnection.Windmill),
methods: z.nativeEnum(WindmillConnectionMethod).array()
});
@@ -0,0 +1,28 @@
import { OrgServiceActor } from "@app/lib/types";
import { AppConnection } from "../app-connection-enums";
import { listWindmillWorkspaces } from "./windmill-connection-fns";
import { TWindmillConnection } from "./windmill-connection-types";
type TGetAppConnectionFunc = (
app: AppConnection,
connectionId: string,
actor: OrgServiceActor
) => Promise<TWindmillConnection>;
export const windmillConnectionService = (getAppConnection: TGetAppConnectionFunc) => {
const listWorkspaces = async (connectionId: string, actor: OrgServiceActor) => {
const appConnection = await getAppConnection(AppConnection.Windmill, connectionId, actor);
try {
const workspaces = await listWindmillWorkspaces(appConnection);
return workspaces;
} catch (error) {
return [];
}
};
return {
listWorkspaces
};
};
@@ -0,0 +1,27 @@
import z from "zod";
import { DiscriminativePick } from "@app/lib/types";
import { AppConnection } from "../app-connection-enums";
import {
CreateWindmillConnectionSchema,
ValidateWindmillConnectionCredentialsSchema,
WindmillConnectionSchema
} from "./windmill-connection-schemas";
export type TWindmillConnection = z.infer<typeof WindmillConnectionSchema>;
export type TWindmillConnectionInput = z.infer<typeof CreateWindmillConnectionSchema> & {
app: AppConnection.Windmill;
};
export type TValidateWindmillConnectionCredentialsSchema = typeof ValidateWindmillConnectionCredentialsSchema;
export type TWindmillConnectionConfig = DiscriminativePick<
TWindmillConnectionInput,
"method" | "app" | "credentials"
> & {
orgId: string;
};
export type TWindmillWorkspace = { id: string; name: string; deleted: boolean };
@@ -47,7 +47,10 @@ export const tokenDALFactory = (db: TDbClient) => {
const findTokenSessions = async (filter: Partial<TAuthTokenSessions>, tx?: Knex) => { const findTokenSessions = async (filter: Partial<TAuthTokenSessions>, tx?: Knex) => {
try { try {
const sessions = await (tx || db.replicaNode())(TableName.AuthTokenSession).where(filter); const sessions = await (tx || db.replicaNode())(TableName.AuthTokenSession)
.where(filter)
.orderBy("lastUsed", "desc");
return sessions; return sessions;
} catch (error) { } catch (error) {
throw new DatabaseError({ name: "Find all token session", error }); throw new DatabaseError({ name: "Find all token session", error });
@@ -151,6 +151,9 @@ export const tokenServiceFactory = ({ tokenDAL, userDAL, orgMembershipDAL }: TAu
const revokeAllMySessions = async (userId: string) => tokenDAL.deleteTokenSession({ userId }); const revokeAllMySessions = async (userId: string) => tokenDAL.deleteTokenSession({ userId });
const revokeMySessionById = async (userId: string, sessionId: string) =>
tokenDAL.deleteTokenSession({ userId, id: sessionId });
const validateRefreshToken = async (refreshToken?: string) => { const validateRefreshToken = async (refreshToken?: string) => {
const appCfg = getConfig(); const appCfg = getConfig();
if (!refreshToken) if (!refreshToken)
@@ -223,6 +226,7 @@ export const tokenServiceFactory = ({ tokenDAL, userDAL, orgMembershipDAL }: TAu
clearTokenSessionById, clearTokenSessionById,
getTokenSessionByUser, getTokenSessionByUser,
revokeAllMySessions, revokeAllMySessions,
revokeMySessionById,
validateRefreshToken, validateRefreshToken,
fnValidateJwtIdentity, fnValidateJwtIdentity,
getUserTokenSessionById getUserTokenSessionById
@@ -3,6 +3,8 @@ import jwt from "jsonwebtoken";
import { Knex } from "knex"; import { Knex } from "knex";
import { OrgMembershipRole, TUsers, UserDeviceSchema } from "@app/db/schemas"; import { OrgMembershipRole, TUsers, UserDeviceSchema } from "@app/db/schemas";
import { TAuditLogServiceFactory } from "@app/ee/services/audit-log/audit-log-service";
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { isAuthMethodSaml } from "@app/ee/services/permission/permission-fns"; import { isAuthMethodSaml } from "@app/ee/services/permission/permission-fns";
import { getConfig } from "@app/lib/config/env"; import { getConfig } from "@app/lib/config/env";
import { request } from "@app/lib/config/request"; import { request } from "@app/lib/config/request";
@@ -11,6 +13,7 @@ import { infisicalSymmetricEncypt } from "@app/lib/crypto/encryption";
import { getUserPrivateKey } from "@app/lib/crypto/srp"; import { getUserPrivateKey } from "@app/lib/crypto/srp";
import { BadRequestError, DatabaseError, ForbiddenRequestError, UnauthorizedError } from "@app/lib/errors"; import { BadRequestError, DatabaseError, ForbiddenRequestError, UnauthorizedError } from "@app/lib/errors";
import { logger } from "@app/lib/logger"; import { logger } from "@app/lib/logger";
import { getUserAgentType } from "@app/server/plugins/audit-log";
import { getServerCfg } from "@app/services/super-admin/super-admin-service"; import { getServerCfg } from "@app/services/super-admin/super-admin-service";
import { TAuthTokenServiceFactory } from "../auth-token/auth-token-service"; import { TAuthTokenServiceFactory } from "../auth-token/auth-token-service";
@@ -28,7 +31,15 @@ import {
TOauthTokenExchangeDTO, TOauthTokenExchangeDTO,
TVerifyMfaTokenDTO TVerifyMfaTokenDTO
} from "./auth-login-type"; } from "./auth-login-type";
import { AuthMethod, AuthModeJwtTokenPayload, AuthModeMfaJwtTokenPayload, AuthTokenType, MfaMethod } from "./auth-type"; import {
ActorType,
AuthMethod,
AuthModeJwtTokenPayload,
AuthModeMfaJwtTokenPayload,
AuthTokenType,
MfaMethod
} from "./auth-type";
import { removeTrailingSlash } from "@app/lib/fn";
type TAuthLoginServiceFactoryDep = { type TAuthLoginServiceFactoryDep = {
userDAL: TUserDALFactory; userDAL: TUserDALFactory;
@@ -36,6 +47,7 @@ type TAuthLoginServiceFactoryDep = {
tokenService: TAuthTokenServiceFactory; tokenService: TAuthTokenServiceFactory;
smtpService: TSmtpService; smtpService: TSmtpService;
totpService: Pick<TTotpServiceFactory, "verifyUserTotp" | "verifyWithUserRecoveryCode">; totpService: Pick<TTotpServiceFactory, "verifyUserTotp" | "verifyWithUserRecoveryCode">;
auditLogService: Pick<TAuditLogServiceFactory, "createAuditLog">;
}; };
export type TAuthLoginFactory = ReturnType<typeof authLoginServiceFactory>; export type TAuthLoginFactory = ReturnType<typeof authLoginServiceFactory>;
@@ -44,7 +56,8 @@ export const authLoginServiceFactory = ({
tokenService, tokenService,
smtpService, smtpService,
orgDAL, orgDAL,
totpService totpService,
auditLogService
}: TAuthLoginServiceFactoryDep) => { }: TAuthLoginServiceFactoryDep) => {
/* /*
* Private * Private
@@ -412,6 +425,55 @@ export const authLoginServiceFactory = ({
mfaMethod: decodedToken.mfaMethod mfaMethod: decodedToken.mfaMethod
}); });
// In the event of this being a break-glass request (non-saml / non-oidc, when either is enforced)
if (
selectedOrg.authEnforced &&
selectedOrg.bypassOrgAuthEnabled &&
!isAuthMethodSaml(decodedToken.authMethod) &&
decodedToken.authMethod !== AuthMethod.OIDC
) {
await auditLogService.createAuditLog({
orgId: organizationId,
ipAddress,
userAgent,
userAgentType: getUserAgentType(userAgent),
actor: {
type: ActorType.USER,
metadata: {
email: user.email,
userId: user.id,
username: user.username
}
},
event: {
type: EventType.ORG_ADMIN_BYPASS_SSO,
metadata: {}
}
});
// Notify all admins via email (besides the actor)
const orgAdmins = await orgDAL.findOrgMembersByRole(organizationId, OrgMembershipRole.Admin);
const adminEmails = orgAdmins
.filter((admin) => admin.user.id !== user.id)
.map((admin) => admin.user.email)
.filter(Boolean) as string[];
if (adminEmails.length > 0) {
await smtpService.sendMail({
recipients: adminEmails,
subjectLine: "Security Alert: Admin SSO Bypass",
substitutions: {
email: user.email,
timestamp: new Date().toISOString(),
ip: ipAddress,
userAgent,
siteUrl: removeTrailingSlash(cfg.SITE_URL || "https://app.infisical.com")
},
template: SmtpTemplates.OrgAdminBreakglassAccess
});
}
}
return { return {
...tokens, ...tokens,
isMfaEnabled: false isMfaEnabled: false
@@ -1,3 +1,5 @@
import RE2 from "re2";
import { TCertificateTemplates } from "@app/db/schemas"; import { TCertificateTemplates } from "@app/db/schemas";
import { BadRequestError } from "@app/lib/errors"; import { BadRequestError } from "@app/lib/errors";
import { ms } from "@app/lib/ms"; import { ms } from "@app/lib/ms";
@@ -12,7 +14,7 @@ export const validateCertificateDetailsAgainstTemplate = (
template: TCertificateTemplates template: TCertificateTemplates
) => { ) => {
// these are validated in router using validateTemplateRegexField // these are validated in router using validateTemplateRegexField
const commonNameRegex = new RegExp(template.commonName); const commonNameRegex = new RE2(template.commonName);
if (!commonNameRegex.test(cert.commonName)) { if (!commonNameRegex.test(cert.commonName)) {
throw new BadRequestError({ throw new BadRequestError({
message: "Invalid common name based on template policy" message: "Invalid common name based on template policy"
@@ -25,7 +27,7 @@ export const validateCertificateDetailsAgainstTemplate = (
}); });
} }
const subjectAlternativeNameRegex = new RegExp(template.subjectAlternativeName); const subjectAlternativeNameRegex = new RE2(template.subjectAlternativeName);
cert.altNames.forEach((altName) => { cert.altNames.forEach((altName) => {
if (!subjectAlternativeNameRegex.test(altName)) { if (!subjectAlternativeNameRegex.test(altName)) {
throw new BadRequestError({ throw new BadRequestError({
@@ -2,6 +2,7 @@
import { ForbiddenError } from "@casl/ability"; import { ForbiddenError } from "@casl/ability";
import axios from "axios"; import axios from "axios";
import jwt from "jsonwebtoken"; import jwt from "jsonwebtoken";
import RE2 from "re2";
import { IdentityAuthMethod } from "@app/db/schemas"; import { IdentityAuthMethod } from "@app/db/schemas";
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
@@ -67,6 +68,15 @@ const awsRegionFromHeader = (authorizationHeader: string): string | null => {
return null; return null;
}; };
function isValidAwsRegion(region: string | null): boolean {
const validRegionPattern = new RE2("^[a-z0-9-]+$");
if (typeof region !== "string" || region.length === 0 || region.length > 20) {
return false;
}
return validRegionPattern.test(region);
}
export const identityAwsAuthServiceFactory = ({ export const identityAwsAuthServiceFactory = ({
identityAccessTokenDAL, identityAccessTokenDAL,
identityAwsAuthDAL, identityAwsAuthDAL,
@@ -84,8 +94,12 @@ export const identityAwsAuthServiceFactory = ({
const headers: TAwsGetCallerIdentityHeaders = JSON.parse(Buffer.from(iamRequestHeaders, "base64").toString()); const headers: TAwsGetCallerIdentityHeaders = JSON.parse(Buffer.from(iamRequestHeaders, "base64").toString());
const body: string = Buffer.from(iamRequestBody, "base64").toString(); const body: string = Buffer.from(iamRequestBody, "base64").toString();
const region = headers.Authorization ? awsRegionFromHeader(headers.Authorization) : null; const region = headers.Authorization ? awsRegionFromHeader(headers.Authorization) : null;
if (!isValidAwsRegion(region)) {
throw new BadRequestError({ message: "Invalid AWS region" });
}
const url = region ? `https://sts.${region}.amazonaws.com` : identityAwsAuth.stsEndpoint; const url = region ? `https://sts.${region}.amazonaws.com` : identityAwsAuth.stsEndpoint;
const { const {
@@ -125,7 +139,7 @@ export const identityAwsAuthServiceFactory = ({
// convert wildcard ARN to a regular expression: "arn:aws:iam::123456789012:*" -> "^arn:aws:iam::123456789012:.*$" // convert wildcard ARN to a regular expression: "arn:aws:iam::123456789012:*" -> "^arn:aws:iam::123456789012:.*$"
// considers exact matches + wildcard matches // considers exact matches + wildcard matches
// heavily validated in router // heavily validated in router
const regex = new RegExp(`^${principalArn.replaceAll("*", ".*")}$`); const regex = new RE2(`^${principalArn.replaceAll("*", ".*")}$`);
return regex.test(extractPrincipalArn(Arn)); return regex.test(extractPrincipalArn(Arn));
}); });
@@ -1,9 +1,10 @@
import RE2 from "re2";
import safe from "safe-regex"; import safe from "safe-regex";
import { z } from "zod"; import { z } from "zod";
const twelveDigitRegex = /^\d{12}$/; const twelveDigitRegex = new RE2(/^\d{12}$/);
// akhilmhdh: change this to a normal function later. Checked no redosable at the moment // akhilmhdh: change this to a normal function later. Checked no redosable at the moment
const arnRegex = /^arn:aws:iam::\d{12}:(user\/[a-zA-Z0-9_.@+*/-]+|role\/[a-zA-Z0-9_.@+*/-]+|\*)$/; const arnRegex = new RE2(/^arn:aws:iam::\d{12}:(user\/[a-zA-Z0-9_.@+*/-]+|role\/[a-zA-Z0-9_.@+*/-]+|\*)$/);
export const validateAccountIds = z export const validateAccountIds = z
.string() .string()
@@ -435,12 +435,16 @@ export const identityKubernetesAuthServiceFactory = ({
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
const identityKubernetesAuth = await identityKubernetesAuthDAL.findOne({ identityId });
if (!identityKubernetesAuth) {
throw new NotFoundError({ message: `Failed to find Kubernetes Auth for identity with ID ${identityId}` });
}
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.KUBERNETES_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.KUBERNETES_AUTH)) {
throw new BadRequestError({ throw new BadRequestError({
message: "The identity does not have Kubernetes Auth attached" message: "The identity does not have Kubernetes Auth attached"
}); });
} }
const identityKubernetesAuth = await identityKubernetesAuthDAL.findOne({ identityId });
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
@@ -50,7 +50,7 @@ const getIntegrationSecretsV2 = async (
} }
// process secrets in current folder // process secrets in current folder
const secrets = await secretV2BridgeDAL.findByFolderId({ folderId: dto.folderId, projectId: dto.projectId }); const secrets = await secretV2BridgeDAL.findByFolderId({ folderId: dto.folderId });
secrets.forEach((secret) => { secrets.forEach((secret) => {
const secretKey = secret.key; const secretKey = secret.key;
@@ -63,7 +63,6 @@ const getIntegrationSecretsV2 = async (
// if no imports then return secrets in the current folder // if no imports then return secrets in the current folder
if (!secretImports.length) return content; if (!secretImports.length) return content;
const importedSecrets = await fnSecretsV2FromImports({ const importedSecrets = await fnSecretsV2FromImports({
projectId: dto.projectId,
decryptor: dto.decryptor, decryptor: dto.decryptor,
folderDAL, folderDAL,
secretDAL: secretV2BridgeDAL, secretDAL: secretV2BridgeDAL,

Some files were not shown because too many files have changed in this diff Show More