diff --git a/backend-pg/src/@types/knex.d.ts b/backend-pg/src/@types/knex.d.ts index 252708c68..887e85fc3 100644 --- a/backend-pg/src/@types/knex.d.ts +++ b/backend-pg/src/@types/knex.d.ts @@ -12,6 +12,7 @@ import { TAuthTokenSessions, TAuthTokenSessionsInsert, TAuthTokenSessionsUpdate, + TAuthTokensInsert, TAuthTokensUpdate, TBackupPrivateKey, TBackupPrivateKeyInsert, @@ -272,11 +273,6 @@ declare module "knex/types/tables" { TSecretImportsInsert, TSecretImportsUpdate >; - [TableName.SecretSnapshot]: Knex.CompositeTableType< - TSecretSnapshots, - TSecretSnapshotsInsert, - TSecretSnapshotsUpdate - >; [TableName.Integration]: Knex.CompositeTableType< TIntegrations, TIntegrationsInsert, diff --git a/backend-pg/src/services/super-admin/super-admin-service.ts b/backend-pg/src/services/super-admin/super-admin-service.ts index 32b9ba870..3eadd8be8 100644 --- a/backend-pg/src/services/super-admin/super-admin-service.ts +++ b/backend-pg/src/services/super-admin/super-admin-service.ts @@ -2,11 +2,11 @@ import { TSuperAdmin, TSuperAdminUpdate } from "@app/db/schemas"; import { BadRequestError } from "@app/lib/errors"; import { TAuthLoginFactory } from "../auth/auth-login-service"; +import { AuthMethod } from "../auth/auth-type"; +import { TOrgServiceFactory } from "../org/org-service"; import { TUserDalFactory } from "../user/user-dal"; import { TSuperAdminDalFactory } from "./super-admin-dal"; import { TAdminSignUpDTO } from "./super-admin-types"; -import { TOrgServiceFactory } from "../org/org-service"; -import { AuthMethod } from "../auth/auth-type"; type TSuperAdminServiceFactoryDep = { serverCfgDal: TSuperAdminDalFactory; diff --git a/pg-migrator/package-lock.json b/pg-migrator/package-lock.json new file mode 100644 index 000000000..8560ceeee --- /dev/null +++ b/pg-migrator/package-lock.json @@ -0,0 +1,1365 @@ +{ + "name": "pg-migrator", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "pg-migrator", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "dotenv": "^16.3.1", + "knex": "^3.1.0", + "level": "^8.0.0", + "mongoose": "^8.0.4", + "pg": "^8.11.3", + "prompt-sync": "^4.2.0", + "zod": "^3.22.4" + }, + "devDependencies": { + "@types/node": "^20.11.0", + "@types/prompt-sync": "^4.2.3", + "tsx": "^4.7.0", + "typescript": "^5.3.3" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.11.tgz", + "integrity": "sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.11.tgz", + "integrity": "sha512-5OVapq0ClabvKvQ58Bws8+wkLCV+Rxg7tUVbo9xu034Nm536QTII4YzhaFriQ7rMrorfnFKUsArD2lqKbFY4vw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.11.tgz", + "integrity": "sha512-aiu7K/5JnLj//KOnOfEZ0D90obUkRzDMyqd/wNAUQ34m4YUPVhRZpnqKV9uqDGxT7cToSDnIHsGooyIczu9T+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.11.tgz", + "integrity": "sha512-eccxjlfGw43WYoY9QgB82SgGgDbibcqyDTlk3l3C0jOVHKxrjdc9CTwDUQd0vkvYg5um0OH+GpxYvp39r+IPOg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.11.tgz", + "integrity": "sha512-ETp87DRWuSt9KdDVkqSoKoLFHYTrkyz2+65fj9nfXsaV3bMhTCjtQfw3y+um88vGRKRiF7erPrh/ZuIdLUIVxQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.11.tgz", + "integrity": "sha512-fkFUiS6IUK9WYUO/+22omwetaSNl5/A8giXvQlcinLIjVkxwTLSktbF5f/kJMftM2MJp9+fXqZ5ezS7+SALp4g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.11.tgz", + "integrity": "sha512-lhoSp5K6bxKRNdXUtHoNc5HhbXVCS8V0iZmDvyWvYq9S5WSfTIHU2UGjcGt7UeS6iEYp9eeymIl5mJBn0yiuxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.11.tgz", + "integrity": "sha512-JkUqn44AffGXitVI6/AbQdoYAq0TEullFdqcMY/PCUZ36xJ9ZJRtQabzMA+Vi7r78+25ZIBosLTOKnUXBSi1Kw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.11.tgz", + "integrity": "sha512-3CRkr9+vCV2XJbjwgzjPtO8T0SZUmRZla+UL1jw+XqHZPkPgZiyWvbDvl9rqAN8Zl7qJF0O/9ycMtjU67HN9/Q==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.11.tgz", + "integrity": "sha512-LneLg3ypEeveBSMuoa0kwMpCGmpu8XQUh+mL8XXwoYZ6Be2qBnVtcDI5azSvh7vioMDhoJFZzp9GWp9IWpYoUg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.11.tgz", + "integrity": "sha512-caHy++CsD8Bgq2V5CodbJjFPEiDPq8JJmBdeyZ8GWVQMjRD0sU548nNdwPNvKjVpamYYVL40AORekgfIubwHoA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.11.tgz", + "integrity": "sha512-ppZSSLVpPrwHccvC6nQVZaSHlFsvCQyjnvirnVjbKSHuE5N24Yl8F3UwYUUR1UEPaFObGD2tSvVKbvR+uT1Nrg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.11.tgz", + "integrity": "sha512-B5x9j0OgjG+v1dF2DkH34lr+7Gmv0kzX6/V0afF41FkPMMqaQ77pH7CrhWeR22aEeHKaeZVtZ6yFwlxOKPVFyg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.11.tgz", + "integrity": "sha512-MHrZYLeCG8vXblMetWyttkdVRjQlQUb/oMgBNurVEnhj4YWOr4G5lmBfZjHYQHHN0g6yDmCAQRR8MUHldvvRDA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.11.tgz", + "integrity": "sha512-f3DY++t94uVg141dozDu4CCUkYW+09rWtaWfnb3bqe4w5NqmZd6nPVBm+qbz7WaHZCoqXqHz5p6CM6qv3qnSSQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.11.tgz", + "integrity": "sha512-A5xdUoyWJHMMlcSMcPGVLzYzpcY8QP1RtYzX5/bS4dvjBGVxdhuiYyFwp7z74ocV7WDc0n1harxmpq2ePOjI0Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.11.tgz", + "integrity": "sha512-grbyMlVCvJSfxFQUndw5mCtWs5LO1gUlwP4CDi4iJBbVpZcqLVT29FxgGuBJGSzyOxotFG4LoO5X+M1350zmPA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.11.tgz", + "integrity": "sha512-13jvrQZJc3P230OhU8xgwUnDeuC/9egsjTkXN49b3GcS5BKvJqZn86aGM8W9pd14Kd+u7HuFBMVtrNGhh6fHEQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.11.tgz", + "integrity": "sha512-ysyOGZuTp6SNKPE11INDUeFVVQFrhcNDVUgSQVDzqsqX38DjhPEPATpid04LCoUr2WXhQTEZ8ct/EgJCUDpyNw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.11.tgz", + "integrity": "sha512-Hf+Sad9nVwvtxy4DXCZQqLpgmRTQqyFyhT3bZ4F2XlJCjxGmRFF0Shwn9rzhOYRB61w9VMXUkxlBy56dk9JJiQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.11.tgz", + "integrity": "sha512-0P58Sbi0LctOMOQbpEOvOL44Ne0sqbS0XWHMvvrg6NE5jQ1xguCSSw9jQeUk2lfrXYsKDdOe6K+oZiwKPilYPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.11.tgz", + "integrity": "sha512-6YOrWS+sDJDmshdBIQU+Uoyh7pQKrdykdefC1avn76ss5c+RN6gut3LZA4E2cH5xUEp5/cA0+YxRaVtRAb0xBg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.11.tgz", + "integrity": "sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@mongodb-js/saslprep": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.3.tgz", + "integrity": "sha512-SyCxhJfmK6MoLNV5SbDpNdUy9SDv5H7y9/9rl3KpnwgTHWuNNMc87zWqbcIZXNWY+aUjxLGLEcvHoLagG4tWCg==", + "dependencies": { + "sparse-bitfield": "^3.0.3" + } + }, + "node_modules/@types/node": { + "version": "20.11.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.0.tgz", + "integrity": "sha512-o9bjXmDNcF7GbM4CNQpmi+TutCgap/K3w1JyKgxAjqx41zp9qlIAVFi0IhCNsJcXolEqLWhbFbEeL0PvYm4pcQ==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/prompt-sync": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@types/prompt-sync/-/prompt-sync-4.2.3.tgz", + "integrity": "sha512-Ox77gCSx0YyeakGt/qfOZUSFNSSi+sh3ABoGOiCwiO2KODx492BJnUm9oIXS+AHJtqp12iM4RduY6viTJ9bYwA==", + "dev": true + }, + "node_modules/@types/webidl-conversions": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" + }, + "node_modules/@types/whatwg-url": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz", + "integrity": "sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==", + "dependencies": { + "@types/node": "*", + "@types/webidl-conversions": "*" + } + }, + "node_modules/abstract-level": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.3.tgz", + "integrity": "sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA==", + "dependencies": { + "buffer": "^6.0.3", + "catering": "^2.1.0", + "is-buffer": "^2.0.5", + "level-supports": "^4.0.0", + "level-transcoder": "^1.0.1", + "module-error": "^1.0.1", + "queue-microtask": "^1.2.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/browser-level": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browser-level/-/browser-level-1.0.1.tgz", + "integrity": "sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ==", + "dependencies": { + "abstract-level": "^1.0.2", + "catering": "^2.1.1", + "module-error": "^1.0.2", + "run-parallel-limit": "^1.1.0" + } + }, + "node_modules/bson": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.2.0.tgz", + "integrity": "sha512-ID1cI+7bazPDyL9wYy9GaQ8gEEohWvcUl/Yf0dIdutJxnmInEEyCsb4awy/OiBfall7zBA179Pahi3vCdFze3Q==", + "engines": { + "node": ">=16.20.1" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-writer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/catering": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz", + "integrity": "sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==", + "engines": { + "node": ">=6" + } + }, + "node_modules/classic-level": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/classic-level/-/classic-level-1.3.0.tgz", + "integrity": "sha512-iwFAJQYtqRTRM0F6L8h4JCt00ZSGdOyqh7yVrhhjrOpFhmBjNlRUey64MCiyo6UmQHMJ+No3c81nujPv+n9yrg==", + "hasInstallScript": true, + "dependencies": { + "abstract-level": "^1.0.2", + "catering": "^2.1.0", + "module-error": "^1.0.1", + "napi-macros": "^2.2.2", + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/colorette": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" + }, + "node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "engines": { + "node": ">=14" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/dotenv": { + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" + } + }, + "node_modules/esbuild": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.11.tgz", + "integrity": "sha512-HJ96Hev2hX/6i5cDVwcqiJBBtuo9+FeIJOtZ9W1kA5M6AMJRHUZlpYZ1/SbEwtO0ioNAW8rUooVpC/WehY2SfA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.11", + "@esbuild/android-arm": "0.19.11", + "@esbuild/android-arm64": "0.19.11", + "@esbuild/android-x64": "0.19.11", + "@esbuild/darwin-arm64": "0.19.11", + "@esbuild/darwin-x64": "0.19.11", + "@esbuild/freebsd-arm64": "0.19.11", + "@esbuild/freebsd-x64": "0.19.11", + "@esbuild/linux-arm": "0.19.11", + "@esbuild/linux-arm64": "0.19.11", + "@esbuild/linux-ia32": "0.19.11", + "@esbuild/linux-loong64": "0.19.11", + "@esbuild/linux-mips64el": "0.19.11", + "@esbuild/linux-ppc64": "0.19.11", + "@esbuild/linux-riscv64": "0.19.11", + "@esbuild/linux-s390x": "0.19.11", + "@esbuild/linux-x64": "0.19.11", + "@esbuild/netbsd-x64": "0.19.11", + "@esbuild/openbsd-x64": "0.19.11", + "@esbuild/sunos-x64": "0.19.11", + "@esbuild/win32-arm64": "0.19.11", + "@esbuild/win32-ia32": "0.19.11", + "@esbuild/win32-x64": "0.19.11" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/esm": { + "version": "3.2.25", + "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", + "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-tsconfig": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", + "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", + "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/getopts": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.3.0.tgz", + "integrity": "sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA==" + }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/interpret": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "engines": { + "node": ">=4" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/kareem": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz", + "integrity": "sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/knex": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/knex/-/knex-3.1.0.tgz", + "integrity": "sha512-GLoII6hR0c4ti243gMs5/1Rb3B+AjwMOfjYm97pu0FOQa7JH56hgBxYf5WK2525ceSbBY1cjeZ9yk99GPMB6Kw==", + "dependencies": { + "colorette": "2.0.19", + "commander": "^10.0.0", + "debug": "4.3.4", + "escalade": "^3.1.1", + "esm": "^3.2.25", + "get-package-type": "^0.1.0", + "getopts": "2.3.0", + "interpret": "^2.2.0", + "lodash": "^4.17.21", + "pg-connection-string": "2.6.2", + "rechoir": "^0.8.0", + "resolve-from": "^5.0.0", + "tarn": "^3.0.2", + "tildify": "2.0.0" + }, + "bin": { + "knex": "bin/cli.js" + }, + "engines": { + "node": ">=16" + }, + "peerDependenciesMeta": { + "better-sqlite3": { + "optional": true + }, + "mysql": { + "optional": true + }, + "mysql2": { + "optional": true + }, + "pg": { + "optional": true + }, + "pg-native": { + "optional": true + }, + "sqlite3": { + "optional": true + }, + "tedious": { + "optional": true + } + } + }, + "node_modules/level": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/level/-/level-8.0.0.tgz", + "integrity": "sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ==", + "dependencies": { + "browser-level": "^1.0.1", + "classic-level": "^1.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/level" + } + }, + "node_modules/level-supports": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-4.0.1.tgz", + "integrity": "sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/level-transcoder": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz", + "integrity": "sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==", + "dependencies": { + "buffer": "^6.0.3", + "module-error": "^1.0.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" + }, + "node_modules/module-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz", + "integrity": "sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/mongodb": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.2.0.tgz", + "integrity": "sha512-d7OSuGjGWDZ5usZPqfvb36laQ9CPhnWkAGHT61x5P95p/8nMVeH8asloMwW6GcYFeB0Vj4CB/1wOTDG2RA9BFA==", + "dependencies": { + "@mongodb-js/saslprep": "^1.1.0", + "bson": "^6.2.0", + "mongodb-connection-string-url": "^2.6.0" + }, + "engines": { + "node": ">=16.20.1" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.188.0", + "@mongodb-js/zstd": "^1.1.0", + "gcp-metadata": "^5.2.0", + "kerberos": "^2.0.1", + "mongodb-client-encryption": ">=6.0.0 <7", + "snappy": "^7.2.2", + "socks": "^2.7.1" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { + "optional": true + }, + "gcp-metadata": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + }, + "socks": { + "optional": true + } + } + }, + "node_modules/mongodb-connection-string-url": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz", + "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==", + "dependencies": { + "@types/whatwg-url": "^8.2.1", + "whatwg-url": "^11.0.0" + } + }, + "node_modules/mongoose": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.0.4.tgz", + "integrity": "sha512-wN9qvdevX3+922VnLT7CpaZRT3jmVCBOK2QMHMGeScQxDRnFMPpkuI9StEPpZo/3x8t+kbzH7F8RMPsyNwyM4w==", + "dependencies": { + "bson": "^6.2.0", + "kareem": "2.5.1", + "mongodb": "6.2.0", + "mpath": "0.9.0", + "mquery": "5.0.0", + "ms": "2.1.3", + "sift": "16.0.1" + }, + "engines": { + "node": ">=16.20.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mongoose" + } + }, + "node_modules/mongoose/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mquery": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", + "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", + "dependencies": { + "debug": "4.x" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/napi-macros": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.2.2.tgz", + "integrity": "sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g==" + }, + "node_modules/node-gyp-build": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.0.tgz", + "integrity": "sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/pg": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz", + "integrity": "sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==", + "dependencies": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "^2.6.2", + "pg-pool": "^3.6.1", + "pg-protocol": "^1.6.0", + "pg-types": "^2.1.0", + "pgpass": "1.x" + }, + "engines": { + "node": ">= 8.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.1.1" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-cloudflare": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", + "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", + "optional": true + }, + "node_modules/pg-connection-string": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", + "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz", + "integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", + "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "dependencies": { + "split2": "^4.1.0" + } + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/prompt-sync": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/prompt-sync/-/prompt-sync-4.2.0.tgz", + "integrity": "sha512-BuEzzc5zptP5LsgV5MZETjDaKSWfchl5U9Luiu8SKp7iZWD5tZalOxvNcZRwv+d2phNFr8xlbxmFNcRKfJOzJw==", + "dependencies": { + "strip-ansi": "^5.0.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/run-parallel-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", + "integrity": "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/sift": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.1.tgz", + "integrity": "sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ==" + }, + "node_modules/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "dependencies": { + "memory-pager": "^1.0.2" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tarn": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.2.tgz", + "integrity": "sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/tildify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tildify/-/tildify-2.0.0.tgz", + "integrity": "sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.0.tgz", + "integrity": "sha512-I+t79RYPlEYlHn9a+KzwrvEwhJg35h/1zHsLC2JXvhC2mdynMv6Zxzvhv5EMV6VF5qJlLlkSnMVvdZV3PSIGcg==", + "dev": true, + "dependencies": { + "esbuild": "~0.19.10", + "get-tsconfig": "^4.7.2" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/zod": { + "version": "3.22.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", + "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/pg-migrator/package.json b/pg-migrator/package.json new file mode 100644 index 000000000..9ffa16086 --- /dev/null +++ b/pg-migrator/package.json @@ -0,0 +1,26 @@ +{ + "name": "pg-migrator", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "migration": "tsx src/index.ts" + }, + "author": "", + "license": "ISC", + "devDependencies": { + "@types/node": "^20.11.0", + "@types/prompt-sync": "^4.2.3", + "tsx": "^4.7.0", + "typescript": "^5.3.3" + }, + "dependencies": { + "dotenv": "^16.3.1", + "knex": "^3.1.0", + "level": "^8.0.0", + "mongoose": "^8.0.4", + "pg": "^8.11.3", + "prompt-sync": "^4.2.0", + "zod": "^3.22.4" + } +} diff --git a/pg-migrator/src/.gitignore b/pg-migrator/src/.gitignore new file mode 100644 index 000000000..65eef93d6 --- /dev/null +++ b/pg-migrator/src/.gitignore @@ -0,0 +1 @@ +db diff --git a/pg-migrator/src/@types/knex.d.ts b/pg-migrator/src/@types/knex.d.ts new file mode 100644 index 000000000..10a9162f7 --- /dev/null +++ b/pg-migrator/src/@types/knex.d.ts @@ -0,0 +1,443 @@ +import { Knex } from "knex"; + +import { + TableName, + TApiKeys, + TApiKeysInsert, + TApiKeysUpdate, + TAuditLogs, + TAuditLogsInsert, + TAuditLogsUpdate, + TAuthTokens, + TAuthTokenSessions, + TAuthTokenSessionsInsert, + TAuthTokenSessionsUpdate, + TAuthTokensUpdate, + TBackupPrivateKey, + TBackupPrivateKeyInsert, + TBackupPrivateKeyUpdate, + TGitAppInstallSessions, + TGitAppInstallSessionsInsert, + TGitAppInstallSessionsUpdate, + TGitAppOrg, + TGitAppOrgInsert, + TGitAppOrgUpdate, + TIdentities, + TIdentitiesInsert, + TIdentitiesUpdate, + TIdentityAccessTokens, + TIdentityAccessTokensInsert, + TIdentityAccessTokensUpdate, + TIdentityOrgMemberships, + TIdentityOrgMembershipsInsert, + TIdentityOrgMembershipsUpdate, + TIdentityProjectMemberships, + TIdentityProjectMembershipsInsert, + TIdentityProjectMembershipsUpdate, + TIdentityUaClientSecrets, + TIdentityUaClientSecretsInsert, + TIdentityUaClientSecretsUpdate, + TIdentityUniversalAuths, + TIdentityUniversalAuthsInsert, + TIdentityUniversalAuthsUpdate, + TIncidentContacts, + TIncidentContactsInsert, + TIncidentContactsUpdate, + TIntegrationAuths, + TIntegrationAuthsInsert, + TIntegrationAuthsUpdate, + TIntegrations, + TIntegrationsInsert, + TIntegrationsUpdate, + TOrganizations, + TOrganizationsInsert, + TOrganizationsUpdate, + TOrgBots, + TOrgBotsInsert, + TOrgBotsUpdate, + TOrgMemberships, + TOrgMembershipsInsert, + TOrgMembershipsUpdate, + TOrgRoles, + TOrgRolesInsert, + TOrgRolesUpdate, + TProjectBots, + TProjectBotsInsert, + TProjectBotsUpdate, + TProjectEnvironments, + TProjectEnvironmentsInsert, + TProjectEnvironmentsUpdate, + TProjectKeys, + TProjectKeysInsert, + TProjectKeysUpdate, + TProjectMemberships, + TProjectMembershipsInsert, + TProjectMembershipsUpdate, + TProjectRoles, + TProjectRolesInsert, + TProjectRolesUpdate, + TProjects, + TProjectsInsert, + TProjectsUpdate, + TSamlConfigs, + TSamlConfigsInsert, + TSamlConfigsUpdate, + TSapApprovers, + TSapApproversInsert, + TSapApproversUpdate, + TSaRequestSecrets, + TSaRequestSecretsInsert, + TSaRequestSecretsUpdate, + TSaRequestSecretTags, + TSaRequestSecretTagsInsert, + TSaRequestSecretTagsUpdate, + TSarReviewers, + TSarReviewersInsert, + TSarReviewersUpdate, + TSecretApprovalPolicies, + TSecretApprovalPoliciesInsert, + TSecretApprovalPoliciesUpdate, + TSecretApprovalRequests, + TSecretApprovalRequestsInsert, + TSecretApprovalRequestsUpdate, + TSecretBlindIndexes, + TSecretBlindIndexesInsert, + TSecretBlindIndexesUpdate, + TSecretFolders, + TSecretFoldersInsert, + TSecretFoldersUpdate, + TSecretFolderVersions, + TSecretFolderVersionsInsert, + TSecretFolderVersionsUpdate, + TSecretImports, + TSecretImportsInsert, + TSecretImportsUpdate, + TSecretRotationOutputs, + TSecretRotationOutputsInsert, + TSecretRotationOutputsUpdate, + TSecretRotations, + TSecretRotationsInsert, + TSecretRotationsUpdate, + TSecrets, + TSecretScanningGitRisks, + TSecretScanningGitRisksInsert, + TSecretScanningGitRisksUpdate, + TSecretsInsert, + TSecretSnapshotFolders, + TSecretSnapshotFoldersInsert, + TSecretSnapshotFoldersUpdate, + TSecretSnapshots, + TSecretSnapshotSecrets, + TSecretSnapshotSecretsInsert, + TSecretSnapshotSecretsUpdate, + TSecretSnapshotsInsert, + TSecretSnapshotsUpdate, + TSecretsUpdate, + TSecretTagJunction, + TSecretTagJunctionInsert, + TSecretTagJunctionUpdate, + TSecretTags, + TSecretTagsInsert, + TSecretTagsUpdate, + TSecretVersions, + TSecretVersionsInsert, + TSecretVersionsUpdate, + TServiceTokens, + TServiceTokensInsert, + TServiceTokensUpdate, + TSuperAdmin, + TSuperAdminInsert, + TSuperAdminUpdate, + TTrustedIps, + TTrustedIpsInsert, + TTrustedIpsUpdate, + TUserActions, + TUserActionsInsert, + TUserActionsUpdate, + TUserEncryptionKeys, + TUserEncryptionKeysInsert, + TUserEncryptionKeysUpdate, + TUsers, + TUsersInsert, + TUsersUpdate, + TWebhooks, + TWebhooksInsert, + TWebhooksUpdate, + TAuthTokensInsert, +} from "../schemas"; + +declare module "knex/types/tables" { + interface Tables { + [TableName.Users]: Knex.CompositeTableType< + TUsers, + TUsersInsert, + TUsersUpdate + >; + [TableName.UserEncryptionKey]: Knex.CompositeTableType< + TUserEncryptionKeys, + TUserEncryptionKeysInsert, + TUserEncryptionKeysUpdate + >; + [TableName.AuthTokens]: Knex.CompositeTableType< + TAuthTokens, + TAuthTokensInsert, + TAuthTokensUpdate + >; + [TableName.AuthTokenSession]: Knex.CompositeTableType< + TAuthTokenSessions, + TAuthTokenSessionsInsert, + TAuthTokenSessionsUpdate + >; + [TableName.BackupPrivateKey]: Knex.CompositeTableType< + TBackupPrivateKey, + TBackupPrivateKeyInsert, + TBackupPrivateKeyUpdate + >; + [TableName.Organization]: Knex.CompositeTableType< + TOrganizations, + TOrganizationsInsert, + TOrganizationsUpdate + >; + [TableName.OrgMembership]: Knex.CompositeTableType< + TOrgMemberships, + TOrgMembershipsInsert, + TOrgMembershipsUpdate + >; + [TableName.OrgRoles]: Knex.CompositeTableType< + TOrgRoles, + TOrgRolesInsert, + TOrgRolesUpdate + >; + [TableName.IncidentContact]: Knex.CompositeTableType< + TIncidentContacts, + TIncidentContactsInsert, + TIncidentContactsUpdate + >; + [TableName.UserAction]: Knex.CompositeTableType< + TUserActions, + TUserActionsInsert, + TUserActionsUpdate + >; + [TableName.SuperAdmin]: Knex.CompositeTableType< + TSuperAdmin, + TSuperAdminInsert, + TSuperAdminUpdate + >; + [TableName.ApiKey]: Knex.CompositeTableType< + TApiKeys, + TApiKeysInsert, + TApiKeysUpdate + >; + [TableName.Project]: Knex.CompositeTableType< + TProjects, + TProjectsInsert, + TProjectsUpdate + >; + [TableName.ProjectMembership]: Knex.CompositeTableType< + TProjectMemberships, + TProjectMembershipsInsert, + TProjectMembershipsUpdate + >; + [TableName.Environment]: Knex.CompositeTableType< + TProjectEnvironments, + TProjectEnvironmentsInsert, + TProjectEnvironmentsUpdate + >; + [TableName.ProjectBot]: Knex.CompositeTableType< + TProjectBots, + TProjectBotsInsert, + TProjectBotsUpdate + >; + [TableName.ProjectRoles]: Knex.CompositeTableType< + TProjectRoles, + TProjectRolesInsert, + TProjectRolesUpdate + >; + [TableName.ProjectKeys]: Knex.CompositeTableType< + TProjectKeys, + TProjectKeysInsert, + TProjectKeysUpdate + >; + [TableName.Secret]: Knex.CompositeTableType< + TSecrets, + TSecretsInsert, + TSecretsUpdate + >; + [TableName.SecretBlindIndex]: Knex.CompositeTableType< + TSecretBlindIndexes, + TSecretBlindIndexesInsert, + TSecretBlindIndexesUpdate + >; + [TableName.SecretVersion]: Knex.CompositeTableType< + TSecretVersions, + TSecretVersionsInsert, + TSecretVersionsUpdate + >; + [TableName.SecretFolder]: Knex.CompositeTableType< + TSecretFolders, + TSecretFoldersInsert, + TSecretFoldersUpdate + >; + [TableName.SecretFolderVersion]: Knex.CompositeTableType< + TSecretFolderVersions, + TSecretFolderVersionsInsert, + TSecretFolderVersionsUpdate + >; + [TableName.SecretTag]: Knex.CompositeTableType< + TSecretTags, + TSecretTagsInsert, + TSecretTagsUpdate + >; + [TableName.SecretImport]: Knex.CompositeTableType< + TSecretImports, + TSecretImportsInsert, + TSecretImportsUpdate + >; + [TableName.Integration]: Knex.CompositeTableType< + TIntegrations, + TIntegrationsInsert, + TIntegrationsUpdate + >; + [TableName.Webhook]: Knex.CompositeTableType< + TWebhooks, + TWebhooksInsert, + TWebhooksUpdate + >; + [TableName.ServiceToken]: Knex.CompositeTableType< + TServiceTokens, + TServiceTokensInsert, + TServiceTokensUpdate + >; + [TableName.IntegrationAuth]: Knex.CompositeTableType< + TIntegrationAuths, + TIntegrationAuthsInsert, + TIntegrationAuthsUpdate + >; + [TableName.Identity]: Knex.CompositeTableType< + TIdentities, + TIdentitiesInsert, + TIdentitiesUpdate + >; + [TableName.IdentityUniversalAuth]: Knex.CompositeTableType< + TIdentityUniversalAuths, + TIdentityUniversalAuthsInsert, + TIdentityUniversalAuthsUpdate + >; + [TableName.IdentityUaClientSecret]: Knex.CompositeTableType< + TIdentityUaClientSecrets, + TIdentityUaClientSecretsInsert, + TIdentityUaClientSecretsUpdate + >; + [TableName.IdentityAccessToken]: Knex.CompositeTableType< + TIdentityAccessTokens, + TIdentityAccessTokensInsert, + TIdentityAccessTokensUpdate + >; + [TableName.IdentityOrgMembership]: Knex.CompositeTableType< + TIdentityOrgMemberships, + TIdentityOrgMembershipsInsert, + TIdentityOrgMembershipsUpdate + >; + [TableName.IdentityProjectMembership]: Knex.CompositeTableType< + TIdentityProjectMemberships, + TIdentityProjectMembershipsInsert, + TIdentityProjectMembershipsUpdate + >; + [TableName.SecretApprovalPolicy]: Knex.CompositeTableType< + TSecretApprovalPolicies, + TSecretApprovalPoliciesInsert, + TSecretApprovalPoliciesUpdate + >; + [TableName.SapApprover]: Knex.CompositeTableType< + TSapApprovers, + TSapApproversInsert, + TSapApproversUpdate + >; + [TableName.SecretApprovalRequest]: Knex.CompositeTableType< + TSecretApprovalRequests, + TSecretApprovalRequestsInsert, + TSecretApprovalRequestsUpdate + >; + [TableName.SarReviewer]: Knex.CompositeTableType< + TSarReviewers, + TSarReviewersInsert, + TSarReviewersUpdate + >; + [TableName.SarSecret]: Knex.CompositeTableType< + TSaRequestSecrets, + TSaRequestSecretsInsert, + TSaRequestSecretsUpdate + >; + [TableName.SarSecretTag]: Knex.CompositeTableType< + TSaRequestSecretTags, + TSaRequestSecretTagsInsert, + TSaRequestSecretTagsUpdate + >; + [TableName.SecretRotation]: Knex.CompositeTableType< + TSecretRotations, + TSecretRotationsInsert, + TSecretRotationsUpdate + >; + [TableName.SecretRotationOutput]: Knex.CompositeTableType< + TSecretRotationOutputs, + TSecretRotationOutputsInsert, + TSecretRotationOutputsUpdate + >; + [TableName.Snapshot]: Knex.CompositeTableType< + TSecretSnapshots, + TSecretSnapshotsInsert, + TSecretSnapshotsUpdate + >; + [TableName.SnapshotSecret]: Knex.CompositeTableType< + TSecretSnapshotSecrets, + TSecretSnapshotSecretsInsert, + TSecretSnapshotSecretsUpdate + >; + [TableName.SnapshotFolder]: Knex.CompositeTableType< + TSecretSnapshotFolders, + TSecretSnapshotFoldersInsert, + TSecretSnapshotFoldersUpdate + >; + [TableName.SamlConfig]: Knex.CompositeTableType< + TSamlConfigs, + TSamlConfigsInsert, + TSamlConfigsUpdate + >; + [TableName.OrgBot]: Knex.CompositeTableType< + TOrgBots, + TOrgBotsInsert, + TOrgBotsUpdate + >; + [TableName.AuditLog]: Knex.CompositeTableType< + TAuditLogs, + TAuditLogsInsert, + TAuditLogsUpdate + >; + [TableName.GitAppInstallSession]: Knex.CompositeTableType< + TGitAppInstallSessions, + TGitAppInstallSessionsInsert, + TGitAppInstallSessionsUpdate + >; + [TableName.GitAppOrg]: Knex.CompositeTableType< + TGitAppOrg, + TGitAppOrgInsert, + TGitAppOrgUpdate + >; + [TableName.SecretScanningGitRisk]: Knex.CompositeTableType< + TSecretScanningGitRisks, + TSecretScanningGitRisksInsert, + TSecretScanningGitRisksUpdate + >; + [TableName.TrustedIps]: Knex.CompositeTableType< + TTrustedIps, + TTrustedIpsInsert, + TTrustedIpsUpdate + >; + // Junction tables + [TableName.JnSecretTag]: Knex.CompositeTableType< + TSecretTagJunction, + TSecretTagJunctionInsert, + TSecretTagJunctionUpdate + >; + } +} diff --git a/pg-migrator/src/index.ts b/pg-migrator/src/index.ts new file mode 100644 index 000000000..2f402eeba --- /dev/null +++ b/pg-migrator/src/index.ts @@ -0,0 +1,80 @@ +import promptSync from "prompt-sync"; +import mongoose from "mongoose"; +import dotenv from "dotenv"; +import knex from "knex"; +import path from "path"; +import { Level } from "level"; +import { IUser, User } from "./models"; +import { TUsers, TUsersInsert, TableName } from "./schemas"; + +const kdb = new Level("./db", { valueEncoding: "json" }); + +const main = async () => { + try { + dotenv.config(); + const prompt = promptSync({ sigint: true }); + + let mongodb_url = process.env.MONGO_DB_URL; + if (!mongodb_url) { + mongodb_url = prompt("Type the mongodb url: "); + } + console.log("Checking mongoose connection..."); + await mongoose.connect(mongodb_url); + console.log("Connected successfully to mongo"); + + let postgres_url = process.env.POSTGRES_DB_URL; + if (!postgres_url) { + postgres_url = prompt("Type the mongodb url: "); + } + + console.log("Checking postgres connection..."); + const db = knex({ + client: "pg", + connection: postgres_url, + migrations: { + directory: path.join(__dirname, "./migrations"), + extension: "ts", + tableName: "infisical_migrations", + }, + }); + console.log("Connected successfully to postgres"); + await db.raw("select 1+1 as result"); + + console.log("Executing migration"); + await db.migrate.latest(); + + console.log("Starting to insert users"); + const users: IUser[] = []; + const newUsers: TUsersInsert[] = []; + for await (const doc of User.find().cursor({ batchSize: 100 })) { + users.push(doc); + newUsers.push({ + firstName: doc.firstName, + email: doc.email, + devices: doc.devices, + lastName: doc.lastName, + isAccepted: Boolean(doc.publicKey), + superAdmin: doc.superAdmin, + authMethods: doc.authMethods, + isMfaEnabled: doc.isMfaEnabled, + }); + if (users.length >= 1000) { + const newUserIds = await db.transaction(async (tx) => { + return await tx + .batchInsert(TableName.Users, newUsers) + .returning("id"); + }); + console.log(newUserIds.length); + users.slice(0, users.length); + newUsers.slice(0, newUsers.length); + } + } + + process.exit(1); + } catch (error) { + console.error(error); + process.exit(1); + } +}; + +main(); diff --git a/pg-migrator/src/migrations/20231128072457_user.ts b/pg-migrator/src/migrations/20231128072457_user.ts new file mode 100644 index 000000000..f0572824e --- /dev/null +++ b/pg-migrator/src/migrations/20231128072457_user.ts @@ -0,0 +1,37 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { + createOnUpdateTrigger, + createUpdateAtTriggerFunction, + dropOnUpdateTrigger, + dropUpdatedAtTriggerFunction +} from "../utils"; + +export async function up(knex: Knex): Promise { + const isTablePresent = await knex.schema.hasTable(TableName.Users); + if (!isTablePresent) { + await knex.schema.createTable(TableName.Users, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("email").notNullable(); + t.specificType("authMethods", "text[]"); + t.boolean("superAdmin").defaultTo(false); + t.string("firstName"); + t.string("lastName"); + t.boolean("isAccepted").defaultTo(false); + t.boolean("isMfaEnabled").defaultTo(false); + t.specificType("mfaMethods", "text[]"); + t.jsonb("devices"); + t.timestamps(true, true, true); + }); + } + // this is a one time function + await createUpdateAtTriggerFunction(knex); + await createOnUpdateTrigger(knex, TableName.Users); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.Users); + await dropOnUpdateTrigger(knex, TableName.Users); + await dropUpdatedAtTriggerFunction(knex); +} diff --git a/pg-migrator/src/migrations/20231128092347_user-encryption-key.ts b/pg-migrator/src/migrations/20231128092347_user-encryption-key.ts new file mode 100644 index 000000000..5cf251865 --- /dev/null +++ b/pg-migrator/src/migrations/20231128092347_user-encryption-key.ts @@ -0,0 +1,31 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; + +export async function up(knex: Knex): Promise { + const isTablePresent = await knex.schema.hasTable(TableName.UserEncryptionKey); + if (!isTablePresent) { + await knex.schema.createTable(TableName.UserEncryptionKey, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.text("clientPublicKey"); + t.text("serverPrivateKey"); + t.integer("encryptionVersion").defaultTo(2); + t.text("protectedKey").notNullable(); + t.text("protectedKeyIV").notNullable(); + t.text("protectedKeyTag").notNullable(); + t.text("publicKey").notNullable(); + t.text("encryptedPrivateKey").notNullable(); + t.text("iv").notNullable(); + t.text("tag").notNullable(); + t.text("salt").notNullable(); + t.text("verifier").notNullable(); + // one to one relationship + t.uuid("userId").notNullable().unique(); + t.foreign("userId").references("id").inTable(TableName.Users).onDelete("CASCADE"); + }); + } +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.UserEncryptionKey); +} diff --git a/pg-migrator/src/migrations/20231129072939_auth-token.ts b/pg-migrator/src/migrations/20231129072939_auth-token.ts new file mode 100644 index 000000000..ed23ebe9d --- /dev/null +++ b/pg-migrator/src/migrations/20231129072939_auth-token.ts @@ -0,0 +1,25 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; + +export async function up(knex: Knex): Promise { + const isTablePresent = await knex.schema.hasTable(TableName.AuthTokens); + if (!isTablePresent) { + await knex.schema.createTable(TableName.AuthTokens, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("type").notNullable(); + t.string("phoneNumber"); + t.string("tokenHash").notNullable(); + t.integer("triesLeft"); + t.datetime("expiresAt").notNullable(); + // does not need update trigger we will do it manually + t.timestamps(true, true, true); + t.uuid("userId"); + t.foreign("userId").references("id").inTable(TableName.Users).onDelete("CASCADE"); + }); + } +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.AuthTokens); +} diff --git a/pg-migrator/src/migrations/20231130072734_auth-token-session.ts b/pg-migrator/src/migrations/20231130072734_auth-token-session.ts new file mode 100644 index 000000000..9d5b98910 --- /dev/null +++ b/pg-migrator/src/migrations/20231130072734_auth-token-session.ts @@ -0,0 +1,29 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + const isTablePresent = await knex.schema.hasTable(TableName.AuthTokenSession); + if (!isTablePresent) { + await knex.schema.createTable(TableName.AuthTokenSession, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("ip").notNullable(); + t.string("userAgent"); + t.integer("refreshVersion").notNullable().defaultTo(1); + t.integer("accessVersion").notNullable().defaultTo(1); + t.datetime("lastUsed").notNullable(); + // does not need update trigger we will do it manually + t.timestamps(true, true, true); + t.uuid("userId").notNullable(); + t.foreign("userId").references("id").inTable(TableName.Users).onDelete("CASCADE"); + }); + } + // this is a one time function + await createOnUpdateTrigger(knex, TableName.AuthTokenSession); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.AuthTokenSession); + await dropOnUpdateTrigger(knex, TableName.AuthTokenSession); +} diff --git a/pg-migrator/src/migrations/20231201151432_backup-key.ts b/pg-migrator/src/migrations/20231201151432_backup-key.ts new file mode 100644 index 000000000..0c5dd2286 --- /dev/null +++ b/pg-migrator/src/migrations/20231201151432_backup-key.ts @@ -0,0 +1,26 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; + +export async function up(knex: Knex): Promise { + const doesTableExist = await knex.schema.hasTable(TableName.BackupPrivateKey); + if (!doesTableExist) { + await knex.schema.createTable(TableName.BackupPrivateKey, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.text("encryptedPrivateKey").notNullable(); + t.text("iv").notNullable(); + t.text("tag").notNullable(); + t.string("algorithm").notNullable(); + t.string("keyEncoding").notNullable(); + t.text("salt").notNullable(); + t.text("verifier").notNullable(); + t.timestamps(true, true, true); + t.uuid("userId").notNullable().unique(); + t.foreign("userId").references("id").inTable(TableName.Users).onDelete("CASCADE"); + }); + } +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.BackupPrivateKey); +} diff --git a/pg-migrator/src/migrations/20231204092737_organization.ts b/pg-migrator/src/migrations/20231204092737_organization.ts new file mode 100644 index 000000000..cc03babb2 --- /dev/null +++ b/pg-migrator/src/migrations/20231204092737_organization.ts @@ -0,0 +1,33 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + const isTablePresent = await knex.schema.hasTable(TableName.Organization); + if (!isTablePresent) { + await knex.schema.createTable(TableName.Organization, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("name").notNullable(); + t.string("customerId"); + // does not need update trigger we will do it manually + t.timestamps(true, true, true); + }); + await knex.schema.alterTable(TableName.AuthTokens, (t) => { + t.uuid("orgId"); + t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE"); + }); + } + // this is a one time function + await createOnUpdateTrigger(knex, TableName.Organization); +} + +export async function down(knex: Knex): Promise { + if (await knex.schema.hasColumn(TableName.AuthTokens, "orgId")) { + await knex.schema.alterTable(TableName.AuthTokens, (t) => { + t.dropColumn("orgId"); + }); + } + await knex.schema.dropTableIfExists(TableName.Organization); + await dropOnUpdateTrigger(knex, TableName.Organization); +} diff --git a/pg-migrator/src/migrations/20231204092747_org-membership.ts b/pg-migrator/src/migrations/20231204092747_org-membership.ts new file mode 100644 index 000000000..2b166d3e5 --- /dev/null +++ b/pg-migrator/src/migrations/20231204092747_org-membership.ts @@ -0,0 +1,48 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { OrgMembershipStatus } from "../schemas/models"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + const isOrgRolePresent = await knex.schema.hasTable(TableName.OrgRoles); + if (!isOrgRolePresent) { + await knex.schema.createTable(TableName.OrgRoles, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("name").notNullable(); + t.string("description"); + t.string("slug").notNullable(); + t.jsonb("permissions").notNullable(); + // does not need update trigger we will do it manually + t.timestamps(true, true, true); + t.uuid("orgId").notNullable(); + t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE"); + }); + } + + const isOrgTablePresent = await knex.schema.hasTable(TableName.OrgMembership); + if (!isOrgTablePresent) { + await knex.schema.createTable(TableName.OrgMembership, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("role").notNullable(); + t.string("status").notNullable().defaultTo(OrgMembershipStatus.Invited); + t.string("inviteEmail"); + // does not need update trigger we will do it manually + t.timestamps(true, true, true); + t.uuid("userId"); + t.foreign("userId").references("id").inTable(TableName.Users).onDelete("CASCADE"); + t.uuid("orgId").notNullable(); + t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE"); + t.uuid("roleId"); + t.foreign("roleId").references("id").inTable(TableName.OrgRoles); + }); + } + // this is a one time function + await createOnUpdateTrigger(knex, TableName.OrgMembership); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.OrgMembership); + await knex.schema.dropTableIfExists(TableName.OrgRoles); + await dropOnUpdateTrigger(knex, TableName.OrgMembership); +} diff --git a/pg-migrator/src/migrations/20231205151331_incident-contact.ts b/pg-migrator/src/migrations/20231205151331_incident-contact.ts new file mode 100644 index 000000000..a0c1a3c27 --- /dev/null +++ b/pg-migrator/src/migrations/20231205151331_incident-contact.ts @@ -0,0 +1,25 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + const isTablePresent = await knex.schema.hasTable(TableName.IncidentContact); + if (!isTablePresent) { + await knex.schema.createTable(TableName.IncidentContact, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("email").notNullable(); + // does not need update trigger we will do it manually + t.timestamps(true, true, true); + t.uuid("orgId").notNullable(); + t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE"); + }); + } + // this is a one time function + await createOnUpdateTrigger(knex, TableName.IncidentContact); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.IncidentContact); + await dropOnUpdateTrigger(knex, TableName.IncidentContact); +} diff --git a/pg-migrator/src/migrations/20231207055643_user-action.ts b/pg-migrator/src/migrations/20231207055643_user-action.ts new file mode 100644 index 000000000..c3b54839c --- /dev/null +++ b/pg-migrator/src/migrations/20231207055643_user-action.ts @@ -0,0 +1,20 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; + +export async function up(knex: Knex): Promise { + const isTablePresent = await knex.schema.hasTable(TableName.UserAction); + if (!isTablePresent) { + await knex.schema.createTable(TableName.UserAction, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("action").notNullable(); + t.timestamps(true, true, true); + t.uuid("userId").notNullable(); + t.foreign("userId").references("id").inTable(TableName.Users).onDelete("CASCADE"); + }); + } +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.UserAction); +} diff --git a/pg-migrator/src/migrations/20231207055701_super-admin.ts b/pg-migrator/src/migrations/20231207055701_super-admin.ts new file mode 100644 index 000000000..6d5f7f32d --- /dev/null +++ b/pg-migrator/src/migrations/20231207055701_super-admin.ts @@ -0,0 +1,23 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + const isTablePresent = await knex.schema.hasTable(TableName.SuperAdmin); + if (!isTablePresent) { + await knex.schema.createTable(TableName.SuperAdmin, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.boolean("initialized").defaultTo(false); + t.boolean("allowSignUp").defaultTo(true); + t.timestamps(true, true, true); + }); + } + // this is a one time function + await createOnUpdateTrigger(knex, TableName.SuperAdmin); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.SuperAdmin); + await dropOnUpdateTrigger(knex, TableName.SuperAdmin); +} diff --git a/pg-migrator/src/migrations/20231207105059_api-key.ts b/pg-migrator/src/migrations/20231207105059_api-key.ts new file mode 100644 index 000000000..4758973da --- /dev/null +++ b/pg-migrator/src/migrations/20231207105059_api-key.ts @@ -0,0 +1,26 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + const isTablePresent = await knex.schema.hasTable(TableName.ApiKey); + if (!isTablePresent) { + await knex.schema.createTable(TableName.ApiKey, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("name").notNullable(); + t.datetime("lastUsed"); + t.datetime("expiresAt"); + t.string("secretHash").notNullable(); + t.timestamps(true, true, true); + t.uuid("userId").notNullable(); + t.foreign("userId").references("id").inTable(TableName.Users).onDelete("CASCADE"); + }); + } + await createOnUpdateTrigger(knex, TableName.ApiKey); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.ApiKey); + await dropOnUpdateTrigger(knex, TableName.ApiKey); +} diff --git a/pg-migrator/src/migrations/20231212110939_project.ts b/pg-migrator/src/migrations/20231212110939_project.ts new file mode 100644 index 000000000..732c80c10 --- /dev/null +++ b/pg-migrator/src/migrations/20231212110939_project.ts @@ -0,0 +1,60 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasTable(TableName.Project))) { + await knex.schema.createTable(TableName.Project, (t) => { + t.string("id", 36).primary().defaultTo(knex.fn.uuid()); + t.string("name").notNullable(); + t.boolean("autoCapitalization").defaultTo(true); + t.uuid("orgId").notNullable(); + t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE"); + t.timestamps(true, true, true); + }); + } + await createOnUpdateTrigger(knex, TableName.Project); + // environments + if (!(await knex.schema.hasTable(TableName.Environment))) { + await knex.schema.createTable(TableName.Environment, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("name").notNullable(); + t.string("slug").notNullable(); + t.integer("position").notNullable(); + t.string("projectId").notNullable(); + t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE"); + // this will ensure ever env has its position + t.unique(["projectId", "position"], { + indexName: "env_pos_composite_uniqe", + deferrable: "deferred" + }); + t.timestamps(true, true, true); + }); + } + // project key + if (!(await knex.schema.hasTable(TableName.ProjectKeys))) { + await knex.schema.createTable(TableName.ProjectKeys, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.text("encryptedKey").notNullable(); + t.text("nonce").notNullable(); + t.uuid("receiverId").notNullable(); + t.foreign("receiverId").references("id").inTable(TableName.Users).onDelete("CASCADE"); + t.uuid("senderId"); + // if sender is deleted just don't do anything to this record + t.foreign("senderId").references("id").inTable(TableName.Users).onDelete("SET NULL"); + t.string("projectId").notNullable(); + t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE"); + t.timestamps(true, true, true); + }); + } + await createOnUpdateTrigger(knex, TableName.ProjectKeys); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.Environment); + await knex.schema.dropTableIfExists(TableName.ProjectKeys); + await knex.schema.dropTableIfExists(TableName.Project); + await dropOnUpdateTrigger(knex, TableName.ProjectKeys); + await dropOnUpdateTrigger(knex, TableName.Project); +} diff --git a/pg-migrator/src/migrations/20231212110946_project-membership.ts b/pg-migrator/src/migrations/20231212110946_project-membership.ts new file mode 100644 index 000000000..ad7cdb8a5 --- /dev/null +++ b/pg-migrator/src/migrations/20231212110946_project-membership.ts @@ -0,0 +1,43 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasTable(TableName.ProjectRoles))) { + await knex.schema.createTable(TableName.ProjectRoles, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("name").notNullable(); + t.string("description"); + t.string("slug").notNullable(); + t.jsonb("permissions").notNullable(); + // does not need update trigger we will do it manually + t.timestamps(true, true, true); + t.string("projectId").notNullable(); + t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE"); + }); + } + + if (!(await knex.schema.hasTable(TableName.ProjectMembership))) { + await knex.schema.createTable(TableName.ProjectMembership, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("role").notNullable(); + // does not need update trigger we will do it manually + t.timestamps(true, true, true); + t.uuid("userId").notNullable(); + t.foreign("userId").references("id").inTable(TableName.Users).onDelete("CASCADE"); + t.string("projectId").notNullable(); + t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE"); + // until role is changed/removed the role should not deleted + t.uuid("roleId"); + t.foreign("roleId").references("id").inTable(TableName.ProjectRoles); + }); + } + await createOnUpdateTrigger(knex, TableName.ProjectMembership); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.ProjectMembership); + await knex.schema.dropTableIfExists(TableName.ProjectRoles); + await dropOnUpdateTrigger(knex, TableName.ProjectMembership); +} diff --git a/pg-migrator/src/migrations/20231218092441_secret-folder.ts b/pg-migrator/src/migrations/20231218092441_secret-folder.ts new file mode 100644 index 000000000..ba67e295b --- /dev/null +++ b/pg-migrator/src/migrations/20231218092441_secret-folder.ts @@ -0,0 +1,42 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasTable(TableName.SecretFolder))) { + await knex.schema.createTable(TableName.SecretFolder, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("name").notNullable(); + t.integer("version").defaultTo(1); + t.timestamps(true, true, true); + t.uuid("envId").notNullable(); + t.foreign("envId").references("id").inTable(TableName.Environment).onDelete("CASCADE"); + t.uuid("parentId"); + t.foreign("parentId").references("id").inTable(TableName.SecretFolder).onDelete("CASCADE"); + }); + } + await createOnUpdateTrigger(knex, TableName.SecretFolder); + + if (!(await knex.schema.hasTable(TableName.SecretFolderVersion))) { + await knex.schema.createTable(TableName.SecretFolderVersion, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("name").notNullable(); + t.integer("version").defaultTo(1); + t.timestamps(true, true, true); + t.uuid("envId").notNullable(); + t.foreign("envId").references("id").inTable(TableName.Environment).onDelete("CASCADE"); + t.uuid("folderId").notNullable(); + // t.foreign("folderId").references("id").inTable(TableName.SecretFolder).onDelete("SET NULL"); + }); + } + + await createOnUpdateTrigger(knex, TableName.SecretFolderVersion); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.SecretFolderVersion); + await knex.schema.dropTableIfExists(TableName.SecretFolder); + await dropOnUpdateTrigger(knex, TableName.SecretFolder); + await dropOnUpdateTrigger(knex, TableName.SecretFolderVersion); +} diff --git a/pg-migrator/src/migrations/20231218092508_secret-import.ts b/pg-migrator/src/migrations/20231218092508_secret-import.ts new file mode 100644 index 000000000..12aa80c74 --- /dev/null +++ b/pg-migrator/src/migrations/20231218092508_secret-import.ts @@ -0,0 +1,30 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasTable(TableName.SecretImport))) { + await knex.schema.createTable(TableName.SecretImport, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.integer("version").defaultTo(1); + t.string("importPath").notNullable(); + t.uuid("importEnv").notNullable(); + t.foreign("importEnv").references("id").inTable(TableName.Environment).onDelete("CASCADE"); + t.integer("position").notNullable(); + t.timestamps(true, true, true); + t.uuid("folderId").notNullable(); + t.foreign("folderId").references("id").inTable(TableName.SecretFolder).onDelete("CASCADE"); + t.unique(["folderId", "position"], { + indexName: "import_pos_composite_uniqe", + deferrable: "deferred" + }); + }); + } + await createOnUpdateTrigger(knex, TableName.SecretImport); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.SecretImport); + await dropOnUpdateTrigger(knex, TableName.SecretImport); +} diff --git a/pg-migrator/src/migrations/20231218092517_secret-tag.ts b/pg-migrator/src/migrations/20231218092517_secret-tag.ts new file mode 100644 index 000000000..051f39d76 --- /dev/null +++ b/pg-migrator/src/migrations/20231218092517_secret-tag.ts @@ -0,0 +1,26 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasTable(TableName.SecretTag))) { + await knex.schema.createTable(TableName.SecretTag, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("name").notNullable(); + t.string("slug").notNullable(); + t.string("color"); + t.timestamps(true, true, true); + t.uuid("createdBy"); + t.foreign("createdBy").references("id").inTable(TableName.Users).onDelete("SET NULL"); + t.string("projectId").notNullable(); + t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE"); + }); + } + await createOnUpdateTrigger(knex, TableName.SecretTag); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.SecretTag); + await dropOnUpdateTrigger(knex, TableName.SecretTag); +} diff --git a/pg-migrator/src/migrations/20231218103423_secret.ts b/pg-migrator/src/migrations/20231218103423_secret.ts new file mode 100644 index 000000000..a29dccfc8 --- /dev/null +++ b/pg-migrator/src/migrations/20231218103423_secret.ts @@ -0,0 +1,65 @@ +import { Knex } from "knex"; + +import { SecretEncryptionAlgo, SecretKeyEncoding, SecretType, TableName } from "../schemas"; +import { createJunctionTable, createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasTable(TableName.SecretBlindIndex))) { + await knex.schema.createTable(TableName.SecretBlindIndex, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.text("encryptedSaltCipherText").notNullable(); + t.text("saltIV").notNullable(); + t.text("saltTag").notNullable(); + t.string("algorithm").notNullable().defaultTo(SecretEncryptionAlgo.AES_256_GCM); + t.string("keyEncoding").notNullable().defaultTo(SecretKeyEncoding.UTF8); + t.string("projectId").notNullable().unique(); + t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE"); + t.timestamps(true, true, true); + }); + } + await createOnUpdateTrigger(knex, TableName.SecretBlindIndex); + + if (!(await knex.schema.hasTable(TableName.Secret))) { + await knex.schema.createTable(TableName.Secret, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.integer("version").defaultTo(1).notNullable(); + t.string("type").notNullable().defaultTo(SecretType.Shared); + // t.text("secretKeyHash").notNullable(); + // t.text("secretValueHash"); + // t.text("secretCommentHash"); + t.text("secretBlindIndex").notNullable(); + t.text("secretKeyCiphertext").notNullable(); + t.text("secretKeyIV").notNullable(); + t.text("secretKeyTag").notNullable(); + t.text("secretValueCiphertext").notNullable(); + t.text("secretValueIV").notNullable(); // symmetric encryption + t.text("secretValueTag").notNullable(); + t.text("secretCommentCiphertext"); + t.text("secretCommentIV"); + t.text("secretCommentTag"); + t.string("secretReminderNote"); + t.integer("secretReminderRepeatDays"); + t.boolean("skipMultilineEncoding").defaultTo(false); + t.string("algorithm").notNullable().defaultTo(SecretEncryptionAlgo.AES_256_GCM); + t.string("keyEncoding").notNullable().defaultTo(SecretKeyEncoding.UTF8); + t.jsonb("metadata"); + t.uuid("userId"); + t.foreign("userId").references("id").inTable(TableName.Users).onDelete("CASCADE"); + t.uuid("folderId").notNullable(); + t.foreign("folderId").references("id").inTable(TableName.SecretFolder).onDelete("CASCADE"); + t.timestamps(true, true, true); + }); + } + await createOnUpdateTrigger(knex, TableName.Secret); + // many to many relation between tags + await createJunctionTable(knex, TableName.JnSecretTag, TableName.Secret, TableName.SecretTag); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.SecretBlindIndex); + await dropOnUpdateTrigger(knex, TableName.SecretBlindIndex); + + await knex.schema.dropTableIfExists(TableName.JnSecretTag); + await knex.schema.dropTableIfExists(TableName.Secret); + await dropOnUpdateTrigger(knex, TableName.Secret); +} diff --git a/pg-migrator/src/migrations/20231220052508_secret-version.ts b/pg-migrator/src/migrations/20231220052508_secret-version.ts new file mode 100644 index 000000000..4b515b8e1 --- /dev/null +++ b/pg-migrator/src/migrations/20231220052508_secret-version.ts @@ -0,0 +1,53 @@ +import { Knex } from "knex"; + +import { SecretEncryptionAlgo, SecretKeyEncoding, SecretType, TableName } from "../schemas"; +import { createJunctionTable, createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasTable(TableName.SecretVersion))) { + await knex.schema.createTable(TableName.SecretVersion, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.integer("version").defaultTo(1).notNullable(); + t.string("type").notNullable().defaultTo(SecretType.Shared); + t.text("secretBlindIndex").notNullable(); + t.text("secretKeyCiphertext").notNullable(); + t.text("secretKeyIV").notNullable(); + t.text("secretKeyTag").notNullable(); + t.text("secretValueCiphertext").notNullable(); + t.text("secretValueIV").notNullable(); // symmetric encryption + t.text("secretValueTag").notNullable(); + t.text("secretCommentCiphertext"); + t.text("secretCommentIV"); + t.text("secretCommentTag"); + t.string("secretReminderNote"); + t.integer("secretReminderRepeatDays"); + t.boolean("skipMultilineEncoding").defaultTo(false); + t.string("algorithm").notNullable().defaultTo(SecretEncryptionAlgo.AES_256_GCM); + t.string("keyEncoding").notNullable().defaultTo(SecretKeyEncoding.UTF8); + t.jsonb("metadata"); + // to avoid orphan rows + t.uuid("envId"); + t.foreign("envId").references("id").inTable(TableName.Environment).onDelete("CASCADE"); + t.uuid("secretId").notNullable(); + t.uuid("folderId").notNullable(); + // t.foreign("secretId").references("id").inTable(TableName.Secret).onDelete("SET NULL"); + t.uuid("userId"); + t.foreign("userId").references("id").inTable(TableName.Users).onDelete("CASCADE"); + t.timestamps(true, true, true); + }); + } + await createOnUpdateTrigger(knex, TableName.SecretVersion); + // many to many relation between tags + await createJunctionTable( + knex, + TableName.JnSecretVersionTag, + TableName.SecretVersion, + TableName.SecretTag + ); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.JnSecretVersionTag); + await knex.schema.dropTableIfExists(TableName.SecretVersion); + await dropOnUpdateTrigger(knex, TableName.SecretVersion); +} diff --git a/pg-migrator/src/migrations/20231222092113_project-bot.ts b/pg-migrator/src/migrations/20231222092113_project-bot.ts new file mode 100644 index 000000000..98c67c8b6 --- /dev/null +++ b/pg-migrator/src/migrations/20231222092113_project-bot.ts @@ -0,0 +1,35 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasTable(TableName.ProjectBot))) { + await knex.schema.createTable(TableName.ProjectBot, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("name").notNullable(); + t.boolean("isActive").defaultTo(false).notNullable(); + t.text("encryptedPrivateKey").notNullable(); + t.text("publicKey").notNullable(); + t.text("iv").notNullable(); + t.text("tag").notNullable(); + t.string("algorithm").notNullable(); + t.string("keyEncoding").notNullable(); + t.text("encryptedProjectKey"); + t.text("encryptedProjectKeyNonce"); + // one to one relationship + t.string("projectId").notNullable().unique(); + t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE"); + t.uuid("senderId"); + t.foreign("senderId").references("id").inTable(TableName.Users).onDelete("SET NULL"); + t.timestamps(true, true, true); + }); + } + + await createOnUpdateTrigger(knex, TableName.ProjectBot); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.ProjectBot); + await dropOnUpdateTrigger(knex, TableName.ProjectBot); +} diff --git a/pg-migrator/src/migrations/20231222172455_integration.ts b/pg-migrator/src/migrations/20231222172455_integration.ts new file mode 100644 index 000000000..cedbde23e --- /dev/null +++ b/pg-migrator/src/migrations/20231222172455_integration.ts @@ -0,0 +1,71 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasTable(TableName.IntegrationAuth))) { + await knex.schema.createTable(TableName.IntegrationAuth, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("integration").notNullable(); + t.string("teamId"); // vercel-specific + t.string("url"); // for self hosted + t.string("namespace"); // hashicorp specific + t.string("accountId"); // netlify + t.string("refreshCiphertext"); + t.string("refreshIV"); + t.string("refreshTag"); + t.string("accessIdCiphertext"); + t.string("accessIdIV"); + t.string("accessIdTag"); + t.string("accessCiphertext"); + t.string("accessIV"); + t.string("accessTag"); + t.datetime("accessExpiresAt"); + t.jsonb("metadata"); + t.string("algorithm").notNullable(); + t.string("keyEncoding").notNullable(); + t.string("projectId").notNullable(); + t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE"); + t.timestamps(true, true, true); + }); + } + await createOnUpdateTrigger(knex, TableName.IntegrationAuth); + + if (!(await knex.schema.hasTable(TableName.Integration))) { + await knex.schema.createTable(TableName.Integration, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.boolean("isActive").notNullable(); + t.string("url"); // self hosted + t.string("app"); // name of app in provider + t.string("appId"); + t.string("targetEnvironment"); + t.string("targetEnvironmentId"); + t.string("targetService"); // railway - qovery specific + t.string("targetServiceId"); + t.string("owner"); // github specific + t.string("path"); // aws parameter store / vercel preview branch + t.string("region"); // aws + t.string("scope"); // qovery specific scope + t.string("integration").notNullable(); + t.jsonb("metadata"); + t.uuid("integrationAuthId").notNullable(); + t.foreign("integrationAuthId") + .references("id") + .inTable(TableName.IntegrationAuth) + .onDelete("CASCADE"); + t.uuid("envId").notNullable(); + t.string("secretPath").defaultTo("/").notNullable(); + t.foreign("envId").references("id").inTable(TableName.Environment).onDelete("CASCADE"); + t.timestamps(true, true, true); + }); + } + await createOnUpdateTrigger(knex, TableName.Integration); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.Integration); + await knex.schema.dropTableIfExists(TableName.IntegrationAuth); + await dropOnUpdateTrigger(knex, TableName.IntegrationAuth); + await dropOnUpdateTrigger(knex, TableName.Integration); +} diff --git a/pg-migrator/src/migrations/20231225072545_service-token.ts b/pg-migrator/src/migrations/20231225072545_service-token.ts new file mode 100644 index 000000000..0dd20af82 --- /dev/null +++ b/pg-migrator/src/migrations/20231225072545_service-token.ts @@ -0,0 +1,32 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasTable(TableName.ServiceToken))) { + await knex.schema.createTable(TableName.ServiceToken, (t) => { + t.string("id", 36).primary().defaultTo(knex.fn.uuid()); + t.string("name").notNullable(); + t.jsonb("scopes").notNullable(); + t.specificType("permissions", "text[]").notNullable(); + t.datetime("lastUsed"); + t.datetime("expiresAt"); + t.text("secretHash").notNullable(); + t.text("encryptedKey"); + t.text("iv"); + t.text("tag"); + t.timestamps(true, true, true); + // user is old one + t.string("createdBy").notNullable(); + t.string("projectId").notNullable(); + t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE"); + }); + } + await createOnUpdateTrigger(knex, TableName.ServiceToken); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.ServiceToken); + await dropOnUpdateTrigger(knex, TableName.ServiceToken); +} diff --git a/pg-migrator/src/migrations/20231225072552_webhook.ts b/pg-migrator/src/migrations/20231225072552_webhook.ts new file mode 100644 index 000000000..f12f489e8 --- /dev/null +++ b/pg-migrator/src/migrations/20231225072552_webhook.ts @@ -0,0 +1,32 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasTable(TableName.Webhook))) { + await knex.schema.createTable(TableName.Webhook, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("secretPath").notNullable().defaultTo("/"); + t.string("url").notNullable(); + t.string("lastStatus"); + t.text("lastRunErrorMessage"); + t.boolean("isDisabled").defaultTo(false).notNullable(); + // webhook signature + t.text("encryptedSecretKey"); + t.text("iv"); + t.text("tag"); + t.string("algorithm"); + t.string("keyEncoding"); + t.timestamps(true, true, true); + t.uuid("envId").notNullable(); + t.foreign("envId").references("id").inTable(TableName.Environment).onDelete("CASCADE"); + }); + } + await createOnUpdateTrigger(knex, TableName.Webhook); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.Webhook); + await dropOnUpdateTrigger(knex, TableName.Webhook); +} diff --git a/pg-migrator/src/migrations/20231228074856_identity.ts b/pg-migrator/src/migrations/20231228074856_identity.ts new file mode 100644 index 000000000..56f5c6752 --- /dev/null +++ b/pg-migrator/src/migrations/20231228074856_identity.ts @@ -0,0 +1,21 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasTable(TableName.Identity))) { + await knex.schema.createTable(TableName.Identity, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("name").notNullable(); + t.string("authMethod"); + t.timestamps(true, true, true); + }); + } + await createOnUpdateTrigger(knex, TableName.Identity); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.Identity); + await dropOnUpdateTrigger(knex, TableName.Identity); +} diff --git a/pg-migrator/src/migrations/20231228074908_identity-universal-auth.ts b/pg-migrator/src/migrations/20231228074908_identity-universal-auth.ts new file mode 100644 index 000000000..15270fe94 --- /dev/null +++ b/pg-migrator/src/migrations/20231228074908_identity-universal-auth.ts @@ -0,0 +1,49 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasTable(TableName.IdentityUniversalAuth))) { + await knex.schema.createTable(TableName.IdentityUniversalAuth, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("clientId").notNullable(); + t.integer("accessTokenTTL").defaultTo(7200).notNullable(); + t.integer("accessTokenMaxTTL").defaultTo(7200).notNullable(); + t.integer("accessTokenNumUsesLimit").defaultTo(0).notNullable(); + t.jsonb("clientSecretTrustedIps").notNullable(); + t.jsonb("accessTokenTrustedIps").notNullable(); + t.timestamps(true, true, true); + t.uuid("identityId").notNullable().unique(); + t.foreign("identityId").references("id").inTable(TableName.Identity).onDelete("CASCADE"); + }); + } + if (!(await knex.schema.hasTable(TableName.IdentityUaClientSecret))) { + await knex.schema.createTable(TableName.IdentityUaClientSecret, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("description").notNullable(); + t.string("clientSecretPrefix").notNullable(); + t.string("clientSecretHash").notNullable(); + t.datetime("clientSecretLastUsedAt"); + t.integer("clientSecretNumUses").defaultTo(0).notNullable(); + t.integer("clientSecretNumUsesLimit").defaultTo(0).notNullable(); + t.integer("clientSecretTTL").defaultTo(0).notNullable(); + t.boolean("isClientSecretRevoked").defaultTo(false).notNullable(); + t.timestamps(true, true, true); + t.uuid("identityUAId").notNullable(); + t.foreign("identityUAId") + .references("id") + .inTable(TableName.IdentityUniversalAuth) + .onDelete("CASCADE"); + }); + } + await createOnUpdateTrigger(knex, TableName.IdentityUniversalAuth); + await createOnUpdateTrigger(knex, TableName.IdentityUaClientSecret); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.IdentityUaClientSecret); + await knex.schema.dropTableIfExists(TableName.IdentityUniversalAuth); + await dropOnUpdateTrigger(knex, TableName.IdentityUaClientSecret); + await dropOnUpdateTrigger(knex, TableName.IdentityUniversalAuth); +} diff --git a/pg-migrator/src/migrations/20231228075011_identity-access-token.ts b/pg-migrator/src/migrations/20231228075011_identity-access-token.ts new file mode 100644 index 000000000..1a5953fcd --- /dev/null +++ b/pg-migrator/src/migrations/20231228075011_identity-access-token.ts @@ -0,0 +1,35 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasTable(TableName.IdentityAccessToken))) { + await knex.schema.createTable(TableName.IdentityAccessToken, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("authType").notNullable(); + t.integer("accessTokenTTL").defaultTo(2592000).notNullable(); // 30 days second + t.integer("accessTokenMaxTTL").defaultTo(2592000).notNullable(); + t.integer("accessTokenNumUses").defaultTo(0).notNullable(); + t.integer("accessTokenNumUsesLimit").defaultTo(0).notNullable(); + t.datetime("accessTokenLastUsedAt"); + t.datetime("accessTokenLastRenewedAt"); + t.boolean("isAccessTokenRevoked").defaultTo(false).notNullable(); + t.uuid("identityUAClientSecretId"); + t.foreign("identityUAClientSecretId") + .references("id") + .inTable(TableName.IdentityUaClientSecret) + .onDelete("CASCADE"); + t.uuid("identityId").notNullable(); + t.foreign("identityId").references("id").inTable(TableName.Identity).onDelete("CASCADE"); + t.timestamps(true, true, true); + }); + } + + await createOnUpdateTrigger(knex, TableName.IdentityAccessToken); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.IdentityAccessToken); + await dropOnUpdateTrigger(knex, TableName.IdentityAccessToken); +} diff --git a/pg-migrator/src/migrations/20231228075023_identity-membership.ts b/pg-migrator/src/migrations/20231228075023_identity-membership.ts new file mode 100644 index 000000000..288c11be3 --- /dev/null +++ b/pg-migrator/src/migrations/20231228075023_identity-membership.ts @@ -0,0 +1,44 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasTable(TableName.IdentityOrgMembership))) { + await knex.schema.createTable(TableName.IdentityOrgMembership, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("role").notNullable(); + t.uuid("roleId"); + t.foreign("roleId").references("id").inTable(TableName.OrgRoles); + t.uuid("orgId").notNullable(); + t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE"); + t.timestamps(true, true, true); + t.uuid("identityId").notNullable(); + t.foreign("identityId").references("id").inTable(TableName.Identity).onDelete("CASCADE"); + }); + } + await createOnUpdateTrigger(knex, TableName.IdentityOrgMembership); + + if (!(await knex.schema.hasTable(TableName.IdentityProjectMembership))) { + await knex.schema.createTable(TableName.IdentityProjectMembership, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("role").notNullable(); + t.uuid("roleId"); + t.foreign("roleId").references("id").inTable(TableName.ProjectRoles); + t.string("projectId").notNullable(); + t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE"); + t.uuid("identityId").notNullable(); + t.foreign("identityId").references("id").inTable(TableName.Identity).onDelete("CASCADE"); + t.timestamps(true, true, true); + }); + } + await createOnUpdateTrigger(knex, TableName.IdentityProjectMembership); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.IdentityOrgMembership); + await knex.schema.dropTableIfExists(TableName.IdentityProjectMembership); + + await dropOnUpdateTrigger(knex, TableName.IdentityProjectMembership); + await dropOnUpdateTrigger(knex, TableName.IdentityOrgMembership); +} diff --git a/pg-migrator/src/migrations/20240101054849_secret-approval-policy.ts b/pg-migrator/src/migrations/20240101054849_secret-approval-policy.ts new file mode 100644 index 000000000..10d9a1480 --- /dev/null +++ b/pg-migrator/src/migrations/20240101054849_secret-approval-policy.ts @@ -0,0 +1,45 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasTable(TableName.SecretApprovalPolicy))) { + await knex.schema.createTable(TableName.SecretApprovalPolicy, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("name").notNullable(); + t.string("secretPath"); + t.integer("approvals").defaultTo(1).notNullable(); + t.uuid("envId").notNullable(); + t.foreign("envId").references("id").inTable(TableName.Environment).onDelete("CASCADE"); + t.timestamps(true, true, true); + }); + } + await createOnUpdateTrigger(knex, TableName.SecretApprovalPolicy); + + if (!(await knex.schema.hasTable(TableName.SapApprover))) { + await knex.schema.createTable(TableName.SapApprover, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.uuid("approverId").notNullable(); + t.foreign("approverId") + .references("id") + .inTable(TableName.ProjectMembership) + .onDelete("CASCADE"); + t.uuid("policyId").notNullable(); + t.foreign("policyId") + .references("id") + .inTable(TableName.SecretApprovalPolicy) + .onDelete("CASCADE"); + t.timestamps(true, true, true); + }); + } + + await createOnUpdateTrigger(knex, TableName.SapApprover); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.SapApprover); + await knex.schema.dropTableIfExists(TableName.SecretApprovalPolicy); + await dropOnUpdateTrigger(knex, TableName.SapApprover); + await dropOnUpdateTrigger(knex, TableName.SecretApprovalPolicy); +} diff --git a/pg-migrator/src/migrations/20240101104907_secret-approval-request.ts b/pg-migrator/src/migrations/20240101104907_secret-approval-request.ts new file mode 100644 index 000000000..5fce143c3 --- /dev/null +++ b/pg-migrator/src/migrations/20240101104907_secret-approval-request.ts @@ -0,0 +1,115 @@ +import { Knex } from "knex"; + +import { SecretEncryptionAlgo, SecretKeyEncoding, TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasTable(TableName.SecretApprovalRequest))) { + await knex.schema.createTable(TableName.SecretApprovalRequest, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.uuid("policyId").notNullable(); + t.boolean("hasMerged").defaultTo(false).notNullable(); + t.string("status").defaultTo("open").notNullable(); + t.jsonb("conflicts"); + t.foreign("policyId") + .references("id") + .inTable(TableName.SecretApprovalPolicy) + .onDelete("CASCADE"); + t.string("slug").notNullable(); + t.uuid("folderId").notNullable(); + t.foreign("folderId").references("id").inTable(TableName.SecretFolder).onDelete("CASCADE"); + t.uuid("statusChangeBy"); + t.foreign("statusChangeBy") + .references("id") + .inTable(TableName.ProjectMembership) + .onDelete("CASCADE"); + t.uuid("committerId").notNullable(); + t.foreign("committerId") + .references("id") + .inTable(TableName.ProjectMembership) + .onDelete("CASCADE"); + t.timestamps(true, true, true); + }); + } + await createOnUpdateTrigger(knex, TableName.SecretApprovalRequest); + + if (!(await knex.schema.hasTable(TableName.SarReviewer))) { + await knex.schema.createTable(TableName.SarReviewer, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.uuid("member").notNullable(); + t.foreign("member").references("id").inTable(TableName.ProjectMembership).onDelete("CASCADE"); + t.string("status").notNullable(); + t.uuid("requestId").notNullable(); + t.foreign("requestId") + .references("id") + .inTable(TableName.SecretApprovalRequest) + .onDelete("CASCADE"); + t.timestamps(true, true, true); + }); + } + await createOnUpdateTrigger(knex, TableName.SarReviewer); + + if (!(await knex.schema.hasTable(TableName.SarSecret))) { + await knex.schema.createTable(TableName.SarSecret, (t) => { + // everything related to secret + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.integer("version").defaultTo(1); + t.text("secretBlindIndex").notNullable(); + t.text("secretKeyCiphertext").notNullable(); + t.text("secretKeyIV").notNullable(); + t.text("secretKeyTag").notNullable(); + t.text("secretValueCiphertext").notNullable(); + t.text("secretValueIV").notNullable(); // symmetric encryption + t.text("secretValueTag").notNullable(); + t.text("secretCommentCiphertext"); + t.text("secretCommentIV"); + t.text("secretCommentTag"); + t.string("secretReminderNote"); + t.integer("secretReminderRepeatDays"); + t.boolean("skipMultilineEncoding").defaultTo(false); + t.string("algorithm").notNullable().defaultTo(SecretEncryptionAlgo.AES_256_GCM); + t.string("keyEncoding").notNullable().defaultTo(SecretKeyEncoding.UTF8); + t.jsonb("metadata"); + t.timestamps(true, true, true); + // commit details + t.uuid("requestId").notNullable(); + t.foreign("requestId") + .references("id") + .inTable(TableName.SecretApprovalRequest) + .onDelete("CASCADE"); + t.string("op").notNullable(); + t.uuid("secretId"); + t.foreign("secretId").references("id").inTable(TableName.Secret).onDelete("SET NULL"); + t.uuid("secretVersion"); + t.foreign("secretVersion") + .references("id") + .inTable(TableName.SecretVersion) + .onDelete("SET NULL"); + }); + } + await createOnUpdateTrigger(knex, TableName.SarSecret); + + if (!(await knex.schema.hasTable(TableName.SarSecretTag))) { + await knex.schema.createTable(TableName.SarSecretTag, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.uuid("secretId").notNullable(); + t.foreign("secretId").references("id").inTable(TableName.SarSecret).onDelete("CASCADE"); + t.uuid("tagId").notNullable(); + t.foreign("tagId").references("id").inTable(TableName.SecretTag).onDelete("CASCADE"); + t.timestamps(true, true, true); + }); + } + await createOnUpdateTrigger(knex, TableName.SarSecretTag); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.SarSecretTag); + await knex.schema.dropTableIfExists(TableName.SarSecret); + await knex.schema.dropTableIfExists(TableName.SarReviewer); + await knex.schema.dropTableIfExists(TableName.SecretApprovalRequest); + + await dropOnUpdateTrigger(knex, TableName.SarSecretTag); + await dropOnUpdateTrigger(knex, TableName.SarSecret); + await dropOnUpdateTrigger(knex, TableName.SarReviewer); + await dropOnUpdateTrigger(knex, TableName.SecretApprovalRequest); +} diff --git a/pg-migrator/src/migrations/20240102152111_secret-rotation.ts b/pg-migrator/src/migrations/20240102152111_secret-rotation.ts new file mode 100644 index 000000000..f7009488a --- /dev/null +++ b/pg-migrator/src/migrations/20240102152111_secret-rotation.ts @@ -0,0 +1,47 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasTable(TableName.SecretRotation))) { + await knex.schema.createTable(TableName.SecretRotation, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("provider").notNullable(); + t.string("secretPath").notNullable(); + t.integer("interval").notNullable(); + t.datetime("lastRotatedAt"); + t.string("status"); + t.text("statusMessage"); + t.text("encryptedData"); + t.text("encryptedDataIV"); + t.text("encryptedDataTag"); + t.string("algorithm"); + t.string("keyEncoding"); + t.uuid("envId").notNullable(); + t.foreign("envId").references("id").inTable(TableName.Environment).onDelete("CASCADE"); + t.timestamps(true, true, true); + }); + } + await createOnUpdateTrigger(knex, TableName.SecretRotation); + + if (!(await knex.schema.hasTable(TableName.SecretRotationOutput))) { + await knex.schema.createTable(TableName.SecretRotationOutput, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("key").notNullable(); + t.uuid("secretId").notNullable(); + t.foreign("secretId").references("id").inTable(TableName.Secret).onDelete("CASCADE"); + t.uuid("rotationId").notNullable(); + t.foreign("rotationId") + .references("id") + .inTable(TableName.SecretRotation) + .onDelete("CASCADE"); + }); + } +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.SecretRotationOutput); + await knex.schema.dropTableIfExists(TableName.SecretRotation); + await dropOnUpdateTrigger(knex, TableName.SecretRotation); +} diff --git a/pg-migrator/src/migrations/20240104140641_secret-snapshot.ts b/pg-migrator/src/migrations/20240104140641_secret-snapshot.ts new file mode 100644 index 000000000..01b1e24fb --- /dev/null +++ b/pg-migrator/src/migrations/20240104140641_secret-snapshot.ts @@ -0,0 +1,61 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasTable(TableName.Snapshot))) { + await knex.schema.createTable(TableName.Snapshot, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.uuid("envId").notNullable(); + t.foreign("envId").references("id").inTable(TableName.Environment).onDelete("CASCADE"); + // this is not a relation kept like that + // this ensure snapshot are not lost when folder gets deleted and rolled back + t.uuid("folderId").notNullable(); + t.uuid("parentFolderId"); + t.timestamps(true, true, true); + }); + } + await createOnUpdateTrigger(knex, TableName.Snapshot); + + if (!(await knex.schema.hasTable(TableName.SnapshotSecret))) { + await knex.schema.createTable(TableName.SnapshotSecret, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.uuid("envId").notNullable(); + t.foreign("envId").references("id").inTable(TableName.Environment).onDelete("CASCADE"); + // not a relation kept like that to keep it when rolled back + t.uuid("secretVersionId").notNullable(); + t.foreign("secretVersionId") + .references("id") + .inTable(TableName.SecretVersion) + .onDelete("CASCADE"); + t.uuid("snapshotId").notNullable(); + t.foreign("snapshotId").references("id").inTable(TableName.Snapshot).onDelete("CASCADE"); + t.timestamps(true, true, true); + }); + } + + if (!(await knex.schema.hasTable(TableName.SnapshotFolder))) { + await knex.schema.createTable(TableName.SnapshotFolder, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.uuid("envId").notNullable(); + t.foreign("envId").references("id").inTable(TableName.Environment).onDelete("CASCADE"); + // not a relation kept like that to keep it when rolled back + t.uuid("folderVersionId").notNullable(); + t.foreign("folderVersionId") + .references("id") + .inTable(TableName.SecretFolderVersion) + .onDelete("CASCADE"); + t.uuid("snapshotId").notNullable(); + t.foreign("snapshotId").references("id").inTable(TableName.Snapshot).onDelete("CASCADE"); + t.timestamps(true, true, true); + }); + } +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.SnapshotSecret); + await knex.schema.dropTableIfExists(TableName.SnapshotFolder); + await knex.schema.dropTableIfExists(TableName.Snapshot); + await dropOnUpdateTrigger(knex, TableName.Snapshot); +} diff --git a/pg-migrator/src/migrations/20240107153439_saml-config.ts b/pg-migrator/src/migrations/20240107153439_saml-config.ts new file mode 100644 index 000000000..76070dc68 --- /dev/null +++ b/pg-migrator/src/migrations/20240107153439_saml-config.ts @@ -0,0 +1,33 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasTable(TableName.SamlConfig))) { + await knex.schema.createTable(TableName.SamlConfig, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("authProvider").notNullable(); + t.boolean("isActive").notNullable(); + t.string("encryptedEntryPoint"); + t.string("entryPointIV"); + t.string("entryPointTag"); + t.string("encryptedIssuer"); + t.string("issuerTag"); + t.string("issuerIV"); + t.text("encryptedCert"); + t.string("certIV"); + t.string("certTag"); + t.timestamps(true, true, true); + t.uuid("orgId").notNullable().unique(); + t.foreign("orgId").references("id").inTable(TableName.Organization); + }); + } + + await createOnUpdateTrigger(knex, TableName.SamlConfig); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.SamlConfig); + await dropOnUpdateTrigger(knex, TableName.SamlConfig); +} diff --git a/pg-migrator/src/migrations/20240107163155_org-bot.ts b/pg-migrator/src/migrations/20240107163155_org-bot.ts new file mode 100644 index 000000000..6e4365f9d --- /dev/null +++ b/pg-migrator/src/migrations/20240107163155_org-bot.ts @@ -0,0 +1,35 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasTable(TableName.OrgBot))) { + await knex.schema.createTable(TableName.OrgBot, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("name").notNullable(); + t.text("publicKey").notNullable(); + t.text("encryptedSymmetricKey").notNullable(); + t.text("symmetricKeyIV").notNullable(); + t.text("symmetricKeyTag").notNullable(); + t.string("symmetricKeyAlgorithm").notNullable(); + t.string("symmetricKeyKeyEncoding").notNullable(); + t.text("encryptedPrivateKey").notNullable(); + t.text("privateKeyIV").notNullable(); + t.text("privateKeyTag").notNullable(); + t.string("privateKeyAlgorithm").notNullable(); + t.string("privateKeyKeyEncoding").notNullable(); + // one to one relationship + t.uuid("orgId").notNullable().unique(); + t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE"); + t.timestamps(true, true, true); + }); + } + + await createOnUpdateTrigger(knex, TableName.OrgBot); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.OrgBot); + await dropOnUpdateTrigger(knex, TableName.OrgBot); +} diff --git a/pg-migrator/src/migrations/20240108134148_audit-log.ts b/pg-migrator/src/migrations/20240108134148_audit-log.ts new file mode 100644 index 000000000..9eb74f03d --- /dev/null +++ b/pg-migrator/src/migrations/20240108134148_audit-log.ts @@ -0,0 +1,29 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasTable(TableName.AuditLog))) { + await knex.schema.createTable(TableName.AuditLog, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("actor").notNullable(); + t.jsonb("actorMetadata").notNullable(); + t.string("ipAddress"); + t.string("eventType").notNullable(); + t.jsonb("eventMetadata"); + t.string("userAgent"); + t.string("userAgentType"); + t.datetime("expiresAt"); + t.timestamps(true, true, true); + // no trigger needed as this collection is append only + t.uuid("orgId"); + t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE"); + t.string("projectId"); + t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE"); + }); + } +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.AuditLog); +} diff --git a/pg-migrator/src/migrations/20240111051011_secret-scanning.ts b/pg-migrator/src/migrations/20240111051011_secret-scanning.ts new file mode 100644 index 000000000..af011d558 --- /dev/null +++ b/pg-migrator/src/migrations/20240111051011_secret-scanning.ts @@ -0,0 +1,79 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasTable(TableName.GitAppInstallSession))) { + await knex.schema.createTable(TableName.GitAppInstallSession, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("sessionId").notNullable().unique(); + t.uuid("userId"); + // one to one relationship + t.uuid("orgId").notNullable().unique(); + t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE"); + t.timestamps(true, true, true); + }); + } + createOnUpdateTrigger(knex, TableName.GitAppInstallSession); + + if (!(await knex.schema.hasTable(TableName.GitAppOrg))) { + await knex.schema.createTable(TableName.GitAppOrg, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("installationId").notNullable().unique(); + t.uuid("userId").notNullable(); + // one to one relationship + t.uuid("orgId").notNullable().unique(); + t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE"); + t.timestamps(true, true, true); + }); + } + createOnUpdateTrigger(knex, TableName.GitAppOrg); + + if (!(await knex.schema.hasTable(TableName.SecretScanningGitRisk))) { + await knex.schema.createTable(TableName.SecretScanningGitRisk, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("description"); + t.string("startLine"); + t.string("endLine"); + t.string("startColumn"); + t.string("endColumn"); + t.string("file"); + t.string("symlinkFile"); + t.string("commit"); + t.string("entropy"); + t.string("author"); + t.string("email"); + t.string("date"); + t.text("message"); + t.specificType("tags", "text[]"); + t.string("ruleID"); + t.string("fingerprint").unique(); + t.string("fingerPrintWithoutCommitId"); + t.boolean("isFalsePositive").defaultTo(false); + t.boolean("isResolved").defaultTo(false); + t.string("riskOwner"); + t.string("installationId").notNullable(); + t.string("repositoryId"); + t.string("repositoryLink"); + t.string("repositoryFullName"); + t.string("pusherName"); + t.string("pusherEmail"); + t.string("status"); + // one to one relationship + t.uuid("orgId").notNullable(); + t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE"); + t.timestamps(true, true, true); + }); + } + createOnUpdateTrigger(knex, TableName.SecretScanningGitRisk); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.SecretScanningGitRisk); + await knex.schema.dropTableIfExists(TableName.GitAppOrg); + await knex.schema.dropTableIfExists(TableName.GitAppInstallSession); + await dropOnUpdateTrigger(knex, TableName.SecretScanningGitRisk); + await dropOnUpdateTrigger(knex, TableName.GitAppOrg); + await dropOnUpdateTrigger(knex, TableName.GitAppInstallSession); +} diff --git a/pg-migrator/src/migrations/20240113103743_trusted-ip.ts b/pg-migrator/src/migrations/20240113103743_trusted-ip.ts new file mode 100644 index 000000000..2924f0668 --- /dev/null +++ b/pg-migrator/src/migrations/20240113103743_trusted-ip.ts @@ -0,0 +1,26 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasTable(TableName.TrustedIps))) { + await knex.schema.createTable(TableName.TrustedIps, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("ipAddress").notNullable(); + t.string("type").notNullable(); + t.integer("prefix"); + t.boolean("isActive").defaultTo(true); + t.string("comment"); + t.string("projectId").notNullable(); + t.foreign("projectId").references("id").inTable(TableName.Project); + t.timestamps(true, true, true); + }); + } + await createOnUpdateTrigger(knex, TableName.TrustedIps); +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTableIfExists(TableName.TrustedIps); + await dropOnUpdateTrigger(knex, TableName.TrustedIps); +} diff --git a/pg-migrator/src/models/apiKeyData.ts b/pg-migrator/src/models/apiKeyData.ts new file mode 100644 index 000000000..0b88c5ddb --- /dev/null +++ b/pg-migrator/src/models/apiKeyData.ts @@ -0,0 +1,39 @@ +import { Schema, Types, model } from "mongoose"; + +export interface IAPIKeyData { + name: string; + user: Types.ObjectId; + lastUsed: Date; + expiresAt: Date; + secretHash: string; +} + +const apiKeyDataSchema = new Schema( + { + name: { + type: String, + required: true, + }, + user: { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + lastUsed: { + type: Date, + }, + expiresAt: { + type: Date, + }, + secretHash: { + type: String, + required: true, + select: false, + }, + }, + { + timestamps: true, + } +); + +export const APIKeyData = model("APIKeyData", apiKeyDataSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/apiKeyDataV2.ts b/pg-migrator/src/models/apiKeyDataV2.ts new file mode 100644 index 000000000..6775a0878 --- /dev/null +++ b/pg-migrator/src/models/apiKeyDataV2.ts @@ -0,0 +1,38 @@ +import { Document, Schema, Types, model } from "mongoose"; + +export interface IAPIKeyDataV2 extends Document { + _id: Types.ObjectId; + name: string; + user: Types.ObjectId; + lastUsed?: Date + usageCount: number; + expiresAt?: Date; +} + +const apiKeyDataV2Schema = new Schema( + { + name: { + type: String, + required: true + }, + user: { + type: Schema.Types.ObjectId, + ref: "User", + required: true + }, + lastUsed: { + type: Date, + required: false + }, + usageCount: { + type: Number, + default: 0, + required: true + } + }, + { + timestamps: true + } +); + +export const APIKeyDataV2 = model("APIKeyDataV2", apiKeyDataV2Schema); \ No newline at end of file diff --git a/pg-migrator/src/models/auditLog/auditLog.ts b/pg-migrator/src/models/auditLog/auditLog.ts new file mode 100644 index 000000000..824e2f89f --- /dev/null +++ b/pg-migrator/src/models/auditLog/auditLog.ts @@ -0,0 +1,70 @@ +import { Schema, Types, model } from "mongoose"; +import { ActorType, EventType, UserAgentType } from "./enums"; +import { Actor, Event } from "./types"; + +export interface IAuditLog { + actor: Actor; + organization: Types.ObjectId; + workspace: Types.ObjectId; + ipAddress: string; + event: Event; + userAgent: string; + userAgentType: UserAgentType; + expiresAt?: Date; +} + +const auditLogSchema = new Schema( + { + actor: { + type: { + type: String, + enum: ActorType, + required: true + }, + metadata: { + type: Schema.Types.Mixed + } + }, + organization: { + type: Schema.Types.ObjectId, + required: false + }, + workspace: { + type: Schema.Types.ObjectId, + required: false, + index: true + }, + ipAddress: { + type: String, + required: true + }, + event: { + type: { + type: String, + enum: EventType, + required: true + }, + metadata: { + type: Schema.Types.Mixed + } + }, + userAgent: { + type: String, + required: true + }, + userAgentType: { + type: String, + enum: UserAgentType, + required: true + }, + expiresAt: { + type: Date, + expires: 0 + } + }, + { + timestamps: true + } +); + +export const AuditLog = model("AuditLog", auditLogSchema); diff --git a/pg-migrator/src/models/auditLog/enums.ts b/pg-migrator/src/models/auditLog/enums.ts new file mode 100644 index 000000000..ad0051bbc --- /dev/null +++ b/pg-migrator/src/models/auditLog/enums.ts @@ -0,0 +1,69 @@ +export enum ActorType { // would extend to AWS, Azure, ... + USER = "user", // userIdentity + SERVICE = "service", + IDENTITY = "identity" +} + +export enum UserAgentType { + WEB = "web", + CLI = "cli", + K8_OPERATOR = "k8-operator", + TERRAFORM = "terraform", + OTHER = "other", + PYTHON_SDK = "InfisicalPythonSDK", + NODE_SDK = "InfisicalNodeSDK" +} + +export enum EventType { + GET_SECRETS = "get-secrets", + GET_SECRET = "get-secret", + REVEAL_SECRET = "reveal-secret", + CREATE_SECRET = "create-secret", + CREATE_SECRETS = "create-secrets", + UPDATE_SECRET = "update-secret", + UPDATE_SECRETS = "update-secrets", + DELETE_SECRET = "delete-secret", + DELETE_SECRETS = "delete-secrets", + GET_WORKSPACE_KEY = "get-workspace-key", + AUTHORIZE_INTEGRATION = "authorize-integration", + UNAUTHORIZE_INTEGRATION = "unauthorize-integration", + CREATE_INTEGRATION = "create-integration", + DELETE_INTEGRATION = "delete-integration", + ADD_TRUSTED_IP = "add-trusted-ip", + UPDATE_TRUSTED_IP = "update-trusted-ip", + DELETE_TRUSTED_IP = "delete-trusted-ip", + CREATE_SERVICE_TOKEN = "create-service-token", // v2 + DELETE_SERVICE_TOKEN = "delete-service-token", // v2 + CREATE_IDENTITY = "create-identity", + UPDATE_IDENTITY = "update-identity", + DELETE_IDENTITY = "delete-identity", + LOGIN_IDENTITY_UNIVERSAL_AUTH = "login-identity-universal-auth", + ADD_IDENTITY_UNIVERSAL_AUTH = "add-identity-universal-auth", + UPDATE_IDENTITY_UNIVERSAL_AUTH = "update-identity-universal-auth", + GET_IDENTITY_UNIVERSAL_AUTH = "get-identity-universal-auth", + CREATE_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRET = "create-identity-universal-auth-client-secret", + REVOKE_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRET = "revoke-identity-universal-auth-client-secret", + GET_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRETS = "get-identity-universal-auth-client-secret", + CREATE_ENVIRONMENT = "create-environment", + UPDATE_ENVIRONMENT = "update-environment", + DELETE_ENVIRONMENT = "delete-environment", + ADD_WORKSPACE_MEMBER = "add-workspace-member", + ADD_BATCH_WORKSPACE_MEMBER = "add-workspace-members", + REMOVE_WORKSPACE_MEMBER = "remove-workspace-member", + CREATE_FOLDER = "create-folder", + UPDATE_FOLDER = "update-folder", + DELETE_FOLDER = "delete-folder", + CREATE_WEBHOOK = "create-webhook", + UPDATE_WEBHOOK_STATUS = "update-webhook-status", + DELETE_WEBHOOK = "delete-webhook", + GET_SECRET_IMPORTS = "get-secret-imports", + CREATE_SECRET_IMPORT = "create-secret-import", + UPDATE_SECRET_IMPORT = "update-secret-import", + DELETE_SECRET_IMPORT = "delete-secret-import", + UPDATE_USER_WORKSPACE_ROLE = "update-user-workspace-role", + UPDATE_USER_WORKSPACE_DENIED_PERMISSIONS = "update-user-workspace-denied-permissions", + SECRET_APPROVAL_MERGED = "secret-approval-merged", + SECRET_APPROVAL_REQUEST = "secret-approval-request", + SECRET_APPROVAL_CLOSED = "secret-approval-closed", + SECRET_APPROVAL_REOPENED = "secret-approval-reopened" +} diff --git a/pg-migrator/src/models/auditLog/index.ts b/pg-migrator/src/models/auditLog/index.ts new file mode 100644 index 000000000..37b86b5d1 --- /dev/null +++ b/pg-migrator/src/models/auditLog/index.ts @@ -0,0 +1,3 @@ +export * from "./auditLog"; +export * from "./enums"; +export * from "./types"; \ No newline at end of file diff --git a/pg-migrator/src/models/auditLog/types.ts b/pg-migrator/src/models/auditLog/types.ts new file mode 100644 index 000000000..a4e470414 --- /dev/null +++ b/pg-migrator/src/models/auditLog/types.ts @@ -0,0 +1,585 @@ +import { ActorType, EventType } from "./enums"; +import { IIdentityTrustedIp } from "../../../models"; + +interface UserActorMetadata { + userId: string; + email: string; +} + +interface ServiceActorMetadata { + serviceId: string; + name: string; +} + +interface IdentityActorMetadata { + identityId: string; + name: string; +} + +export interface UserActor { + type: ActorType.USER; + metadata: UserActorMetadata; +} + +export interface ServiceActor { + type: ActorType.SERVICE; + metadata: ServiceActorMetadata; +} + +export interface IdentityActor { + type: ActorType.IDENTITY; + metadata: IdentityActorMetadata; +} + +export type Actor = UserActor | ServiceActor | IdentityActor; + +interface GetSecretsEvent { + type: EventType.GET_SECRETS; + metadata: { + environment: string; + secretPath: string; + numberOfSecrets: number; + }; +} + +interface GetSecretEvent { + type: EventType.GET_SECRET; + metadata: { + environment: string; + secretPath: string; + secretId: string; + secretKey: string; + secretVersion: number; + }; +} + +interface CreateSecretEvent { + type: EventType.CREATE_SECRET; + metadata: { + environment: string; + secretPath: string; + secretId: string; + secretKey: string; + secretVersion: number; + }; +} + +interface CreateSecretBatchEvent { + type: EventType.CREATE_SECRETS; + metadata: { + environment: string; + secretPath: string; + secrets: Array<{ secretId: string; secretKey: string; secretVersion: number }>; + }; +} + +interface UpdateSecretEvent { + type: EventType.UPDATE_SECRET; + metadata: { + environment: string; + secretPath: string; + secretId: string; + secretKey: string; + secretVersion: number; + }; +} + +interface UpdateSecretBatchEvent { + type: EventType.UPDATE_SECRETS; + metadata: { + environment: string; + secretPath: string; + secrets: Array<{ secretId: string; secretKey: string; secretVersion: number }>; + }; +} + +interface DeleteSecretEvent { + type: EventType.DELETE_SECRET; + metadata: { + environment: string; + secretPath: string; + secretId: string; + secretKey: string; + secretVersion: number; + }; +} + +interface DeleteSecretBatchEvent { + type: EventType.DELETE_SECRETS; + metadata: { + environment: string; + secretPath: string; + secrets: Array<{ secretId: string; secretKey: string; secretVersion: number }>; + }; +} + +interface GetWorkspaceKeyEvent { + type: EventType.GET_WORKSPACE_KEY; + metadata: { + keyId: string; + }; +} + +interface AuthorizeIntegrationEvent { + type: EventType.AUTHORIZE_INTEGRATION; + metadata: { + integration: string; + }; +} + +interface UnauthorizeIntegrationEvent { + type: EventType.UNAUTHORIZE_INTEGRATION; + metadata: { + integration: string; + }; +} + +interface CreateIntegrationEvent { + type: EventType.CREATE_INTEGRATION; + metadata: { + integrationId: string; + integration: string; // TODO: fix type + environment: string; + secretPath: string; + url?: string; + app?: string; + appId?: string; + targetEnvironment?: string; + targetEnvironmentId?: string; + targetService?: string; + targetServiceId?: string; + path?: string; + region?: string; + }; +} + +interface DeleteIntegrationEvent { + type: EventType.DELETE_INTEGRATION; + metadata: { + integrationId: string; + integration: string; // TODO: fix type + environment: string; + secretPath: string; + url?: string; + app?: string; + appId?: string; + targetEnvironment?: string; + targetEnvironmentId?: string; + targetService?: string; + targetServiceId?: string; + path?: string; + region?: string; + }; +} + +interface AddTrustedIPEvent { + type: EventType.ADD_TRUSTED_IP; + metadata: { + trustedIpId: string; + ipAddress: string; + prefix?: number; + }; +} + +interface UpdateTrustedIPEvent { + type: EventType.UPDATE_TRUSTED_IP; + metadata: { + trustedIpId: string; + ipAddress: string; + prefix?: number; + }; +} + +interface DeleteTrustedIPEvent { + type: EventType.DELETE_TRUSTED_IP; + metadata: { + trustedIpId: string; + ipAddress: string; + prefix?: number; + }; +} + +interface CreateServiceTokenEvent { + type: EventType.CREATE_SERVICE_TOKEN; + metadata: { + name: string; + scopes: Array<{ + environment: string; + secretPath: string; + }>; + }; +} + +interface DeleteServiceTokenEvent { + type: EventType.DELETE_SERVICE_TOKEN; + metadata: { + name: string; + scopes: Array<{ + environment: string; + secretPath: string; + }>; + }; +} + +interface CreateIdentityEvent { // note: currently not logging org-role + type: EventType.CREATE_IDENTITY; + metadata: { + identityId: string; + name: string; + }; +} + +interface UpdateIdentityEvent { + type: EventType.UPDATE_IDENTITY; + metadata: { + identityId: string; + name?: string; + }; +} + +interface DeleteIdentityEvent { + type: EventType.DELETE_IDENTITY; + metadata: { + identityId: string; + }; +} + +interface LoginIdentityUniversalAuthEvent { + type: EventType.LOGIN_IDENTITY_UNIVERSAL_AUTH ; + metadata: { + identityId: string; + identityUniversalAuthId: string; + clientSecretId: string; + identityAccessTokenId: string; + }; +} + +interface AddIdentityUniversalAuthEvent { + type: EventType.ADD_IDENTITY_UNIVERSAL_AUTH; + metadata: { + identityId: string; + clientSecretTrustedIps: Array; + accessTokenTTL: number; + accessTokenMaxTTL: number; + accessTokenNumUsesLimit: number; + accessTokenTrustedIps: Array; + }; +} + +interface UpdateIdentityUniversalAuthEvent { + type: EventType.UPDATE_IDENTITY_UNIVERSAL_AUTH; + metadata: { + identityId: string; + clientSecretTrustedIps?: Array; + accessTokenTTL?: number; + accessTokenMaxTTL?: number; + accessTokenNumUsesLimit?: number; + accessTokenTrustedIps?: Array; + }; +} + +interface GetIdentityUniversalAuthEvent { + type: EventType.GET_IDENTITY_UNIVERSAL_AUTH; + metadata: { + identityId: string; + }; +} + +interface CreateIdentityUniversalAuthClientSecretEvent { + type: EventType.CREATE_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRET ; + metadata: { + identityId: string; + clientSecretId: string; + }; +} + +interface GetIdentityUniversalAuthClientSecretsEvent { + type: EventType.GET_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRETS; + metadata: { + identityId: string; + }; +} + + +interface RevokeIdentityUniversalAuthClientSecretEvent { + type: EventType.REVOKE_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRET ; + metadata: { + identityId: string; + clientSecretId: string; + }; +} + +interface CreateEnvironmentEvent { + type: EventType.CREATE_ENVIRONMENT; + metadata: { + name: string; + slug: string; + }; +} + +interface UpdateEnvironmentEvent { + type: EventType.UPDATE_ENVIRONMENT; + metadata: { + oldName: string; + newName: string; + oldSlug: string; + newSlug: string; + }; +} + +interface DeleteEnvironmentEvent { + type: EventType.DELETE_ENVIRONMENT; + metadata: { + name: string; + slug: string; + }; +} + +interface AddWorkspaceMemberEvent { + type: EventType.ADD_WORKSPACE_MEMBER; + metadata: { + userId: string; + email: string; + }; +} + +interface AddBatchWorkspaceMemberEvent { + type: EventType.ADD_BATCH_WORKSPACE_MEMBER; + metadata: Array<{ + userId: string; + email: string; + }>; +} + +interface RemoveWorkspaceMemberEvent { + type: EventType.REMOVE_WORKSPACE_MEMBER; + metadata: { + userId: string; + email: string; + }; +} + +interface CreateFolderEvent { + type: EventType.CREATE_FOLDER; + metadata: { + environment: string; + folderId: string; + folderName: string; + folderPath: string; + }; +} + +interface UpdateFolderEvent { + type: EventType.UPDATE_FOLDER; + metadata: { + environment: string; + folderId: string; + oldFolderName: string; + newFolderName: string; + folderPath: string; + }; +} + +interface DeleteFolderEvent { + type: EventType.DELETE_FOLDER; + metadata: { + environment: string; + folderId: string; + folderName: string; + folderPath: string; + }; +} + +interface CreateWebhookEvent { + type: EventType.CREATE_WEBHOOK; + metadata: { + webhookId: string; + environment: string; + secretPath: string; + webhookUrl: string; + isDisabled: boolean; + }; +} + +interface UpdateWebhookStatusEvent { + type: EventType.UPDATE_WEBHOOK_STATUS; + metadata: { + webhookId: string; + environment: string; + secretPath: string; + webhookUrl: string; + isDisabled: boolean; + }; +} + +interface DeleteWebhookEvent { + type: EventType.DELETE_WEBHOOK; + metadata: { + webhookId: string; + environment: string; + secretPath: string; + webhookUrl: string; + isDisabled: boolean; + }; +} + +interface GetSecretImportsEvent { + type: EventType.GET_SECRET_IMPORTS; + metadata: { + environment: string; + secretImportId: string; + folderId: string; + numberOfImports: number; + }; +} + +interface CreateSecretImportEvent { + type: EventType.CREATE_SECRET_IMPORT; + metadata: { + secretImportId: string; + folderId: string; + importFromEnvironment: string; + importFromSecretPath: string; + importToEnvironment: string; + importToSecretPath: string; + }; +} + +interface UpdateSecretImportEvent { + type: EventType.UPDATE_SECRET_IMPORT; + metadata: { + secretImportId: string; + folderId: string; + importToEnvironment: string; + importToSecretPath: string; + orderBefore: { + environment: string; + secretPath: string; + }[]; + orderAfter: { + environment: string; + secretPath: string; + }[]; + }; +} + +interface DeleteSecretImportEvent { + type: EventType.DELETE_SECRET_IMPORT; + metadata: { + secretImportId: string; + folderId: string; + importFromEnvironment: string; + importFromSecretPath: string; + importToEnvironment: string; + importToSecretPath: string; + }; +} + +interface UpdateUserRole { + type: EventType.UPDATE_USER_WORKSPACE_ROLE; + metadata: { + userId: string; + email: string; + oldRole: string; + newRole: string; + }; +} + +interface UpdateUserDeniedPermissions { + type: EventType.UPDATE_USER_WORKSPACE_DENIED_PERMISSIONS; + metadata: { + userId: string; + email: string; + deniedPermissions: { + environmentSlug: string; + ability: string; + }[]; + }; +} +interface SecretApprovalMerge { + type: EventType.SECRET_APPROVAL_MERGED; + metadata: { + mergedBy: string; + secretApprovalRequestSlug: string; + secretApprovalRequestId: string; + }; +} + +interface SecretApprovalClosed { + type: EventType.SECRET_APPROVAL_CLOSED; + metadata: { + closedBy: string; + secretApprovalRequestSlug: string; + secretApprovalRequestId: string; + }; +} + +interface SecretApprovalReopened { + type: EventType.SECRET_APPROVAL_REOPENED; + metadata: { + reopenedBy: string; + secretApprovalRequestSlug: string; + secretApprovalRequestId: string; + }; +} + +interface SecretApprovalRequest { + type: EventType.SECRET_APPROVAL_REQUEST; + metadata: { + committedBy: string; + secretApprovalRequestSlug: string; + secretApprovalRequestId: string; + }; +} + +export type Event = + | GetSecretsEvent + | GetSecretEvent + | CreateSecretEvent + | CreateSecretBatchEvent + | UpdateSecretEvent + | UpdateSecretBatchEvent + | DeleteSecretEvent + | DeleteSecretBatchEvent + | GetWorkspaceKeyEvent + | AuthorizeIntegrationEvent + | UnauthorizeIntegrationEvent + | CreateIntegrationEvent + | DeleteIntegrationEvent + | AddTrustedIPEvent + | UpdateTrustedIPEvent + | DeleteTrustedIPEvent + | CreateServiceTokenEvent + | DeleteServiceTokenEvent + | CreateIdentityEvent + | UpdateIdentityEvent + | DeleteIdentityEvent + | LoginIdentityUniversalAuthEvent + | AddIdentityUniversalAuthEvent + | UpdateIdentityUniversalAuthEvent + | GetIdentityUniversalAuthEvent + | CreateIdentityUniversalAuthClientSecretEvent + | GetIdentityUniversalAuthClientSecretsEvent + | RevokeIdentityUniversalAuthClientSecretEvent + | CreateEnvironmentEvent + | UpdateEnvironmentEvent + | DeleteEnvironmentEvent + | AddWorkspaceMemberEvent + | AddBatchWorkspaceMemberEvent + | RemoveWorkspaceMemberEvent + | CreateFolderEvent + | UpdateFolderEvent + | DeleteFolderEvent + | CreateWebhookEvent + | UpdateWebhookStatusEvent + | DeleteWebhookEvent + | GetSecretImportsEvent + | CreateSecretImportEvent + | UpdateSecretImportEvent + | DeleteSecretImportEvent + | UpdateUserRole + | UpdateUserDeniedPermissions + | SecretApprovalMerge + | SecretApprovalClosed + | SecretApprovalRequest + | SecretApprovalReopened; diff --git a/pg-migrator/src/models/backupPrivateKey.ts b/pg-migrator/src/models/backupPrivateKey.ts new file mode 100644 index 000000000..09df1dda7 --- /dev/null +++ b/pg-migrator/src/models/backupPrivateKey.ts @@ -0,0 +1,74 @@ +import { Schema, Types, model } from "mongoose"; +import { + ALGORITHM_AES_256_GCM, + ENCODING_SCHEME_BASE64, + ENCODING_SCHEME_UTF8, +} from "../variables"; + +export interface IBackupPrivateKey { + _id: Types.ObjectId; + user: Types.ObjectId; + encryptedPrivateKey: string; + iv: string; + tag: string; + salt: string; + algorithm: string; + keyEncoding: "base64" | "utf8"; + verifier: string; +} + +const backupPrivateKeySchema = new Schema( + { + user: { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + encryptedPrivateKey: { + type: String, + select: false, + required: true, + }, + iv: { + type: String, + select: false, + required: true, + }, + tag: { + type: String, + select: false, + required: true, + }, + algorithm: { // the encryption algorithm used + type: String, + enum: [ALGORITHM_AES_256_GCM], + required: true, + }, + keyEncoding: { + type: String, + enum: [ + ENCODING_SCHEME_UTF8, + ENCODING_SCHEME_BASE64, + ], + required: true, + }, + salt: { + type: String, + select: false, + required: true, + }, + verifier: { + type: String, + select: false, + required: true, + }, + }, + { + timestamps: true, + } +); + +export const BackupPrivateKey = model( + "BackupPrivateKey", + backupPrivateKeySchema +); diff --git a/pg-migrator/src/models/bot.ts b/pg-migrator/src/models/bot.ts new file mode 100644 index 000000000..5a5c83b13 --- /dev/null +++ b/pg-migrator/src/models/bot.ts @@ -0,0 +1,77 @@ +import { Schema, Types, model } from "mongoose"; +import { + ALGORITHM_AES_256_GCM, + ENCODING_SCHEME_BASE64, + ENCODING_SCHEME_UTF8, +} from "../variables"; + +export interface IBot { + _id: Types.ObjectId; + name: string; + workspace: Types.ObjectId; + isActive: boolean; + publicKey: string; + encryptedPrivateKey: string; + iv: string; + tag: string; + algorithm: "aes-256-gcm"; + keyEncoding: "base64" | "utf8"; +} + +const botSchema = new Schema( + { + name: { + type: String, + required: true, + }, + workspace: { + type: Schema.Types.ObjectId, + ref: "Workspace", + required: true, + }, + isActive: { + type: Boolean, + required: true, + default: false, + }, + publicKey: { + type: String, + required: true, + }, + encryptedPrivateKey: { + type: String, + required: true, + select: false, + }, + iv: { + type: String, + required: true, + select: false, + }, + tag: { + type: String, + required: true, + select: false, + }, + algorithm: { // the encryption algorithm used + type: String, + enum: [ALGORITHM_AES_256_GCM], + required: true, + select: false, + }, + keyEncoding: { + type: String, + enum: [ + ENCODING_SCHEME_UTF8, + ENCODING_SCHEME_BASE64, + ], + required: true, + select: false, + }, + }, + { + timestamps: true, + } +); + +export const Bot = model("Bot", botSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/botKey.ts b/pg-migrator/src/models/botKey.ts new file mode 100644 index 000000000..02a6d6ea9 --- /dev/null +++ b/pg-migrator/src/models/botKey.ts @@ -0,0 +1,43 @@ +import { Schema, Types, model } from "mongoose"; + +export interface IBotKey { + _id: Types.ObjectId; + encryptedKey: string; + nonce: string; + sender: Types.ObjectId; + bot: Types.ObjectId; + workspace: Types.ObjectId; +} + +const botKeySchema = new Schema( + { + encryptedKey: { + type: String, + required: true, + }, + nonce: { + type: String, + required: true, + }, + sender: { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + bot: { + type: Schema.Types.ObjectId, + ref: "Bot", + required: true, + }, + workspace: { + type: Schema.Types.ObjectId, + ref: "Workspace", + required: true, + }, + }, + { + timestamps: true, + } +); + +export const BotKey = model("BotKey", botKeySchema); \ No newline at end of file diff --git a/pg-migrator/src/models/botOrg.ts b/pg-migrator/src/models/botOrg.ts new file mode 100644 index 000000000..177294ef9 --- /dev/null +++ b/pg-migrator/src/models/botOrg.ts @@ -0,0 +1,96 @@ +import { Schema, Types, model } from "mongoose"; +import { + ALGORITHM_AES_256_GCM, + ENCODING_SCHEME_BASE64, + ENCODING_SCHEME_UTF8, +} from "../variables"; + +export interface IBotOrg { + _id: Types.ObjectId; + name: string; + organization: Types.ObjectId; + publicKey: string; + encryptedSymmetricKey: string; + symmetricKeyIV: string; + symmetricKeyTag: string; + symmetricKeyAlgorithm: "aes-256-gcm"; + symmetricKeyKeyEncoding: "base64" | "utf8"; + encryptedPrivateKey: string; + privateKeyIV: string; + privateKeyTag: string; + privateKeyAlgorithm: "aes-256-gcm"; + privateKeyKeyEncoding: "base64" | "utf8"; +} + +const botOrgSchema = new Schema( + { + name: { + type: String, + required: true, + }, + organization: { + type: Schema.Types.ObjectId, + ref: "Organization", + required: true, + }, + publicKey: { + type: String, + required: true, + }, + encryptedSymmetricKey: { + type: String, + required: true + }, + symmetricKeyIV: { + type: String, + required: true + }, + symmetricKeyTag: { + type: String, + required: true + }, + symmetricKeyAlgorithm: { + type: String, + enum: [ALGORITHM_AES_256_GCM], + required: true + }, + symmetricKeyKeyEncoding: { + type: String, + enum: [ + ENCODING_SCHEME_UTF8, + ENCODING_SCHEME_BASE64, + ], + required: true + }, + encryptedPrivateKey: { + type: String, + required: true + }, + privateKeyIV: { + type: String, + required: true + }, + privateKeyTag: { + type: String, + required: true + }, + privateKeyAlgorithm: { + type: String, + enum: [ALGORITHM_AES_256_GCM], + required: true + }, + privateKeyKeyEncoding: { + type: String, + enum: [ + ENCODING_SCHEME_UTF8, + ENCODING_SCHEME_BASE64, + ], + required: true + }, + }, + { + timestamps: true, + } +); + +export const BotOrg = model("BotOrg", botOrgSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/folder.ts b/pg-migrator/src/models/folder.ts new file mode 100644 index 000000000..b3016822d --- /dev/null +++ b/pg-migrator/src/models/folder.ts @@ -0,0 +1,54 @@ +import { Schema, Types, model } from "mongoose"; + +export type TFolderRootSchema = { + _id: Types.ObjectId; + workspace: Types.ObjectId; + environment: string; + nodes: TFolderSchema; +}; + +export type TFolderSchema = { + id: string; + name: string; + version: number; + children: TFolderSchema[]; +}; + +const folderSchema = new Schema({ + id: { + required: true, + type: String, + }, + version: { + required: true, + type: Number, + default: 1, + }, + name: { + required: true, + type: String, + default: "root", + }, +}); + +folderSchema.add({ children: [folderSchema] }); + +const folderRootSchema = new Schema( + { + workspace: { + type: Schema.Types.ObjectId, + ref: "Workspace", + required: true, + }, + environment: { + type: String, + required: true, + }, + nodes: folderSchema, + }, + { + timestamps: true, + } +); + +export const Folder = model("Folder", folderRootSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/folderVersion.ts b/pg-migrator/src/models/folderVersion.ts new file mode 100644 index 000000000..dbcebcb92 --- /dev/null +++ b/pg-migrator/src/models/folderVersion.ts @@ -0,0 +1,58 @@ +import { Schema, Types, model } from "mongoose"; + +export type TFolderRootVersionSchema = { + _id: Types.ObjectId; + workspace: Types.ObjectId; + environment: string; + nodes: TFolderVersionSchema; +}; + +export type TFolderVersionSchema = { + id: string; + name: string; + version: number; + children: TFolderVersionSchema[]; +}; + +const folderVersionSchema = new Schema({ + id: { + required: true, + type: String, + default: "root", + }, + name: { + required: true, + type: String, + default: "root", + }, + version: { + required: true, + type: Number, + default: 1, + }, +}); + +folderVersionSchema.add({ children: [folderVersionSchema] }); + +const folderRootVersionSchema = new Schema( + { + workspace: { + type: Schema.Types.ObjectId, + ref: "Workspace", + required: true, + }, + environment: { + type: String, + required: true, + }, + nodes: folderVersionSchema, + }, + { + timestamps: true, + } +); + +export const FolderVersion = model( + "FolderVersion", + folderRootVersionSchema +); \ No newline at end of file diff --git a/pg-migrator/src/models/gitAppInstallationSession.ts b/pg-migrator/src/models/gitAppInstallationSession.ts new file mode 100644 index 000000000..0cdf8df3c --- /dev/null +++ b/pg-migrator/src/models/gitAppInstallationSession.ts @@ -0,0 +1,32 @@ +import { Schema, Types, model } from "mongoose"; + +type GitAppInstallationSession = { + id: string; + sessionId: string; + organization: Types.ObjectId; + user: Types.ObjectId; +} + +const gitAppInstallationSession = new Schema({ + id: { + required: true, + type: String, + }, + sessionId: { + type: String, + required: true, + unique: true + }, + organization: { + type: Schema.Types.ObjectId, + required: true, + unique: true + }, + user: { + type: Schema.Types.ObjectId, + ref: "User" + } +}); + + +export const GitAppInstallationSession = model("git_app_installation_session", gitAppInstallationSession); \ No newline at end of file diff --git a/pg-migrator/src/models/gitAppOrganizationInstallation.ts b/pg-migrator/src/models/gitAppOrganizationInstallation.ts new file mode 100644 index 000000000..4ce55b0cb --- /dev/null +++ b/pg-migrator/src/models/gitAppOrganizationInstallation.ts @@ -0,0 +1,29 @@ +import { Schema, model } from "mongoose"; + +type Installation = { + installationId: string + organizationId: string + user: Schema.Types.ObjectId +}; + + +const gitAppOrganizationInstallation = new Schema({ + installationId: { + type: String, + required: true, + unique: true + }, + organizationId: { + type: String, + required: true, + unique: true + }, + user: { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + } +}); + + +export const GitAppOrganizationInstallation = model("git_app_organization_installation", gitAppOrganizationInstallation); \ No newline at end of file diff --git a/pg-migrator/src/models/gitRisks.ts b/pg-migrator/src/models/gitRisks.ts new file mode 100644 index 000000000..8d3f59208 --- /dev/null +++ b/pg-migrator/src/models/gitRisks.ts @@ -0,0 +1,150 @@ +import { Schema, model } from "mongoose"; + +export const STATUS_RESOLVED_FALSE_POSITIVE = "RESOLVED_FALSE_POSITIVE"; +export const STATUS_RESOLVED_REVOKED = "RESOLVED_REVOKED"; +export const STATUS_RESOLVED_NOT_REVOKED = "RESOLVED_NOT_REVOKED"; +export const STATUS_UNRESOLVED = "UNRESOLVED"; + +export type IGitRisks = { + id: string; + description: string; + startLine: string; + endLine: string; + startColumn: string; + endColumn: string; + match: string; + secret: string; + file: string; + symlinkFile: string; + commit: string; + entropy: string; + author: string; + email: string; + date: string; + message: string; + tags: string[]; + ruleID: string; + fingerprint: string; + fingerPrintWithoutCommitId: string + + isFalsePositive: boolean; // New field for marking risks as false positives + isResolved: boolean; // New field for marking risks as resolved + riskOwner: string | null; // New field for setting a risk owner (nullable string) + installationId: string, + repositoryId: string, + repositoryLink: string + repositoryFullName: string + status: string + pusher: { + name: string, + email: string + }, + organization: Schema.Types.ObjectId, +} + +const gitRisks = new Schema({ + id: { + type: String, + }, + description: { + type: String, + }, + startLine: { + type: String, + }, + endLine: { + type: String, + }, + startColumn: { + type: String, + }, + endColumn: { + type: String, + }, + file: { + type: String, + }, + symlinkFile: { + type: String, + }, + commit: { + type: String, + }, + entropy: { + type: String, + }, + author: { + type: String, + }, + email: { + type: String, + }, + date: { + type: String, + }, + message: { + type: String, + }, + tags: { + type: [String], + }, + ruleID: { + type: String, + }, + fingerprint: { + type: String, + unique: true + }, + fingerPrintWithoutCommitId: { + type: String, + }, + isFalsePositive: { + type: Boolean, + default: false + }, + isResolved: { + type: Boolean, + default: false + }, + riskOwner: { + type: String, + default: null + }, + installationId: { + type: String, + require: true + }, + repositoryId: { + type: String + }, + repositoryLink: { + type: String + }, + repositoryFullName: { + type: String + }, + pusher: { + name: { + type: String + }, + email: { + type: String + }, + }, + organization: { + type: Schema.Types.ObjectId, + ref: "Organization", + }, + status: { + type: String, + enum: [ + STATUS_RESOLVED_FALSE_POSITIVE, + STATUS_RESOLVED_REVOKED, + STATUS_RESOLVED_NOT_REVOKED, + STATUS_UNRESOLVED + ], + default: STATUS_UNRESOLVED + } +}, { timestamps: true }); + +export const GitRisks = model("GitRisks", gitRisks); \ No newline at end of file diff --git a/pg-migrator/src/models/identity.ts b/pg-migrator/src/models/identity.ts new file mode 100644 index 000000000..ec4948e1b --- /dev/null +++ b/pg-migrator/src/models/identity.ts @@ -0,0 +1,38 @@ +import { Document, Schema, Types, model } from "mongoose"; +import { IPType } from "../ee/models"; + +export interface IIdentityTrustedIp { + ipAddress: string; + type: IPType; + prefix: number; +} + +export enum IdentityAuthMethod { + UNIVERSAL_AUTH = "universal-auth" +} + +export interface IIdentity extends Document { + _id: Types.ObjectId; + name: string; + authMethod?: IdentityAuthMethod; +} + +const identitySchema = new Schema( + { + name: { + type: String, + required: true + }, + authMethod: { + type: String, + enum: IdentityAuthMethod, + required: false, + }, + + }, + { + timestamps: true + } +); + +export const Identity = model("Identity", identitySchema); diff --git a/pg-migrator/src/models/identityAccessToken.ts b/pg-migrator/src/models/identityAccessToken.ts new file mode 100644 index 000000000..82b2e6778 --- /dev/null +++ b/pg-migrator/src/models/identityAccessToken.ts @@ -0,0 +1,104 @@ +import { Document, Schema, Types, model } from "mongoose"; +import { IIdentityTrustedIp } from "./identity"; +import { IPType } from "../ee/models/trustedIp"; + +export interface IIdentityAccessToken extends Document { + _id: Types.ObjectId; + identity: Types.ObjectId; + identityUniversalAuthClientSecret?: Types.ObjectId; + accessTokenLastUsedAt?: Date; + accessTokenLastRenewedAt?: Date; + accessTokenNumUses: number; + accessTokenNumUsesLimit: number; + accessTokenTTL: number; + accessTokenMaxTTL: number; + accessTokenTrustedIps: Array; + isAccessTokenRevoked: boolean; + updatedAt: Date; + createdAt: Date; +} + +const identityAccessTokenSchema = new Schema( + { + identity: { + type: Schema.Types.ObjectId, + ref: "Identity", + required: false + }, + identityUniversalAuthClientSecret: { + type: Schema.Types.ObjectId, + ref: "IdentityUniversalAuthClientSecret", + required: false + }, + accessTokenLastUsedAt: { + type: Date, + required: false + }, + accessTokenLastRenewedAt: { + type: Date, + required: false + }, + accessTokenNumUses: { + // number of times access token has been used + type: Number, + default: 0, + required: true + }, + accessTokenNumUsesLimit: { + // number of times access token can be used for + type: Number, + default: 0, // default: used as many times as needed + required: true + }, + accessTokenTTL: { // seconds + // incremental lifetime + type: Number, + default: 2592000, // 30 days + required: true + }, + accessTokenMaxTTL: { // seconds + // max lifetime + type: Number, + default: 2592000, // 30 days + required: true + }, + accessTokenTrustedIps: { + type: [ + { + ipAddress: { + type: String, + required: true + }, + type: { + type: String, + enum: [ + IPType.IPV4, + IPType.IPV6 + ], + required: true + }, + prefix: { + type: Number, + required: false + } + } + ], + default: [{ + ipAddress: "0.0.0.0", + type: IPType.IPV4.toString(), + prefix: 0 + }], + required: true + }, + isAccessTokenRevoked: { + type: Boolean, + default: false, + required: true + }, + }, + { + timestamps: true + } +); + +export const IdentityAccessToken = model("IdentityAccessToken", identityAccessTokenSchema); diff --git a/pg-migrator/src/models/identityMembership.ts b/pg-migrator/src/models/identityMembership.ts new file mode 100644 index 000000000..4fedfe909 --- /dev/null +++ b/pg-migrator/src/models/identityMembership.ts @@ -0,0 +1,39 @@ +import { Schema, Types, model } from "mongoose"; +import { ADMIN, CUSTOM, MEMBER, NO_ACCESS, VIEWER } from "../variables"; + +export interface IIdentityMembership { + _id: Types.ObjectId; + identity: Types.ObjectId; + workspace: Types.ObjectId; + role: "admin" | "member" | "viewer" | "no-access" | "custom"; + customRole: Types.ObjectId; +} + +const identityMembershipSchema = new Schema( + { + identity: { + type: Schema.Types.ObjectId, + ref: "Identity" + }, + workspace: { + type: Schema.Types.ObjectId, + ref: "Workspace", + required: true, + index: true, + }, + role: { + type: String, + enum: [ADMIN, MEMBER, VIEWER, CUSTOM, NO_ACCESS], + required: true + }, + customRole: { + type: Schema.Types.ObjectId, + ref: "Role" + } + }, + { + timestamps: true + } +); + +export const IdentityMembership = model("IdentityMembership", identityMembershipSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/identityMembershipOrg.ts b/pg-migrator/src/models/identityMembershipOrg.ts new file mode 100644 index 000000000..8da8693c4 --- /dev/null +++ b/pg-migrator/src/models/identityMembershipOrg.ts @@ -0,0 +1,37 @@ +import { Schema, Types, model } from "mongoose"; +import { ADMIN, CUSTOM, MEMBER, NO_ACCESS} from "../variables"; + +export interface IIdentityMembershipOrg { + _id: Types.ObjectId; + identity: Types.ObjectId; + organization: Types.ObjectId; + role: "admin" | "member" | "no-access" | "custom"; + customRole: Types.ObjectId; +} + +const identityMembershipOrgSchema = new Schema( + { + identity: { + type: Schema.Types.ObjectId, + ref: "Identity" + }, + organization: { + type: Schema.Types.ObjectId, + ref: "Organization" + }, + role: { + type: String, + enum: [ADMIN, MEMBER, NO_ACCESS, CUSTOM], + required: true + }, + customRole: { + type: Schema.Types.ObjectId, + ref: "Role" + } + }, + { + timestamps: true + } +); + +export const IdentityMembershipOrg = model("IdentityMembershipOrg", identityMembershipOrgSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/identityUniversalAuth.ts b/pg-migrator/src/models/identityUniversalAuth.ts new file mode 100644 index 000000000..89fb46a95 --- /dev/null +++ b/pg-migrator/src/models/identityUniversalAuth.ts @@ -0,0 +1,107 @@ +import { Document, Schema, Types, model } from "mongoose"; +import { IPType } from "../ee/models"; +import { IIdentityTrustedIp } from "./identity"; + +export interface IIdentityUniversalAuth extends Document { + _id: Types.ObjectId; + identity: Types.ObjectId; + clientId: string; + clientSecretTrustedIps: Array; + accessTokenTTL: number; + accessTokenMaxTTL: number; + accessTokenNumUsesLimit: number; + accessTokenTrustedIps: Array; +} + +const identityUniversalAuthSchema = new Schema( + { + identity: { + type: Schema.Types.ObjectId, + ref: "Identity", + required: true + }, + clientId: { + type: String, + required: true + }, + clientSecretTrustedIps: { + type: [ + { + ipAddress: { + type: String, + required: true + }, + type: { + type: String, + enum: [ + IPType.IPV4, + IPType.IPV6 + ], + required: true + }, + prefix: { + type: Number, + required: false + } + } + ], + default: [{ + ipAddress: "0.0.0.0", + type: IPType.IPV4.toString(), + prefix: 0 + }], + required: true + }, + accessTokenTTL: { // seconds + // incremental lifetime + type: Number, + default: 7200, + required: true + }, + accessTokenMaxTTL: { // seconds + // max lifetime + type: Number, + default: 7200, + required: true + }, + accessTokenNumUsesLimit: { + // number of times access token can be used for + type: Number, + default: 0, // default: used as many times as needed + required: true + }, + accessTokenTrustedIps: { + type: [ + { + ipAddress: { + type: String, + required: true + }, + type: { + type: String, + enum: [ + IPType.IPV4, + IPType.IPV6 + ], + required: true + }, + prefix: { + type: Number, + required: false + } + } + ], + default: [{ + ipAddress: "0.0.0.0", + type: IPType.IPV4.toString(), + prefix: 0 + }], + required: true + } + }, + { + timestamps: true + } +); + +export const IdentityUniversalAuth = model("IdentityUniversalAuth", identityUniversalAuthSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/identityUniversalAuthClientSecret.ts b/pg-migrator/src/models/identityUniversalAuthClientSecret.ts new file mode 100644 index 000000000..af9cc08a4 --- /dev/null +++ b/pg-migrator/src/models/identityUniversalAuthClientSecret.ts @@ -0,0 +1,81 @@ +import { Document, Schema, Types, model } from "mongoose"; + +export interface IIdentityUniversalAuthClientSecret extends Document { + _id: Types.ObjectId; + identity: Types.ObjectId; + identityUniversalAuth : Types.ObjectId; + description: string; + clientSecretPrefix: string; + clientSecretHash: string; + clientSecretLastUsedAt?: Date; + clientSecretNumUses: number; + clientSecretNumUsesLimit: number; + clientSecretTTL: number; + updatedAt: Date; + createdAt: Date; + isClientSecretRevoked: boolean; +} + +const identityUniversalAuthClientSecretSchema = new Schema( + { + identity: { + type: Schema.Types.ObjectId, + ref: "Identity", + required: true + }, + identityUniversalAuth: { + type: Schema.Types.ObjectId, + ref: "IdentityUniversalAuth", + required: true + }, + description: { + type: String, + required: true + }, + clientSecretPrefix: { + type: String, + required: true + }, + clientSecretHash: { + type: String, + required: true + }, + clientSecretLastUsedAt: { + type: Date, + required: false + }, + clientSecretNumUses: { + // number of times client secret has been used + // in login operation + type: Number, + default: 0, + required: true + }, + clientSecretNumUsesLimit: { + // number of times client secret can be used for + // a login operation + type: Number, + default: 0, // default: used as many times as needed + required: true + }, + clientSecretTTL: { + type: Number, + default: 0, // default: does not expire + required: true + }, + isClientSecretRevoked: { + type: Boolean, + default: false, + required: true + } + }, + { + timestamps: true + } +); + +identityUniversalAuthClientSecretSchema.index( + { identityUniversalAuth: 1, isClientSecretRevoked: 1 } +); + +export const IdentityUniversalAuthClientSecret = model("IdentityUniversalAuthClientSecret", identityUniversalAuthClientSecretSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/incidentContactOrg.ts b/pg-migrator/src/models/incidentContactOrg.ts new file mode 100644 index 000000000..905b9263f --- /dev/null +++ b/pg-migrator/src/models/incidentContactOrg.ts @@ -0,0 +1,29 @@ +import { Schema, Types, model } from "mongoose"; + +export interface IIncidentContactOrg { + _id: Types.ObjectId; + email: string; + organization: Types.ObjectId; +} + +const incidentContactOrgSchema = new Schema( + { + email: { + type: String, + required: true, + }, + organization: { + type: Schema.Types.ObjectId, + ref: "Organization", + required: true, + }, + }, + { + timestamps: true, + } +); + +export const IncidentContactOrg = model( + "IncidentContactOrg", + incidentContactOrgSchema +); \ No newline at end of file diff --git a/pg-migrator/src/models/index.ts b/pg-migrator/src/models/index.ts new file mode 100644 index 000000000..2489e30f5 --- /dev/null +++ b/pg-migrator/src/models/index.ts @@ -0,0 +1,49 @@ +export * from "./backupPrivateKey"; +export * from "./bot"; +export * from "./botOrg"; +export * from "./botKey"; +export * from "./incidentContactOrg"; +export * from "./integration/integration"; +export * from "./integrationAuth"; +export * from "./key"; +export * from "./membership"; +export * from "./membershipOrg"; +export * from "./organization"; +export * from "./secret"; +export * from "./tag"; +export * from "./folder"; +export * from "./secretImports"; +export * from "./secretBlindIndexData"; +export * from "./serviceToken"; // TODO: deprecate +export * from "./tokenData"; +export * from "./user"; +export * from "./userAction"; +export * from "./workspace"; +export * from "./serviceTokenData"; // TODO: deprecate + +// new +export * from "./identity"; +export * from "./identityMembership"; +export * from "./identityMembershipOrg"; +export * from "./identityUniversalAuth"; +export * from "./identityUniversalAuthClientSecret"; +export * from "./identityAccessToken"; + +export * from "./apiKeyData"; // TODO: deprecate +export * from "./apiKeyDataV2"; +export * from "./loginSRPDetail"; +export * from "./tokenVersion"; +export * from "./webhooks"; + +export * from "./secretSnapshot"; +export * from "./secretVersion"; +export * from "./folderVersion"; +export * from "./role"; +export * from "./ssoConfig"; +export * from "./trustedIp"; +export * from "./auditLog"; +export * from "./gitRisks"; +export * from "./gitAppOrganizationInstallation"; +export * from "./gitAppInstallationSession"; +export * from "./secretApprovalPolicy"; +export * from "./secretApprovalRequest"; diff --git a/pg-migrator/src/models/integration/index.ts b/pg-migrator/src/models/integration/index.ts new file mode 100644 index 000000000..2ed44cd28 --- /dev/null +++ b/pg-migrator/src/models/integration/index.ts @@ -0,0 +1 @@ +export * from "./integration"; \ No newline at end of file diff --git a/pg-migrator/src/models/integration/integration.ts b/pg-migrator/src/models/integration/integration.ts new file mode 100644 index 000000000..eaaadec92 --- /dev/null +++ b/pg-migrator/src/models/integration/integration.ts @@ -0,0 +1,216 @@ +import { + INTEGRATION_AWS_PARAMETER_STORE, + INTEGRATION_AWS_SECRET_MANAGER, + INTEGRATION_AZURE_KEY_VAULT, + INTEGRATION_BITBUCKET, + INTEGRATION_CHECKLY, + INTEGRATION_CIRCLECI, + INTEGRATION_CLOUDFLARE_PAGES, + INTEGRATION_CLOUDFLARE_WORKERS, + INTEGRATION_CLOUD_66, + INTEGRATION_CODEFRESH, + INTEGRATION_DIGITAL_OCEAN_APP_PLATFORM, + INTEGRATION_FLYIO, + INTEGRATION_GCP_SECRET_MANAGER, + INTEGRATION_GITHUB, + INTEGRATION_GITLAB, + INTEGRATION_HASHICORP_VAULT, + INTEGRATION_HASURA_CLOUD, + INTEGRATION_HEROKU, + INTEGRATION_LARAVELFORGE, + INTEGRATION_NETLIFY, + INTEGRATION_NORTHFLANK, + INTEGRATION_QOVERY, + INTEGRATION_RAILWAY, + INTEGRATION_RENDER, + INTEGRATION_SUPABASE, + INTEGRATION_TEAMCITY, + INTEGRATION_TERRAFORM_CLOUD, + INTEGRATION_TRAVISCI, + INTEGRATION_VERCEL, + INTEGRATION_WINDMILL +} from "../../variables"; +import { Schema, Types, model } from "mongoose"; +import { Metadata } from "./types"; + +export interface IIntegration { + _id: Types.ObjectId; + workspace: Types.ObjectId; + environment: string; + isActive: boolean; + url: string; + app: string; + appId: string; + owner: string; + targetEnvironment: string; + targetEnvironmentId: string; + targetService: string; + targetServiceId: string; + path: string; + region: string; + scope: string; + secretPath: string; + integration: + | "azure-key-vault" + | "aws-parameter-store" + | "aws-secret-manager" + | "heroku" + | "vercel" + | "netlify" + | "github" + | "gitlab" + | "render" + | "railway" + | "flyio" + | "circleci" + | "laravel-forge" + | "travisci" + | "supabase" + | "checkly" + | "qovery" + | "terraform-cloud" + | "teamcity" + | "hashicorp-vault" + | "cloudflare-pages" + | "cloudflare-workers" + | "bitbucket" + | "codefresh" + | "digital-ocean-app-platform" + | "cloud-66" + | "northflank" + | "windmill" + | "gcp-secret-manager" + | "hasura-cloud"; + integrationAuth: Types.ObjectId; + metadata: Metadata; +} + +const integrationSchema = new Schema( + { + workspace: { + type: Schema.Types.ObjectId, + ref: "Workspace", + required: true + }, + environment: { + type: String, + required: true + }, + isActive: { + type: Boolean, + required: true + }, + url: { + // for custom self-hosted integrations (e.g. self-hosted GitHub enterprise) + type: String, + default: null + }, + app: { + // name of app in provider + type: String, + default: null + }, + appId: { + // id of app in provider + type: String, + default: null + }, + targetEnvironment: { + // target environment + type: String, + default: null + }, + targetEnvironmentId: { + type: String, + default: null + }, + targetService: { + // railway-specific service + // qovery-specific project + type: String, + default: null + }, + targetServiceId: { + // railway-specific service + // qovery specific project + type: String, + default: null + }, + owner: { + // github-specific repo owner-login + type: String, + default: null + }, + path: { + // aws-parameter-store-specific path + // (also) vercel preview-branch + type: String, + default: null + }, + region: { + // aws-parameter-store-specific path + type: String, + default: null + }, + scope: { + // qovery-specific scope + type: String, + default: null + }, + integration: { + type: String, + enum: [ + INTEGRATION_AZURE_KEY_VAULT, + INTEGRATION_AWS_PARAMETER_STORE, + INTEGRATION_AWS_SECRET_MANAGER, + INTEGRATION_HEROKU, + INTEGRATION_VERCEL, + INTEGRATION_NETLIFY, + INTEGRATION_GITHUB, + INTEGRATION_GITLAB, + INTEGRATION_RENDER, + INTEGRATION_RAILWAY, + INTEGRATION_FLYIO, + INTEGRATION_CIRCLECI, + INTEGRATION_LARAVELFORGE, + INTEGRATION_TRAVISCI, + INTEGRATION_SUPABASE, + INTEGRATION_CHECKLY, + INTEGRATION_QOVERY, + INTEGRATION_TERRAFORM_CLOUD, + INTEGRATION_TEAMCITY, + INTEGRATION_HASHICORP_VAULT, + INTEGRATION_CLOUDFLARE_PAGES, + INTEGRATION_CLOUDFLARE_WORKERS, + INTEGRATION_CODEFRESH, + INTEGRATION_WINDMILL, + INTEGRATION_BITBUCKET, + INTEGRATION_DIGITAL_OCEAN_APP_PLATFORM, + INTEGRATION_CLOUD_66, + INTEGRATION_NORTHFLANK, + INTEGRATION_GCP_SECRET_MANAGER, + INTEGRATION_HASURA_CLOUD + ], + required: true + }, + integrationAuth: { + type: Schema.Types.ObjectId, + ref: "IntegrationAuth", + required: true + }, + secretPath: { + type: String, + required: true, + default: "/" + }, + metadata: { + type: Schema.Types.Mixed, + default: {} + } + }, + { + timestamps: true + } +); + +export const Integration = model("Integration", integrationSchema); diff --git a/pg-migrator/src/models/integration/types.ts b/pg-migrator/src/models/integration/types.ts new file mode 100644 index 000000000..5c4387bba --- /dev/null +++ b/pg-migrator/src/models/integration/types.ts @@ -0,0 +1,8 @@ +export type Metadata = { + secretPrefix?: string; + secretSuffix?: string; + secretGCPLabel?: { + labelName: string; + labelValue: string; + } +} \ No newline at end of file diff --git a/pg-migrator/src/models/integrationAuth/index.ts b/pg-migrator/src/models/integrationAuth/index.ts new file mode 100644 index 000000000..157095bd2 --- /dev/null +++ b/pg-migrator/src/models/integrationAuth/index.ts @@ -0,0 +1 @@ +export * from "./integrationAuth"; \ No newline at end of file diff --git a/pg-migrator/src/models/integrationAuth/integrationAuth.ts b/pg-migrator/src/models/integrationAuth/integrationAuth.ts new file mode 100644 index 000000000..da1e57268 --- /dev/null +++ b/pg-migrator/src/models/integrationAuth/integrationAuth.ts @@ -0,0 +1,206 @@ +import { + ALGORITHM_AES_256_GCM, + ENCODING_SCHEME_BASE64, + ENCODING_SCHEME_UTF8, + INTEGRATION_AWS_PARAMETER_STORE, + INTEGRATION_AWS_SECRET_MANAGER, + INTEGRATION_AZURE_KEY_VAULT, + INTEGRATION_BITBUCKET, + INTEGRATION_CIRCLECI, + INTEGRATION_CLOUDFLARE_PAGES, + INTEGRATION_CLOUDFLARE_WORKERS, + INTEGRATION_CLOUD_66, + INTEGRATION_CODEFRESH, + INTEGRATION_DIGITAL_OCEAN_APP_PLATFORM, + INTEGRATION_FLYIO, + INTEGRATION_GCP_SECRET_MANAGER, + INTEGRATION_GITHUB, + INTEGRATION_GITLAB, + INTEGRATION_HASHICORP_VAULT, + INTEGRATION_HASURA_CLOUD, + INTEGRATION_HEROKU, + INTEGRATION_LARAVELFORGE, + INTEGRATION_NETLIFY, + INTEGRATION_NORTHFLANK, + INTEGRATION_RAILWAY, + INTEGRATION_RENDER, + INTEGRATION_SUPABASE, + INTEGRATION_TEAMCITY, + INTEGRATION_TERRAFORM_CLOUD, + INTEGRATION_TRAVISCI, + INTEGRATION_VERCEL, + INTEGRATION_WINDMILL +} from "../../variables"; +import { Document, Schema, Types, model } from "mongoose"; +import { IntegrationAuthMetadata } from "./types"; + +export interface IIntegrationAuth extends Document { + _id: Types.ObjectId; + workspace: Types.ObjectId; + integration: + | "heroku" + | "vercel" + | "netlify" + | "github" + | "gitlab" + | "render" + | "railway" + | "flyio" + | "azure-key-vault" + | "laravel-forge" + | "circleci" + | "travisci" + | "supabase" + | "aws-parameter-store" + | "aws-secret-manager" + | "checkly" + | "qovery" + | "cloudflare-pages" + | "cloudflare-workers" + | "codefresh" + | "digital-ocean-app-platform" + | "bitbucket" + | "cloud-66" + | "terraform-cloud" + | "teamcity" + | "northflank" + | "windmill" + | "gcp-secret-manager" + | "hasura-cloud"; + teamId: string; + accountId: string; + url: string; + namespace: string; + refreshCiphertext?: string; + refreshIV?: string; + refreshTag?: string; + accessIdCiphertext?: string; + accessIdIV?: string; + accessIdTag?: string; + accessCiphertext?: string; + accessIV?: string; + accessTag?: string; + algorithm?: "aes-256-gcm"; + keyEncoding?: "utf8" | "base64"; + accessExpiresAt?: Date; + metadata?: IntegrationAuthMetadata; +} + +const integrationAuthSchema = new Schema( + { + workspace: { + type: Schema.Types.ObjectId, + ref: "Workspace", + required: true + }, + integration: { + type: String, + enum: [ + INTEGRATION_AZURE_KEY_VAULT, + INTEGRATION_AWS_PARAMETER_STORE, + INTEGRATION_AWS_SECRET_MANAGER, + INTEGRATION_HEROKU, + INTEGRATION_VERCEL, + INTEGRATION_NETLIFY, + INTEGRATION_GITHUB, + INTEGRATION_GITLAB, + INTEGRATION_RENDER, + INTEGRATION_RAILWAY, + INTEGRATION_FLYIO, + INTEGRATION_CIRCLECI, + INTEGRATION_LARAVELFORGE, + INTEGRATION_TRAVISCI, + INTEGRATION_TEAMCITY, + INTEGRATION_SUPABASE, + INTEGRATION_TERRAFORM_CLOUD, + INTEGRATION_HASHICORP_VAULT, + INTEGRATION_CLOUDFLARE_PAGES, + INTEGRATION_CLOUDFLARE_WORKERS, + INTEGRATION_CODEFRESH, + INTEGRATION_WINDMILL, + INTEGRATION_BITBUCKET, + INTEGRATION_DIGITAL_OCEAN_APP_PLATFORM, + INTEGRATION_CLOUD_66, + INTEGRATION_NORTHFLANK, + INTEGRATION_GCP_SECRET_MANAGER, + INTEGRATION_HASURA_CLOUD + ], + required: true + }, + teamId: { + // vercel-specific integration param + type: String + }, + url: { + // for any self-hosted integrations (e.g. self-hosted hashicorp-vault) + type: String + }, + namespace: { + // hashicorp-vault-specific integration param + type: String + }, + accountId: { + // netlify-specific integration param + type: String + }, + refreshCiphertext: { + type: String, + select: false + }, + refreshIV: { + type: String, + select: false + }, + refreshTag: { + type: String, + select: false + }, + accessIdCiphertext: { + type: String, + select: false + }, + accessIdIV: { + type: String, + select: false + }, + accessIdTag: { + type: String, + select: false + }, + accessCiphertext: { + type: String, + select: false + }, + accessIV: { + type: String, + select: false + }, + accessTag: { + type: String, + select: false + }, + accessExpiresAt: { + type: Date, + select: false + }, + algorithm: { + // the encryption algorithm used + type: String, + enum: [ALGORITHM_AES_256_GCM], + required: true + }, + keyEncoding: { + type: String, + enum: [ENCODING_SCHEME_UTF8, ENCODING_SCHEME_BASE64], + required: true + }, + metadata: { + type: Schema.Types.Mixed + } + }, + { + timestamps: true + } +); + +export const IntegrationAuth = model("IntegrationAuth", integrationAuthSchema); diff --git a/pg-migrator/src/models/integrationAuth/types.ts b/pg-migrator/src/models/integrationAuth/types.ts new file mode 100644 index 000000000..d29869e3b --- /dev/null +++ b/pg-migrator/src/models/integrationAuth/types.ts @@ -0,0 +1,5 @@ +interface GCPIntegrationAuthMetadata { + authMethod: "oauth2" | "serviceAccount" +} + +export type IntegrationAuthMetadata = GCPIntegrationAuthMetadata; \ No newline at end of file diff --git a/pg-migrator/src/models/key.ts b/pg-migrator/src/models/key.ts new file mode 100644 index 000000000..d0d6f80f7 --- /dev/null +++ b/pg-migrator/src/models/key.ts @@ -0,0 +1,43 @@ +import { Schema, Types, model } from "mongoose"; + +export interface IKey { + _id: Types.ObjectId; + encryptedKey: string; + nonce: string; + sender: Types.ObjectId; + receiver: Types.ObjectId; + workspace: Types.ObjectId; +} + +const keySchema = new Schema( + { + encryptedKey: { + type: String, + required: true, + }, + nonce: { + type: String, + required: true, + }, + sender: { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + receiver: { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + workspace: { + type: Schema.Types.ObjectId, + ref: "Workspace", + required: true, + }, + }, + { + timestamps: true, + }, +); + +export const Key = model("Key", keySchema); diff --git a/pg-migrator/src/models/loginSRPDetail.ts b/pg-migrator/src/models/loginSRPDetail.ts new file mode 100644 index 000000000..26f897270 --- /dev/null +++ b/pg-migrator/src/models/loginSRPDetail.ts @@ -0,0 +1,27 @@ +import mongoose, { Schema, Types, model } from "mongoose"; + +export interface ILoginSRPDetail { + _id: Types.ObjectId; + clientPublicKey: string; + email: string; + serverBInt: mongoose.Schema.Types.Buffer; + userId: string; + expireAt: Date; +} + +const loginSRPDetailSchema = new Schema( + { + clientPublicKey: { + type: String, + required: true, + }, + email: { + type: String, + unique: true, + }, + serverBInt: { type: mongoose.Schema.Types.Buffer }, + expireAt: { type: Date }, + } +); + +export const LoginSRPDetail = model("LoginSRPDetail", loginSRPDetailSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/membership.ts b/pg-migrator/src/models/membership.ts new file mode 100644 index 000000000..c09fa2779 --- /dev/null +++ b/pg-migrator/src/models/membership.ts @@ -0,0 +1,60 @@ +import { Schema, Types, model } from "mongoose"; +import { ADMIN, CUSTOM, MEMBER, NO_ACCESS, VIEWER } from "../variables"; + +export interface IMembershipPermission { + environmentSlug: string; + ability: string; +} + +export interface IMembership { + _id: Types.ObjectId; + user: Types.ObjectId; + inviteEmail?: string; + workspace: Types.ObjectId; + role: "admin" | "member" | "viewer" | "no-access" | "custom"; + customRole: Types.ObjectId; + deniedPermissions: IMembershipPermission[]; +} + +const membershipSchema = new Schema( + { + user: { + type: Schema.Types.ObjectId, + ref: "User" + }, + inviteEmail: { + type: String + }, + workspace: { + type: Schema.Types.ObjectId, + ref: "Workspace", + required: true + }, + deniedPermissions: { + type: [ + { + environmentSlug: String, + ability: { + type: String, + enum: ["read", "write"] + } + } + ], + default: [] + }, + role: { + type: String, + enum: [ADMIN, MEMBER, VIEWER, NO_ACCESS, CUSTOM], + required: true + }, + customRole: { + type: Schema.Types.ObjectId, + ref: "Role" + } + }, + { + timestamps: true + } +); + +export const Membership = model("Membership", membershipSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/membershipOrg.ts b/pg-migrator/src/models/membershipOrg.ts new file mode 100644 index 000000000..0d4a2f6b7 --- /dev/null +++ b/pg-migrator/src/models/membershipOrg.ts @@ -0,0 +1,47 @@ +import { Document, Schema, Types, model } from "mongoose"; +import { ACCEPTED, ADMIN, CUSTOM, INVITED, MEMBER, NO_ACCESS } from "../variables"; + +export interface IMembershipOrg extends Document { + _id: Types.ObjectId; + user: Types.ObjectId; + inviteEmail: string; + organization: Types.ObjectId; + role: "admin" | "member" | "no-access" | "custom"; + customRole: Types.ObjectId; + status: "invited" | "accepted"; +} + +const membershipOrgSchema = new Schema( + { + user: { + type: Schema.Types.ObjectId, + ref: "User" + }, + inviteEmail: { + type: String + }, + organization: { + type: Schema.Types.ObjectId, + ref: "Organization" + }, + role: { + type: String, + enum: [ADMIN, MEMBER, NO_ACCESS, CUSTOM], + required: true + }, + status: { + type: String, + enum: [INVITED, ACCEPTED], + required: true + }, + customRole: { + type: Schema.Types.ObjectId, + ref: "Role" + } + }, + { + timestamps: true + } +); + +export const MembershipOrg = model("MembershipOrg", membershipOrgSchema); diff --git a/pg-migrator/src/models/organization.ts b/pg-migrator/src/models/organization.ts new file mode 100644 index 000000000..1ae3bcb45 --- /dev/null +++ b/pg-migrator/src/models/organization.ts @@ -0,0 +1,24 @@ +import { Schema, Types, model } from "mongoose"; + +export interface IOrganization { + _id: Types.ObjectId; + name: string; + customerId?: string; +} + +const organizationSchema = new Schema( + { + name: { + type: String, + required: true, + }, + customerId: { + type: String, + }, + }, + { + timestamps: true, + } +); + +export const Organization = model("Organization", organizationSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/role.ts b/pg-migrator/src/models/role.ts new file mode 100644 index 000000000..d3de1d3ae --- /dev/null +++ b/pg-migrator/src/models/role.ts @@ -0,0 +1,53 @@ +import { Schema, Types, model } from "mongoose"; + +export interface IRole { + _id: Types.ObjectId; + name: string; + description: string; + slug: string; + permissions: Array; + workspace: Types.ObjectId; + organization: Types.ObjectId; + isOrgRole: boolean; +} + +const roleSchema = new Schema( + { + name: { + type: String, + required: true + }, + organization: { + type: Schema.Types.ObjectId, + ref: "Organization", + required: true + }, + workspace: { + type: Schema.Types.ObjectId, + ref: "Workspace" + }, + isOrgRole: { + type: Boolean, + required: true, + select: false + }, + description: { + type: String + }, + slug: { + type: String, + required: true + }, + permissions: { + type: Array, + required: true + } + }, + { + timestamps: true + } +); + +roleSchema.index({ organization: 1, workspace: 1 }); + +export const Role = model("Role", roleSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/secret.ts b/pg-migrator/src/models/secret.ts new file mode 100644 index 000000000..4c1400fa8 --- /dev/null +++ b/pg-migrator/src/models/secret.ts @@ -0,0 +1,172 @@ +import { Schema, Types, model } from "mongoose"; +import { + ALGORITHM_AES_256_GCM, + ENCODING_SCHEME_BASE64, + ENCODING_SCHEME_UTF8, + SECRET_PERSONAL, + SECRET_SHARED +} from "../variables"; + +export interface ISecret { + _id: Types.ObjectId; + version: number; + workspace: Types.ObjectId; + type: string; + user?: Types.ObjectId; + environment: string; + secretBlindIndex?: string; + secretKeyCiphertext: string; + secretKeyIV: string; + secretKeyTag: string; + secretKeyHash: string; + secretValueCiphertext: string; + secretValueIV: string; + secretValueTag: string; + secretValueHash: string; + secretCommentCiphertext?: string; + secretCommentIV?: string; + secretCommentTag?: string; + secretCommentHash?: string; + + // ? NOTE: This works great for workspace-level reminders. + // ? If we want to do it on a user-basis, we should ideally have a seperate model for reminders. + secretReminderRepeatDays?: number | null; + secretReminderNote?: string | null; + + skipMultilineEncoding?: boolean; + algorithm: "aes-256-gcm"; + keyEncoding: "utf8" | "base64"; + tags?: string[]; + folder?: string; + metadata?: { + [key: string]: string; + }; +} + +const secretSchema = new Schema( + { + version: { + type: Number, + required: true, + default: 1 + }, + workspace: { + type: Schema.Types.ObjectId, + ref: "Workspace", + required: true + }, + type: { + type: String, + enum: [SECRET_SHARED, SECRET_PERSONAL], + required: true + }, + user: { + // user associated with the personal secret + type: Schema.Types.ObjectId, + ref: "User" + }, + tags: { + ref: "Tag", + type: [Schema.Types.ObjectId], + default: [] + }, + environment: { + type: String, + required: true + }, + secretBlindIndex: { + type: String, + select: false + }, + secretKeyCiphertext: { + type: String, + required: true + }, + secretKeyIV: { + type: String, // symmetric + required: true + }, + secretKeyTag: { + type: String, // symmetric + required: true + }, + secretKeyHash: { + type: String + }, + secretValueCiphertext: { + type: String, + required: true + }, + secretValueIV: { + type: String, // symmetric + required: true + }, + secretValueTag: { + type: String, // symmetric + required: true + }, + secretValueHash: { + type: String + }, + secretCommentCiphertext: { + type: String, + required: false + }, + secretCommentIV: { + type: String, // symmetric + required: false + }, + secretCommentTag: { + type: String, // symmetric + required: false + }, + secretCommentHash: { + type: String, + required: false + }, + + secretReminderRepeatDays: { + type: Number, + required: false, + default: null + }, + secretReminderNote: { + type: String, + required: false, + default: null + }, + + skipMultilineEncoding: { + type: Boolean, + required: false + }, + + algorithm: { + // the encryption algorithm used + type: String, + enum: [ALGORITHM_AES_256_GCM], + required: true, + default: ALGORITHM_AES_256_GCM + }, + keyEncoding: { + type: String, + enum: [ENCODING_SCHEME_UTF8, ENCODING_SCHEME_BASE64], + required: true, + default: ENCODING_SCHEME_UTF8 + }, + folder: { + type: String, + default: "root" + }, + metadata: { + type: Schema.Types.Mixed + } + }, + { + timestamps: true + } +); + +secretSchema.index({ tags: 1 }, { background: true }); + +export const Secret = model("Secret", secretSchema); diff --git a/pg-migrator/src/models/secretApprovalPolicy.ts b/pg-migrator/src/models/secretApprovalPolicy.ts new file mode 100644 index 000000000..376b541c7 --- /dev/null +++ b/pg-migrator/src/models/secretApprovalPolicy.ts @@ -0,0 +1,51 @@ +import { Schema, Types, model } from "mongoose"; + +export interface ISecretApprovalPolicy { + _id: Types.ObjectId; + workspace: Types.ObjectId; + name: string; + environment: string; + secretPath?: string; + approvers: Types.ObjectId[]; + approvals: number; +} + +const secretApprovalPolicySchema = new Schema( + { + workspace: { + type: Schema.Types.ObjectId, + ref: "Workspace", + required: true + }, + approvers: [ + { + // user associated with the personal secret + type: Schema.Types.ObjectId, + ref: "Membership" + } + ], + name: { + type: String + }, + environment: { + type: String, + required: true + }, + secretPath: { + type: String, + required: false + }, + approvals: { + type: Number, + default: 1 + } + }, + { + timestamps: true + } +); + +export const SecretApprovalPolicy = model( + "SecretApprovalPolicy", + secretApprovalPolicySchema +); diff --git a/pg-migrator/src/models/secretApprovalRequest.ts b/pg-migrator/src/models/secretApprovalRequest.ts new file mode 100644 index 000000000..24e8af39a --- /dev/null +++ b/pg-migrator/src/models/secretApprovalRequest.ts @@ -0,0 +1,203 @@ +import { Schema, Types, model } from "mongoose"; +import { customAlphabet } from "nanoid"; +import { + ALGORITHM_AES_256_GCM, + ENCODING_SCHEME_BASE64, + ENCODING_SCHEME_UTF8 +} from "../../variables"; + +export enum ApprovalStatus { + PENDING = "pending", + APPROVED = "approved", + REJECTED = "rejected" +} + +export enum CommitType { + DELETE = "delete", + UPDATE = "update", + CREATE = "create" +} + +const SLUG_ALPHABETS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; +const nanoId = customAlphabet(SLUG_ALPHABETS, 10); + +export interface ISecretApprovalSecChange { + _id: Types.ObjectId; + version: number; + secretBlindIndex?: string; + secretKeyCiphertext: string; + secretKeyIV: string; + secretKeyTag: string; + secretValueCiphertext: string; + secretValueIV: string; + secretValueTag: string; + secretCommentIV?: string; + secretCommentTag?: string; + secretCommentCiphertext?: string; + skipMultilineEncoding?: boolean; + algorithm?: "aes-256-gcm"; + keyEncoding?: "utf8" | "base64"; + tags?: string[]; +} + +export type ISecretCommits = Array< + | { + newVersion: ISecretApprovalSecChange; + op: CommitType.CREATE; + } + | { + // secret is recorded to get the latest version, we can keep ref to secret for pulling change as it will also get changed + // on merge + secretVersion: J; + secret: T; + newVersion: Partial> & { _id: Types.ObjectId }; + op: CommitType.UPDATE; + } + | { + secret: T; + secretVersion: J; + op: CommitType.DELETE; + } +>; +export interface ISecretApprovalRequest { + _id: Types.ObjectId; + committer: Types.ObjectId; + slug: string; + statusChangeBy: Types.ObjectId; + reviewers: { + member: Types.ObjectId; + status: ApprovalStatus; + }[]; + workspace: Types.ObjectId; + environment: string; + folderId: string; + hasMerged: boolean; + status: "open" | "close"; + policy: Types.ObjectId; + commits: ISecretCommits; + conflicts: Array<{ secretId: string; op: CommitType }>; +} + +const secretApprovalSecretChangeSchema = new Schema({ + version: { + type: Number, + default: 1, + required: true + }, + secretBlindIndex: { + type: String, + select: false + }, + secretKeyCiphertext: { + type: String, + required: true + }, + secretKeyIV: { + type: String, // symmetric + required: true + }, + secretKeyTag: { + type: String, // symmetric + required: true + }, + secretValueCiphertext: { + type: String, + required: true + }, + secretValueIV: { + type: String, // symmetric + required: true + }, + secretValueTag: { + type: String, // symmetric + required: true + }, + skipMultilineEncoding: { + type: Boolean, + required: false + }, + algorithm: { + // the encryption algorithm used + type: String, + enum: [ALGORITHM_AES_256_GCM], + required: true, + default: ALGORITHM_AES_256_GCM + }, + keyEncoding: { + type: String, + enum: [ENCODING_SCHEME_UTF8, ENCODING_SCHEME_BASE64], + required: true, + default: ENCODING_SCHEME_UTF8 + }, + tags: { + ref: "Tag", + type: [Schema.Types.ObjectId], + default: [] + } +}); + +const secretApprovalRequestSchema = new Schema( + { + workspace: { + type: Schema.Types.ObjectId, + ref: "Workspace", + required: true + }, + environment: { + type: String, + required: true + }, + folderId: { + type: String, + required: true, + default: "root" + }, + slug: { + type: String, + default: () => nanoId() + }, + reviewers: { + type: [ + { + member: { + // user associated with the personal secret + type: Schema.Types.ObjectId, + ref: "Membership" + }, + status: { type: String, enum: ApprovalStatus, default: ApprovalStatus.PENDING } + } + ], + default: [] + }, + policy: { type: Schema.Types.ObjectId, ref: "SecretApprovalPolicy" }, + hasMerged: { type: Boolean, default: false }, + status: { type: String, enum: ["close", "open"], default: "open" }, + committer: { type: Schema.Types.ObjectId, ref: "Membership" }, + statusChangeBy: { type: Schema.Types.ObjectId, ref: "Membership" }, + commits: [ + { + secret: { type: Types.ObjectId, ref: "Secret" }, + newVersion: secretApprovalSecretChangeSchema, + secretVersion: { type: Types.ObjectId, ref: "SecretVersion" }, + op: { type: String, enum: [CommitType], required: true } + } + ], + conflicts: { + type: [ + { + secretId: { type: String, required: true }, + op: { type: String, enum: [CommitType], required: true } + } + ], + default: [] + } + }, + { + timestamps: true + } +); + +export const SecretApprovalRequest = model( + "SecretApprovalRequest", + secretApprovalRequestSchema +); diff --git a/pg-migrator/src/models/secretBlindIndexData.ts b/pg-migrator/src/models/secretBlindIndexData.ts new file mode 100644 index 000000000..da397d2c1 --- /dev/null +++ b/pg-migrator/src/models/secretBlindIndexData.ts @@ -0,0 +1,58 @@ +import { Document, Schema, Types, model } from "mongoose"; +import { + ALGORITHM_AES_256_GCM, + ENCODING_SCHEME_BASE64, + ENCODING_SCHEME_UTF8, +} from "../variables"; + +export interface ISecretBlindIndexData extends Document { + _id: Types.ObjectId; + workspace: Types.ObjectId; + encryptedSaltCiphertext: string; + saltIV: string; + saltTag: string; + algorithm: "aes-256-gcm"; + keyEncoding: "base64" | "utf8" +} + +const secretBlindIndexDataSchema = new Schema( + { + workspace: { + type: Schema.Types.ObjectId, + ref: "Workspace", + required: true, + }, + encryptedSaltCiphertext: { // TODO: make these select: false + type: String, + required: true, + }, + saltIV: { + type: String, + required: true, + }, + saltTag: { + type: String, + required: true, + }, + algorithm: { + type: String, + enum: [ALGORITHM_AES_256_GCM], + required: true, + select: false, + }, + keyEncoding: { + type: String, + enum: [ + ENCODING_SCHEME_UTF8, + ENCODING_SCHEME_BASE64, + ], + required: true, + select: false, + }, + + } +); + +secretBlindIndexDataSchema.index({ workspace: 1 }); + +export const SecretBlindIndexData = model("SecretBlindIndexData", secretBlindIndexDataSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/secretImports.ts b/pg-migrator/src/models/secretImports.ts new file mode 100644 index 000000000..79046a489 --- /dev/null +++ b/pg-migrator/src/models/secretImports.ts @@ -0,0 +1,51 @@ +import { Schema, Types, model } from "mongoose"; + +export interface ISecretImports { + _id: Types.ObjectId; + workspace: Types.ObjectId; + environment: string; + folderId: string; + imports: Array<{ + environment: string; + secretPath: string; + }>; +} + +const secretImportSchema = new Schema( + { + workspace: { + type: Schema.Types.ObjectId, + ref: "Workspace", + required: true + }, + environment: { + type: String, + required: true + }, + folderId: { + type: String, + required: true, + default: "root" + }, + imports: { + type: [ + { + environment: { + type: String, + required: true + }, + secretPath: { + type: String, + required: true + } + } + ], + default: [] + } + }, + { + timestamps: true + } +); + +export const SecretImport = model("SecretImports", secretImportSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/secretSnapshot.ts b/pg-migrator/src/models/secretSnapshot.ts new file mode 100644 index 000000000..71d1b27e6 --- /dev/null +++ b/pg-migrator/src/models/secretSnapshot.ts @@ -0,0 +1,52 @@ +import { Schema, Types, model } from "mongoose"; + +export interface ISecretSnapshot { + workspace: Types.ObjectId; + environment: string; + folderId: string | "root"; + version: number; + secretVersions: Types.ObjectId[]; + folderVersion: Types.ObjectId; +} + +const secretSnapshotSchema = new Schema( + { + workspace: { + type: Schema.Types.ObjectId, + ref: "Workspace", + required: true, + }, + environment: { + type: String, + required: true, + }, + folderId: { + type: String, + default: "root", + }, + version: { + type: Number, + default: 1, + required: true, + }, + secretVersions: [ + { + type: Schema.Types.ObjectId, + ref: "SecretVersion", + required: true, + }, + ], + folderVersion: { + type: Schema.Types.ObjectId, + ref: "FolderVersion", + }, + }, + { + timestamps: true, + } +); + +export const SecretSnapshot = model( + "SecretSnapshot", + secretSnapshotSchema +); \ No newline at end of file diff --git a/pg-migrator/src/models/secretVersion.ts b/pg-migrator/src/models/secretVersion.ts new file mode 100644 index 000000000..11ffa79ab --- /dev/null +++ b/pg-migrator/src/models/secretVersion.ts @@ -0,0 +1,132 @@ +import { Schema, Types, model } from "mongoose"; +import { + ALGORITHM_AES_256_GCM, + ENCODING_SCHEME_BASE64, + ENCODING_SCHEME_UTF8, + SECRET_PERSONAL, + SECRET_SHARED +} from "../../variables"; + +export interface ISecretVersion { + _id: Types.ObjectId; + secret: Types.ObjectId; + version: number; + workspace: Types.ObjectId; // new + type: string; // new + user?: Types.ObjectId; // new + environment: string; // new + isDeleted: boolean; + secretBlindIndex?: string; + secretKeyCiphertext: string; + secretKeyIV: string; + secretKeyTag: string; + secretValueCiphertext: string; + secretValueIV: string; + secretValueTag: string; + skipMultilineEncoding?: boolean; + algorithm: "aes-256-gcm"; + keyEncoding: "utf8" | "base64"; + createdAt: string; + folder?: string; + tags?: string[]; +} + +const secretVersionSchema = new Schema( + { + secret: { + // could be deleted + type: Schema.Types.ObjectId, + ref: "Secret", + required: true + }, + version: { + type: Number, + default: 1, + required: true + }, + workspace: { + type: Schema.Types.ObjectId, + ref: "Workspace", + required: true + }, + type: { + type: String, + enum: [SECRET_SHARED, SECRET_PERSONAL], + required: true + }, + user: { + // user associated with the personal secret + type: Schema.Types.ObjectId, + ref: "User" + }, + environment: { + type: String, + required: true + }, + isDeleted: { + // consider removing field + type: Boolean, + default: false, + required: true + }, + secretBlindIndex: { + type: String, + select: false + }, + secretKeyCiphertext: { + type: String, + required: true + }, + secretKeyIV: { + type: String, // symmetric + required: true + }, + secretKeyTag: { + type: String, // symmetric + required: true + }, + secretValueCiphertext: { + type: String, + required: true + }, + secretValueIV: { + type: String, // symmetric + required: true + }, + secretValueTag: { + type: String, // symmetric + required: true + }, + skipMultilineEncoding: { + type: Boolean, + required: false + }, + algorithm: { + // the encryption algorithm used + type: String, + enum: [ALGORITHM_AES_256_GCM], + required: true, + default: ALGORITHM_AES_256_GCM + }, + keyEncoding: { + type: String, + enum: [ENCODING_SCHEME_UTF8, ENCODING_SCHEME_BASE64], + required: true, + default: ENCODING_SCHEME_UTF8 + }, + folder: { + type: String, + required: true + }, + tags: { + ref: "Tag", + type: [Schema.Types.ObjectId], + default: [] + } + }, + { + timestamps: true + } +); + +export const SecretVersion = model("SecretVersion", secretVersionSchema); diff --git a/pg-migrator/src/models/serverConfig.ts b/pg-migrator/src/models/serverConfig.ts new file mode 100644 index 000000000..13e469bd5 --- /dev/null +++ b/pg-migrator/src/models/serverConfig.ts @@ -0,0 +1,25 @@ +import { Schema, Types, model } from "mongoose"; + +export interface IServerConfig { + _id: Types.ObjectId; + initialized: boolean; + allowSignUp: boolean; +} + +const serverConfigSchema = new Schema( + { + initialized: { + type: Boolean, + default: false + }, + allowSignUp: { + type: Boolean, + default: true + } + }, + { + timestamps: true + } +); + +export const ServerConfig = model("ServerConfig", serverConfigSchema); diff --git a/pg-migrator/src/models/serviceToken.ts b/pg-migrator/src/models/serviceToken.ts new file mode 100644 index 000000000..0e943b177 --- /dev/null +++ b/pg-migrator/src/models/serviceToken.ts @@ -0,0 +1,60 @@ +// TODO: deprecate +import { Schema, Types, model } from "mongoose"; +export interface IServiceToken { + _id: Types.ObjectId; + name: string; + user: Types.ObjectId; + workspace: Types.ObjectId; + environment: string; + expiresAt: Date; + publicKey: string; + encryptedKey: string; + nonce: string; +} + +const serviceTokenSchema = new Schema( + { + name: { + type: String, + required: true, + }, + user: { + // token issuer + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + workspace: { + type: Schema.Types.ObjectId, + ref: "Workspace", + required: true, + }, + environment: { + type: String, + required: true, + }, + expiresAt: { + type: Date, + }, + publicKey: { + type: String, + required: true, + select: true, + }, + encryptedKey: { + type: String, + required: true, + select: true, + }, + nonce: { + type: String, + required: true, + select: true, + }, + }, + { + timestamps: true, + } +); + +export const ServiceToken = model("ServiceToken", serviceTokenSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/serviceTokenData.ts b/pg-migrator/src/models/serviceTokenData.ts new file mode 100644 index 000000000..735131703 --- /dev/null +++ b/pg-migrator/src/models/serviceTokenData.ts @@ -0,0 +1,93 @@ +// TODO: deprecate +import { Document, Schema, Types, model } from "mongoose"; + +export interface IServiceTokenData extends Document { + _id: Types.ObjectId; + name: string; + workspace: Types.ObjectId; + scopes: Array<{ + environment: string; + secretPath: string; + }>; + user: Types.ObjectId; + serviceAccount: Types.ObjectId; + lastUsed: Date; + expiresAt: Date; + secretHash: string; + encryptedKey: string; + iv: string; + tag: string; + permissions: string[]; +} + +const serviceTokenDataSchema = new Schema( + { + name: { + type: String, + required: true + }, + workspace: { + type: Schema.Types.ObjectId, + ref: "Workspace", + required: true + }, + scopes: { + type: [ + { + environment: { + type: String, + required: true + }, + secretPath: { + type: String, + default: "/", + required: true + } + } + ], + required: true + }, + user: { + type: Schema.Types.ObjectId, + ref: "User", + required: true + }, + serviceAccount: { + type: Schema.Types.ObjectId, + ref: "ServiceAccount" + }, + lastUsed: { + type: Date + }, + expiresAt: { + type: Date + }, + secretHash: { + type: String, + required: true, + select: false + }, + encryptedKey: { + type: String, + select: false + }, + iv: { + type: String, + select: false + }, + tag: { + type: String, + select: false + }, + permissions: { + type: [String], + enum: ["read", "write"], + default: ["read"] + } + }, + { + timestamps: true + } +); + +export const ServiceTokenData = model("ServiceTokenData", serviceTokenDataSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/ssoConfig.ts b/pg-migrator/src/models/ssoConfig.ts new file mode 100644 index 000000000..b591b8817 --- /dev/null +++ b/pg-migrator/src/models/ssoConfig.ts @@ -0,0 +1,72 @@ +import { Schema, Types, model } from "mongoose"; + +export enum AuthProvider { + OKTA_SAML = "okta-saml", + AZURE_SAML = "azure-saml", + JUMPCLOUD_SAML = "jumpcloud-saml" +} + +export interface ISSOConfig { + organization: Types.ObjectId; + authProvider: AuthProvider; + isActive: boolean; + encryptedEntryPoint: string; + entryPointIV: string; + entryPointTag: string; + encryptedIssuer: string; + issuerIV: string; + issuerTag: string; + encryptedCert: string; + certIV: string; + certTag: string; +} + +const ssoConfigSchema = new Schema( + { + organization: { + type: Schema.Types.ObjectId, + ref: "Organization" + }, + authProvider: { + type: String, + enum: AuthProvider, + required: true + }, + isActive: { + type: Boolean, + required: true + }, + encryptedEntryPoint: { + type: String + }, + entryPointIV: { + type: String + }, + entryPointTag: { + type: String + }, + encryptedIssuer: { + type: String + }, + issuerIV: { + type: String + }, + issuerTag: { + type: String + }, + encryptedCert: { + type: String + }, + certIV: { + type: String + }, + certTag: { + type: String + } + }, + { + timestamps: true + } +); + +export const SSOConfig = model("SSOConfig", ssoConfigSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/tag.ts b/pg-migrator/src/models/tag.ts new file mode 100644 index 000000000..a5f0bd307 --- /dev/null +++ b/pg-migrator/src/models/tag.ts @@ -0,0 +1,53 @@ +import { Schema, Types, model } from "mongoose"; + +export interface ITag { + _id: Types.ObjectId; + name: string; + tagColor: string; + slug: string; + user: Types.ObjectId; + workspace: Types.ObjectId; +} + +const tagSchema = new Schema( + { + name: { + type: String, + required: true, + trim: true, + }, + tagColor: { + type: String, + required: false, + trim: true, + }, + slug: { + type: String, + required: true, + trim: true, + lowercase: true, + validate: [ + function (value: any) { + return value.indexOf(" ") === -1; + }, + "slug cannot contain spaces", + ], + }, + user: { + type: Schema.Types.ObjectId, + ref: "User", + }, + workspace: { + type: Schema.Types.ObjectId, + ref: "Workspace", + }, + }, + { + timestamps: true, + } +); + +tagSchema.index({ slug: 1, workspace: 1 }, { unique: true }) +tagSchema.index({ workspace: 1 }) + +export const Tag = model("Tag", tagSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/token.ts b/pg-migrator/src/models/token.ts new file mode 100644 index 000000000..62d342b0a --- /dev/null +++ b/pg-migrator/src/models/token.ts @@ -0,0 +1,30 @@ +import { Schema, model } from "mongoose"; + +export interface IToken { + email: string; + token: string; + createdAt: Date; + ttl: number; +} + +const tokenSchema = new Schema({ + email: { + type: String, + required: true, + }, + token: { + type: String, + required: true, + }, + createdAt: { + type: Date, + default: Date.now, + }, + ttl: { + type: Number, + }, +}); + +tokenSchema.index({ email: 1 }); + +export const Token = model("Token", tokenSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/tokenData.ts b/pg-migrator/src/models/tokenData.ts new file mode 100644 index 000000000..2544c05f1 --- /dev/null +++ b/pg-migrator/src/models/tokenData.ts @@ -0,0 +1,53 @@ +import { Schema, Types, model } from "mongoose"; + +export interface ITokenData { + type: string; + email?: string; + phoneNumber?: string; + organization?: Types.ObjectId; + tokenHash: string; + triesLeft?: number; + expiresAt: Date; + createdAt: Date; + updatedAt: Date; +} + +const tokenDataSchema = new Schema({ + type: { + type: String, + enum: [ + "emailConfirmation", + "emailMfa", + "organizationInvitation", + "passwordReset", + ], + required: true, + }, + email: { + type: String, + }, + phoneNumber: { + type: String, + }, + organization: { // organizationInvitation-specific field + type: Schema.Types.ObjectId, + ref: "Organization", + }, + tokenHash: { + type: String, + select: false, + required: true, + }, + triesLeft: { + type: Number, + }, + expiresAt: { + type: Date, + expires: 0, + required: true, + }, +}, { + timestamps: true, +}); + +export const TokenData = model("TokenData", tokenDataSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/tokenVersion.ts b/pg-migrator/src/models/tokenVersion.ts new file mode 100644 index 000000000..b162e019e --- /dev/null +++ b/pg-migrator/src/models/tokenVersion.ts @@ -0,0 +1,45 @@ +import { Document, Schema, Types, model } from "mongoose"; + +export interface ITokenVersion extends Document { + user: Types.ObjectId; + ip: string; + userAgent: string; + refreshVersion: number; + accessVersion: number; + lastUsed: Date; +} + +const tokenVersionSchema = new Schema( + { + user: { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + ip: { + type: String, + required: true, + }, + userAgent: { + type: String, + required: true, + }, + refreshVersion: { + type: Number, + required: true, + }, + accessVersion: { + type: Number, + required: true, + }, + lastUsed: { + type: Date, + required: true, + }, + }, + { + timestamps: true, + } +); + +export const TokenVersion = model("TokenVersion", tokenVersionSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/trustedIp.ts b/pg-migrator/src/models/trustedIp.ts new file mode 100644 index 000000000..85616be11 --- /dev/null +++ b/pg-migrator/src/models/trustedIp.ts @@ -0,0 +1,54 @@ +import { Schema, Types, model } from "mongoose"; + +export enum IPType { + IPV4 = "ipv4", + IPV6 = "ipv6" +} + +export interface ITrustedIP { + _id: Types.ObjectId; + workspace: Types.ObjectId; + ipAddress: string; + type: "ipv4" | "ipv6", // either IPv4/IPv6 address or network IPv4/IPv6 address + isActive: boolean; + comment: string; + prefix?: number; // CIDR +} + +const trustedIpSchema = new Schema( + { + workspace: { + type: Schema.Types.ObjectId, + ref: "Workspace", + required: true + }, + ipAddress: { + type: String, + required: true + }, + type: { + type: String, + enum: [ + IPType.IPV4, + IPType.IPV6 + ], + required: true + }, + prefix: { + type: Number, + required: false + }, + isActive: { + type: Boolean, + required: true + }, + comment: { + type: String + } + }, + { + timestamps: true + } +); + +export const TrustedIP = model("TrustedIP", trustedIpSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/user.ts b/pg-migrator/src/models/user.ts new file mode 100644 index 000000000..a3d73b8a2 --- /dev/null +++ b/pg-migrator/src/models/user.ts @@ -0,0 +1,141 @@ +import { Document, Schema, Types, model } from "mongoose"; + +export enum AuthMethod { + EMAIL = "email", + GOOGLE = "google", + GITHUB = "github", + GITLAB = "gitlab", + OKTA_SAML = "okta-saml", + AZURE_SAML = "azure-saml", + JUMPCLOUD_SAML = "jumpcloud-saml" +} + +export interface IUser extends Document { + _id: Types.ObjectId; + authProvider?: AuthMethod; + authMethods: AuthMethod[]; + email: string; + superAdmin?: boolean; + firstName?: string; + lastName?: string; + encryptionVersion: number; + protectedKey: string; + protectedKeyIV: string; + protectedKeyTag: string; + publicKey?: string; + encryptedPrivateKey?: string; + iv?: string; + tag?: string; + salt?: string; + verifier?: string; + isMfaEnabled: boolean; + mfaMethods: boolean; + devices: { + ip: string; + userAgent: string; + }[]; +} + +const userSchema = new Schema( + { + authProvider: { + // TODO field: deprecate + type: String, + enum: AuthMethod + }, + authMethods: { + type: [ + { + type: String, + enum: AuthMethod + } + ], + default: [AuthMethod.EMAIL], + required: true + }, + email: { + type: String, + required: true, + unique: true + }, + firstName: { + type: String + }, + lastName: { + type: String + }, + encryptionVersion: { + type: Number, + select: false, + default: 1 // to resolve backward-compatibility issues + }, + protectedKey: { + // introduced as part of encryption version 2 + type: String, + select: false + }, + protectedKeyIV: { + // introduced as part of encryption version 2 + type: String, + select: false + }, + protectedKeyTag: { + // introduced as part of encryption version 2 + type: String, + select: false + }, + publicKey: { + type: String, + select: false + }, + encryptedPrivateKey: { + type: String, + select: false + }, + superAdmin: { + type: Boolean + }, + iv: { + // iv of [encryptedPrivateKey] + type: String, + select: false + }, + tag: { + // tag of [encryptedPrivateKey] + type: String, + select: false + }, + salt: { + type: String, + select: false + }, + verifier: { + type: String, + select: false + }, + isMfaEnabled: { + type: Boolean, + default: false + }, + mfaMethods: [ + { + type: String + } + ], + devices: { + type: [ + { + ip: String, + userAgent: String + } + ], + default: [], + select: false + } + }, + { + timestamps: true + } +); + +export const User = model("User", userSchema); diff --git a/pg-migrator/src/models/userAction.ts b/pg-migrator/src/models/userAction.ts new file mode 100644 index 000000000..68fae22be --- /dev/null +++ b/pg-migrator/src/models/userAction.ts @@ -0,0 +1,26 @@ +import { Schema, Types, model } from "mongoose"; + +export interface IUserAction { + _id: Types.ObjectId; + user: Types.ObjectId; + action: string; +} + +const userActionSchema = new Schema( + { + user: { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + action: { + type: String, + required: true, + }, + }, + { + timestamps: true, + } +); + +export const UserAction = model("UserAction", userActionSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/webhooks.ts b/pg-migrator/src/models/webhooks.ts new file mode 100644 index 000000000..bef5e795a --- /dev/null +++ b/pg-migrator/src/models/webhooks.ts @@ -0,0 +1,81 @@ +import { Document, Schema, Types, model } from "mongoose"; +import { ALGORITHM_AES_256_GCM, ENCODING_SCHEME_BASE64, ENCODING_SCHEME_UTF8 } from "../variables"; + +export interface IWebhook extends Document { + _id: Types.ObjectId; + workspace: Types.ObjectId; + environment: string; + secretPath: string; + url: string; + lastStatus: "success" | "failed"; + lastRunErrorMessage?: string; + isDisabled: boolean; + encryptedSecretKey: string; + iv: string; + tag: string; + algorithm: "aes-256-gcm"; + keyEncoding: "base64" | "utf8"; +} + +const WebhookSchema = new Schema( + { + workspace: { + type: Schema.Types.ObjectId, + ref: "Workspace", + required: true + }, + environment: { + type: String, + required: true + }, + secretPath: { + type: String, + required: true, + default: "/" + }, + url: { + type: String, + required: true + }, + lastStatus: { + type: String, + enum: ["success", "failed"] + }, + lastRunErrorMessage: { + type: String + }, + isDisabled: { + type: Boolean, + default: false + }, + // used for webhook signature + encryptedSecretKey: { + type: String, + select: false + }, + iv: { + type: String, + select: false + }, + tag: { + type: String, + select: false + }, + algorithm: { + // the encryption algorithm used + type: String, + enum: [ALGORITHM_AES_256_GCM], + select: false + }, + keyEncoding: { + type: String, + enum: [ENCODING_SCHEME_UTF8, ENCODING_SCHEME_BASE64], + select: false + } + }, + { + timestamps: true + } +); + +export const Webhook = model("Webhook", WebhookSchema); diff --git a/pg-migrator/src/models/workspace.ts b/pg-migrator/src/models/workspace.ts new file mode 100644 index 000000000..9d7a19fcc --- /dev/null +++ b/pg-migrator/src/models/workspace.ts @@ -0,0 +1,52 @@ +import { Schema, Types, model } from "mongoose"; + +export interface IWorkspace { + _id: Types.ObjectId; + name: string; + organization: Types.ObjectId; + environments: Array<{ + name: string; + slug: string; + }>; + autoCapitalization: boolean; +} + +const workspaceSchema = new Schema({ + name: { + type: String, + required: true, + }, + autoCapitalization: { + type: Boolean, + default: true, + }, + organization: { + type: Schema.Types.ObjectId, + ref: "Organization", + required: true, + }, + environments: { + type: [ + { + name: String, + slug: String, + }, + ], + default: [ + { + name: "Development", + slug: "dev", + }, + { + name: "Staging", + slug: "staging", + }, + { + name: "Production", + slug: "prod", + }, + ], + }, +}); + +export const Workspace = model("Workspace", workspaceSchema); \ No newline at end of file diff --git a/pg-migrator/src/schemas/api-keys.ts b/pg-migrator/src/schemas/api-keys.ts new file mode 100644 index 000000000..32e5ef6c8 --- /dev/null +++ b/pg-migrator/src/schemas/api-keys.ts @@ -0,0 +1,23 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const ApiKeysSchema = z.object({ + id: z.string().uuid(), + name: z.string(), + lastUsed: z.date().nullable().optional(), + expiresAt: z.date().nullable().optional(), + secretHash: z.string(), + createdAt: z.date(), + updatedAt: z.date(), + userId: z.string().uuid(), +}); + +export type TApiKeys = z.infer; +export type TApiKeysInsert = Omit; +export type TApiKeysUpdate = Partial>; diff --git a/pg-migrator/src/schemas/audit-logs.ts b/pg-migrator/src/schemas/audit-logs.ts new file mode 100644 index 000000000..90c389b94 --- /dev/null +++ b/pg-migrator/src/schemas/audit-logs.ts @@ -0,0 +1,28 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const AuditLogsSchema = z.object({ + id: z.string().uuid(), + actor: z.string(), + actorMetadata: z.unknown(), + ipAddress: z.string().nullable().optional(), + eventType: z.string(), + eventMetadata: z.unknown().nullable().optional(), + userAgent: z.string().nullable().optional(), + userAgentType: z.string().nullable().optional(), + expiresAt: z.date().nullable().optional(), + createdAt: z.date(), + updatedAt: z.date(), + orgId: z.string().uuid().nullable().optional(), + projectId: z.string().nullable().optional(), +}); + +export type TAuditLogs = z.infer; +export type TAuditLogsInsert = Omit; +export type TAuditLogsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/auth-token-sessions.ts b/pg-migrator/src/schemas/auth-token-sessions.ts new file mode 100644 index 000000000..9dbf8e09f --- /dev/null +++ b/pg-migrator/src/schemas/auth-token-sessions.ts @@ -0,0 +1,24 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const AuthTokenSessionsSchema = z.object({ + id: z.string().uuid(), + ip: z.string(), + userAgent: z.string().nullable().optional(), + refreshVersion: z.number().default(1), + accessVersion: z.number().default(1), + lastUsed: z.date(), + createdAt: z.date(), + updatedAt: z.date(), + userId: z.string().uuid(), +}); + +export type TAuthTokenSessions = z.infer; +export type TAuthTokenSessionsInsert = Omit; +export type TAuthTokenSessionsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/auth-tokens.ts b/pg-migrator/src/schemas/auth-tokens.ts new file mode 100644 index 000000000..4a612b11d --- /dev/null +++ b/pg-migrator/src/schemas/auth-tokens.ts @@ -0,0 +1,25 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const AuthTokensSchema = z.object({ + id: z.string().uuid(), + type: z.string(), + phoneNumber: z.string().nullable().optional(), + tokenHash: z.string(), + triesLeft: z.number().nullable().optional(), + expiresAt: z.date(), + createdAt: z.date(), + updatedAt: z.date(), + userId: z.string().uuid().nullable().optional(), + orgId: z.string().uuid().nullable().optional(), +}); + +export type TAuthTokens = z.infer; +export type TAuthTokensInsert = Omit; +export type TAuthTokensUpdate = Partial>; diff --git a/pg-migrator/src/schemas/backup-private-key.ts b/pg-migrator/src/schemas/backup-private-key.ts new file mode 100644 index 000000000..9b6e787b1 --- /dev/null +++ b/pg-migrator/src/schemas/backup-private-key.ts @@ -0,0 +1,26 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const BackupPrivateKeySchema = z.object({ + id: z.string().uuid(), + encryptedPrivateKey: z.string(), + iv: z.string(), + tag: z.string(), + algorithm: z.string(), + keyEncoding: z.string(), + salt: z.string(), + verifier: z.string(), + createdAt: z.date(), + updatedAt: z.date(), + userId: z.string().uuid(), +}); + +export type TBackupPrivateKey = z.infer; +export type TBackupPrivateKeyInsert = Omit; +export type TBackupPrivateKeyUpdate = Partial>; diff --git a/pg-migrator/src/schemas/git-app-install-sessions.ts b/pg-migrator/src/schemas/git-app-install-sessions.ts new file mode 100644 index 000000000..16f62eab7 --- /dev/null +++ b/pg-migrator/src/schemas/git-app-install-sessions.ts @@ -0,0 +1,21 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const GitAppInstallSessionsSchema = z.object({ + id: z.string().uuid(), + sessionId: z.string(), + userId: z.string().uuid().nullable().optional(), + orgId: z.string().uuid(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TGitAppInstallSessions = z.infer; +export type TGitAppInstallSessionsInsert = Omit; +export type TGitAppInstallSessionsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/git-app-org.ts b/pg-migrator/src/schemas/git-app-org.ts new file mode 100644 index 000000000..f5226811d --- /dev/null +++ b/pg-migrator/src/schemas/git-app-org.ts @@ -0,0 +1,21 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const GitAppOrgSchema = z.object({ + id: z.string().uuid(), + installationId: z.string(), + userId: z.string().uuid(), + orgId: z.string().uuid(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TGitAppOrg = z.infer; +export type TGitAppOrgInsert = Omit; +export type TGitAppOrgUpdate = Partial>; diff --git a/pg-migrator/src/schemas/identities.ts b/pg-migrator/src/schemas/identities.ts new file mode 100644 index 000000000..b8ff6c36f --- /dev/null +++ b/pg-migrator/src/schemas/identities.ts @@ -0,0 +1,20 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const IdentitiesSchema = z.object({ + id: z.string().uuid(), + name: z.string(), + authMethod: z.string().nullable().optional(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TIdentities = z.infer; +export type TIdentitiesInsert = Omit; +export type TIdentitiesUpdate = Partial>; diff --git a/pg-migrator/src/schemas/identity-access-tokens.ts b/pg-migrator/src/schemas/identity-access-tokens.ts new file mode 100644 index 000000000..1d8405427 --- /dev/null +++ b/pg-migrator/src/schemas/identity-access-tokens.ts @@ -0,0 +1,28 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const IdentityAccessTokensSchema = z.object({ + id: z.string().uuid(), + authType: z.string(), + accessTokenTTL: z.number().default(2592000), + accessTokenMaxTTL: z.number().default(2592000), + accessTokenNumUses: z.number().default(0), + accessTokenNumUsesLimit: z.number().default(0), + accessTokenLastUsedAt: z.date().nullable().optional(), + accessTokenLastRenewedAt: z.date().nullable().optional(), + isAccessTokenRevoked: z.boolean().default(false), + identityUAClientSecretId: z.string().uuid().nullable().optional(), + identityId: z.string().uuid(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TIdentityAccessTokens = z.infer; +export type TIdentityAccessTokensInsert = Omit; +export type TIdentityAccessTokensUpdate = Partial>; diff --git a/pg-migrator/src/schemas/identity-org-memberships.ts b/pg-migrator/src/schemas/identity-org-memberships.ts new file mode 100644 index 000000000..c5c9a0f61 --- /dev/null +++ b/pg-migrator/src/schemas/identity-org-memberships.ts @@ -0,0 +1,22 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const IdentityOrgMembershipsSchema = z.object({ + id: z.string().uuid(), + role: z.string(), + roleId: z.string().uuid().nullable().optional(), + orgId: z.string().uuid(), + createdAt: z.date(), + updatedAt: z.date(), + identityId: z.string().uuid(), +}); + +export type TIdentityOrgMemberships = z.infer; +export type TIdentityOrgMembershipsInsert = Omit; +export type TIdentityOrgMembershipsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/identity-project-memberships.ts b/pg-migrator/src/schemas/identity-project-memberships.ts new file mode 100644 index 000000000..9a57952a4 --- /dev/null +++ b/pg-migrator/src/schemas/identity-project-memberships.ts @@ -0,0 +1,22 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const IdentityProjectMembershipsSchema = z.object({ + id: z.string().uuid(), + role: z.string(), + roleId: z.string().uuid().nullable().optional(), + projectId: z.string(), + identityId: z.string().uuid(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TIdentityProjectMemberships = z.infer; +export type TIdentityProjectMembershipsInsert = Omit; +export type TIdentityProjectMembershipsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/identity-ua-client-secrets.ts b/pg-migrator/src/schemas/identity-ua-client-secrets.ts new file mode 100644 index 000000000..46b22c496 --- /dev/null +++ b/pg-migrator/src/schemas/identity-ua-client-secrets.ts @@ -0,0 +1,27 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const IdentityUaClientSecretsSchema = z.object({ + id: z.string().uuid(), + description: z.string(), + clientSecretPrefix: z.string(), + clientSecretHash: z.string(), + clientSecretLastUsedAt: z.date().nullable().optional(), + clientSecretNumUses: z.number().default(0), + clientSecretNumUsesLimit: z.number().default(0), + clientSecretTTL: z.number().default(0), + isClientSecretRevoked: z.boolean().default(false), + createdAt: z.date(), + updatedAt: z.date(), + identityUAId: z.string().uuid(), +}); + +export type TIdentityUaClientSecrets = z.infer; +export type TIdentityUaClientSecretsInsert = Omit; +export type TIdentityUaClientSecretsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/identity-universal-auths.ts b/pg-migrator/src/schemas/identity-universal-auths.ts new file mode 100644 index 000000000..82b9fb23e --- /dev/null +++ b/pg-migrator/src/schemas/identity-universal-auths.ts @@ -0,0 +1,25 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const IdentityUniversalAuthsSchema = z.object({ + id: z.string().uuid(), + clientId: z.string(), + accessTokenTTL: z.number().default(7200), + accessTokenMaxTTL: z.number().default(7200), + accessTokenNumUsesLimit: z.number().default(0), + clientSecretTrustedIps: z.unknown(), + accessTokenTrustedIps: z.unknown(), + createdAt: z.date(), + updatedAt: z.date(), + identityId: z.string().uuid(), +}); + +export type TIdentityUniversalAuths = z.infer; +export type TIdentityUniversalAuthsInsert = Omit; +export type TIdentityUniversalAuthsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/incident-contacts.ts b/pg-migrator/src/schemas/incident-contacts.ts new file mode 100644 index 000000000..c1492e0fa --- /dev/null +++ b/pg-migrator/src/schemas/incident-contacts.ts @@ -0,0 +1,20 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const IncidentContactsSchema = z.object({ + id: z.string().uuid(), + email: z.string(), + createdAt: z.date(), + updatedAt: z.date(), + orgId: z.string().uuid(), +}); + +export type TIncidentContacts = z.infer; +export type TIncidentContactsInsert = Omit; +export type TIncidentContactsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/index.ts b/pg-migrator/src/schemas/index.ts new file mode 100644 index 000000000..b02cab80a --- /dev/null +++ b/pg-migrator/src/schemas/index.ts @@ -0,0 +1,55 @@ +export * from "./api-keys"; +export * from "./audit-logs"; +export * from "./auth-token-sessions"; +export * from "./auth-tokens"; +export * from "./backup-private-key"; +export * from "./git-app-install-sessions"; +export * from "./git-app-org"; +export * from "./identities"; +export * from "./identity-access-tokens"; +export * from "./identity-org-memberships"; +export * from "./identity-project-memberships"; +export * from "./identity-ua-client-secrets"; +export * from "./identity-universal-auths"; +export * from "./incident-contacts"; +export * from "./integration-auths"; +export * from "./integrations"; +export * from "./models"; +export * from "./org-bots"; +export * from "./org-memberships"; +export * from "./org-roles"; +export * from "./organizations"; +export * from "./project-bots"; +export * from "./project-environments"; +export * from "./project-keys"; +export * from "./project-memberships"; +export * from "./project-roles"; +export * from "./projects"; +export * from "./sa-request-secret-tags"; +export * from "./sa-request-secrets"; +export * from "./saml-configs"; +export * from "./sap-approvers"; +export * from "./sar-reviewers"; +export * from "./secret-approval-policies"; +export * from "./secret-approval-requests"; +export * from "./secret-blind-indexes"; +export * from "./secret-folder-versions"; +export * from "./secret-folders"; +export * from "./secret-imports"; +export * from "./secret-rotation-outputs"; +export * from "./secret-rotations"; +export * from "./secret-scanning-git-risks"; +export * from "./secret-snapshot-folders"; +export * from "./secret-snapshot-secrets"; +export * from "./secret-snapshots"; +export * from "./secret-tag-junction"; +export * from "./secret-tags"; +export * from "./secret-versions"; +export * from "./secrets"; +export * from "./service-tokens"; +export * from "./super-admin"; +export * from "./trusted-ips"; +export * from "./user-actions"; +export * from "./user-encryption-keys"; +export * from "./users"; +export * from "./webhooks"; diff --git a/pg-migrator/src/schemas/integration-auths.ts b/pg-migrator/src/schemas/integration-auths.ts new file mode 100644 index 000000000..d2983658c --- /dev/null +++ b/pg-migrator/src/schemas/integration-auths.ts @@ -0,0 +1,37 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const IntegrationAuthsSchema = z.object({ + id: z.string().uuid(), + integration: z.string(), + teamId: z.string().nullable().optional(), + url: z.string().nullable().optional(), + namespace: z.string().nullable().optional(), + accountId: z.string().nullable().optional(), + refreshCiphertext: z.string().nullable().optional(), + refreshIV: z.string().nullable().optional(), + refreshTag: z.string().nullable().optional(), + accessIdCiphertext: z.string().nullable().optional(), + accessIdIV: z.string().nullable().optional(), + accessIdTag: z.string().nullable().optional(), + accessCiphertext: z.string().nullable().optional(), + accessIV: z.string().nullable().optional(), + accessTag: z.string().nullable().optional(), + accessExpiresAt: z.date().nullable().optional(), + metadata: z.unknown().nullable().optional(), + algorithm: z.string(), + keyEncoding: z.string(), + projectId: z.string(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TIntegrationAuths = z.infer; +export type TIntegrationAuthsInsert = Omit; +export type TIntegrationAuthsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/integrations.ts b/pg-migrator/src/schemas/integrations.ts new file mode 100644 index 000000000..b2163dc4d --- /dev/null +++ b/pg-migrator/src/schemas/integrations.ts @@ -0,0 +1,35 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const IntegrationsSchema = z.object({ + id: z.string().uuid(), + isActive: z.boolean(), + url: z.string().nullable().optional(), + app: z.string().nullable().optional(), + appId: z.string().nullable().optional(), + targetEnvironment: z.string().nullable().optional(), + targetEnvironmentId: z.string().nullable().optional(), + targetService: z.string().nullable().optional(), + targetServiceId: z.string().nullable().optional(), + owner: z.string().nullable().optional(), + path: z.string().nullable().optional(), + region: z.string().nullable().optional(), + scope: z.string().nullable().optional(), + integration: z.string(), + metadata: z.unknown().nullable().optional(), + integrationAuthId: z.string().uuid(), + envId: z.string().uuid(), + secretPath: z.string().default('/'), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TIntegrations = z.infer; +export type TIntegrationsInsert = Omit; +export type TIntegrationsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/models.ts b/pg-migrator/src/schemas/models.ts new file mode 100644 index 000000000..0fab0665c --- /dev/null +++ b/pg-migrator/src/schemas/models.ts @@ -0,0 +1,116 @@ +import { z } from "zod"; + +export enum TableName { + Users = "users", + UserEncryptionKey = "user_encryption_keys", + AuthTokens = "auth_tokens", + AuthTokenSession = "auth_token_sessions", + BackupPrivateKey = "backup_private_key", + Organization = "organizations", + OrgMembership = "org_memberships", + OrgRoles = "org_roles", + OrgBot = "org_bots", + IncidentContact = "incident_contacts", + UserAction = "user_actions", + SuperAdmin = "super_admin", + ApiKey = "api_keys", + Project = "projects", + ProjectBot = "project_bots", + Environment = "project_environments", + ProjectMembership = "project_memberships", + ProjectRoles = "project_roles", + ProjectKeys = "project_keys", + Secret = "secrets", + SecretBlindIndex = "secret_blind_indexes", + SecretVersion = "secret_versions", + SecretFolder = "secret_folders", + SecretFolderVersion = "secret_folder_versions", + SecretImport = "secret_imports", + Snapshot = "secret_snapshots", + SnapshotSecret = "secret_snapshot_secrets", + SnapshotFolder = "secret_snapshot_folders", + SecretTag = "secret_tags", + Integration = "integrations", + IntegrationAuth = "integration_auths", + ServiceToken = "service_tokens", + Webhook = "webhooks", + Identity = "identities", + IdentityAccessToken = "identity_access_tokens", + IdentityUniversalAuth = "identity_universal_auths", + IdentityUaClientSecret = "identity_ua_client_secrets", + IdentityOrgMembership = "identity_org_memberships", + IdentityProjectMembership = "identity_project_memberships", + SecretApprovalPolicy = "secret_approval_policies", + SapApprover = "sap_approvers", // sap: secret approval policy + SecretApprovalRequest = "secret_approval_requests", + SarReviewer = "sar_reviewers", + SarSecret = "sa_request_secrets", + SarSecretTag = "sa_request_secret_tags", + SecretRotation = "secret_rotations", + SecretRotationOutput = "secret_rotation_outputs", + SamlConfig = "saml_configs", + AuditLog = "audit_logs", + GitAppInstallSession = "git_app_install_sessions", + GitAppOrg = "git_app_org", + SecretScanningGitRisk = "secret_scanning_git_risks", + TrustedIps = "trusted_ips", + // junction tables + JnSecretTag = "secret_tag_junction", + JnSecretVersionTag = "secret_version_tag_junction" +} + +export type TImmutableDBKeys = "id" | "createdAt" | "updatedAt"; + +export const UserDeviceSchema = z + .object({ + ip: z.string(), + userAgent: z.string() + }) + .array() + .default([]); + +export const ServiceTokenScopes = z + .object({ + environment: z.string(), + secretPath: z.string().default("/") + }) + .array(); + +export enum OrgMembershipRole { + Admin = "admin", + Member = "member", + NoAccess = "no-access", + Custom = "custom" +} + +export enum OrgMembershipStatus { + Invited = "invited", + Accepted = "accepted" +} + +export enum ProjectMembershipRole { + Admin = "admin", + Member = "member", + Custom = "custom", + Viewer = "viewer", + NoAccess = "no-access" +} + +export enum SecretEncryptionAlgo { + AES_256_GCM = "aes-256-gcm" +} + +export enum SecretKeyEncoding { + UTF8 = "utf8", + BASE64 = "base64", + HEX = "hex" +} + +export enum SecretType { + Shared = "shared", + Personal = "personal" +} + +export enum IdentityAuthMethod { + Univeral = "universal" +} diff --git a/pg-migrator/src/schemas/org-bots.ts b/pg-migrator/src/schemas/org-bots.ts new file mode 100644 index 000000000..400ab19c8 --- /dev/null +++ b/pg-migrator/src/schemas/org-bots.ts @@ -0,0 +1,31 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const OrgBotsSchema = z.object({ + id: z.string().uuid(), + name: z.string(), + publicKey: z.string(), + encryptedSymmetricKey: z.string(), + symmetricKeyIV: z.string(), + symmetricKeyTag: z.string(), + symmetricKeyAlgorithm: z.string(), + symmetricKeyKeyEncoding: z.string(), + encryptedPrivateKey: z.string(), + privateKeyIV: z.string(), + privateKeyTag: z.string(), + privateKeyAlgorithm: z.string(), + privateKeyKeyEncoding: z.string(), + orgId: z.string().uuid(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TOrgBots = z.infer; +export type TOrgBotsInsert = Omit; +export type TOrgBotsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/org-memberships.ts b/pg-migrator/src/schemas/org-memberships.ts new file mode 100644 index 000000000..932c84d00 --- /dev/null +++ b/pg-migrator/src/schemas/org-memberships.ts @@ -0,0 +1,24 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const OrgMembershipsSchema = z.object({ + id: z.string().uuid(), + role: z.string(), + status: z.string().default('invited'), + inviteEmail: z.string().nullable().optional(), + createdAt: z.date(), + updatedAt: z.date(), + userId: z.string().uuid().nullable().optional(), + orgId: z.string().uuid(), + roleId: z.string().uuid().nullable().optional(), +}); + +export type TOrgMemberships = z.infer; +export type TOrgMembershipsInsert = Omit; +export type TOrgMembershipsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/org-roles.ts b/pg-migrator/src/schemas/org-roles.ts new file mode 100644 index 000000000..9718cdb26 --- /dev/null +++ b/pg-migrator/src/schemas/org-roles.ts @@ -0,0 +1,23 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const OrgRolesSchema = z.object({ + id: z.string().uuid(), + name: z.string(), + description: z.string().nullable().optional(), + slug: z.string(), + permissions: z.unknown(), + createdAt: z.date(), + updatedAt: z.date(), + orgId: z.string().uuid(), +}); + +export type TOrgRoles = z.infer; +export type TOrgRolesInsert = Omit; +export type TOrgRolesUpdate = Partial>; diff --git a/pg-migrator/src/schemas/organizations.ts b/pg-migrator/src/schemas/organizations.ts new file mode 100644 index 000000000..e9ff4555f --- /dev/null +++ b/pg-migrator/src/schemas/organizations.ts @@ -0,0 +1,20 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const OrganizationsSchema = z.object({ + id: z.string().uuid(), + name: z.string(), + customerId: z.string().nullable().optional(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TOrganizations = z.infer; +export type TOrganizationsInsert = Omit; +export type TOrganizationsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/project-bots.ts b/pg-migrator/src/schemas/project-bots.ts new file mode 100644 index 000000000..90ced9b3e --- /dev/null +++ b/pg-migrator/src/schemas/project-bots.ts @@ -0,0 +1,30 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const ProjectBotsSchema = z.object({ + id: z.string().uuid(), + name: z.string(), + isActive: z.boolean().default(false), + encryptedPrivateKey: z.string(), + publicKey: z.string(), + iv: z.string(), + tag: z.string(), + algorithm: z.string(), + keyEncoding: z.string(), + encryptedProjectKey: z.string().nullable().optional(), + encryptedProjectKeyNonce: z.string().nullable().optional(), + projectId: z.string(), + senderId: z.string().uuid().nullable().optional(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TProjectBots = z.infer; +export type TProjectBotsInsert = Omit; +export type TProjectBotsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/project-environments.ts b/pg-migrator/src/schemas/project-environments.ts new file mode 100644 index 000000000..aa3e392c7 --- /dev/null +++ b/pg-migrator/src/schemas/project-environments.ts @@ -0,0 +1,22 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const ProjectEnvironmentsSchema = z.object({ + id: z.string().uuid(), + name: z.string(), + slug: z.string(), + position: z.number(), + projectId: z.string(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TProjectEnvironments = z.infer; +export type TProjectEnvironmentsInsert = Omit; +export type TProjectEnvironmentsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/project-keys.ts b/pg-migrator/src/schemas/project-keys.ts new file mode 100644 index 000000000..64e33d574 --- /dev/null +++ b/pg-migrator/src/schemas/project-keys.ts @@ -0,0 +1,23 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const ProjectKeysSchema = z.object({ + id: z.string().uuid(), + encryptedKey: z.string(), + nonce: z.string(), + receiverId: z.string().uuid(), + senderId: z.string().uuid().nullable().optional(), + projectId: z.string(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TProjectKeys = z.infer; +export type TProjectKeysInsert = Omit; +export type TProjectKeysUpdate = Partial>; diff --git a/pg-migrator/src/schemas/project-memberships.ts b/pg-migrator/src/schemas/project-memberships.ts new file mode 100644 index 000000000..c98befb38 --- /dev/null +++ b/pg-migrator/src/schemas/project-memberships.ts @@ -0,0 +1,22 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const ProjectMembershipsSchema = z.object({ + id: z.string().uuid(), + role: z.string(), + createdAt: z.date(), + updatedAt: z.date(), + userId: z.string().uuid(), + projectId: z.string(), + roleId: z.string().uuid().nullable().optional(), +}); + +export type TProjectMemberships = z.infer; +export type TProjectMembershipsInsert = Omit; +export type TProjectMembershipsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/project-roles.ts b/pg-migrator/src/schemas/project-roles.ts new file mode 100644 index 000000000..190dd1cec --- /dev/null +++ b/pg-migrator/src/schemas/project-roles.ts @@ -0,0 +1,23 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const ProjectRolesSchema = z.object({ + id: z.string().uuid(), + name: z.string(), + description: z.string().nullable().optional(), + slug: z.string(), + permissions: z.unknown(), + createdAt: z.date(), + updatedAt: z.date(), + projectId: z.string(), +}); + +export type TProjectRoles = z.infer; +export type TProjectRolesInsert = Omit; +export type TProjectRolesUpdate = Partial>; diff --git a/pg-migrator/src/schemas/projects.ts b/pg-migrator/src/schemas/projects.ts new file mode 100644 index 000000000..f44010674 --- /dev/null +++ b/pg-migrator/src/schemas/projects.ts @@ -0,0 +1,21 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const ProjectsSchema = z.object({ + id: z.string(), + name: z.string(), + autoCapitalization: z.boolean().default(true).nullable().optional(), + orgId: z.string().uuid(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TProjects = z.infer; +export type TProjectsInsert = Omit; +export type TProjectsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/sa-request-secret-tags.ts b/pg-migrator/src/schemas/sa-request-secret-tags.ts new file mode 100644 index 000000000..d0366f125 --- /dev/null +++ b/pg-migrator/src/schemas/sa-request-secret-tags.ts @@ -0,0 +1,20 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const SaRequestSecretTagsSchema = z.object({ + id: z.string().uuid(), + secretId: z.string().uuid(), + tagId: z.string().uuid(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TSaRequestSecretTags = z.infer; +export type TSaRequestSecretTagsInsert = Omit; +export type TSaRequestSecretTagsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/sa-request-secrets.ts b/pg-migrator/src/schemas/sa-request-secrets.ts new file mode 100644 index 000000000..b8135a785 --- /dev/null +++ b/pg-migrator/src/schemas/sa-request-secrets.ts @@ -0,0 +1,39 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const SaRequestSecretsSchema = z.object({ + id: z.string().uuid(), + version: z.number().default(1).nullable().optional(), + secretBlindIndex: z.string(), + secretKeyCiphertext: z.string(), + secretKeyIV: z.string(), + secretKeyTag: z.string(), + secretValueCiphertext: z.string(), + secretValueIV: z.string(), + secretValueTag: z.string(), + secretCommentCiphertext: z.string().nullable().optional(), + secretCommentIV: z.string().nullable().optional(), + secretCommentTag: z.string().nullable().optional(), + secretReminderNote: z.string().nullable().optional(), + secretReminderRepeatDays: z.number().nullable().optional(), + skipMultilineEncoding: z.boolean().default(false).nullable().optional(), + algorithm: z.string().default('aes-256-gcm'), + keyEncoding: z.string().default('utf8'), + metadata: z.unknown().nullable().optional(), + createdAt: z.date(), + updatedAt: z.date(), + requestId: z.string().uuid(), + op: z.string(), + secretId: z.string().uuid().nullable().optional(), + secretVersion: z.string().uuid().nullable().optional(), +}); + +export type TSaRequestSecrets = z.infer; +export type TSaRequestSecretsInsert = Omit; +export type TSaRequestSecretsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/saml-configs.ts b/pg-migrator/src/schemas/saml-configs.ts new file mode 100644 index 000000000..392fb2bef --- /dev/null +++ b/pg-migrator/src/schemas/saml-configs.ts @@ -0,0 +1,30 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const SamlConfigsSchema = z.object({ + id: z.string().uuid(), + authProvider: z.string(), + isActive: z.boolean(), + encryptedEntryPoint: z.string().nullable().optional(), + entryPointIV: z.string().nullable().optional(), + entryPointTag: z.string().nullable().optional(), + encryptedIssuer: z.string().nullable().optional(), + issuerTag: z.string().nullable().optional(), + issuerIV: z.string().nullable().optional(), + encryptedCert: z.string().nullable().optional(), + certIV: z.string().nullable().optional(), + certTag: z.string().nullable().optional(), + createdAt: z.date(), + updatedAt: z.date(), + orgId: z.string().uuid(), +}); + +export type TSamlConfigs = z.infer; +export type TSamlConfigsInsert = Omit; +export type TSamlConfigsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/sap-approvers.ts b/pg-migrator/src/schemas/sap-approvers.ts new file mode 100644 index 000000000..65cc0aea0 --- /dev/null +++ b/pg-migrator/src/schemas/sap-approvers.ts @@ -0,0 +1,20 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const SapApproversSchema = z.object({ + id: z.string().uuid(), + approverId: z.string().uuid(), + policyId: z.string().uuid(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TSapApprovers = z.infer; +export type TSapApproversInsert = Omit; +export type TSapApproversUpdate = Partial>; diff --git a/pg-migrator/src/schemas/sar-reviewers.ts b/pg-migrator/src/schemas/sar-reviewers.ts new file mode 100644 index 000000000..a23d5cd75 --- /dev/null +++ b/pg-migrator/src/schemas/sar-reviewers.ts @@ -0,0 +1,21 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const SarReviewersSchema = z.object({ + id: z.string().uuid(), + member: z.string().uuid(), + status: z.string(), + requestId: z.string().uuid(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TSarReviewers = z.infer; +export type TSarReviewersInsert = Omit; +export type TSarReviewersUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-approval-policies.ts b/pg-migrator/src/schemas/secret-approval-policies.ts new file mode 100644 index 000000000..ec859bb4e --- /dev/null +++ b/pg-migrator/src/schemas/secret-approval-policies.ts @@ -0,0 +1,22 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const SecretApprovalPoliciesSchema = z.object({ + id: z.string().uuid(), + name: z.string(), + secretPath: z.string().nullable().optional(), + approvals: z.number().default(1), + envId: z.string().uuid(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TSecretApprovalPolicies = z.infer; +export type TSecretApprovalPoliciesInsert = Omit; +export type TSecretApprovalPoliciesUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-approval-requests.ts b/pg-migrator/src/schemas/secret-approval-requests.ts new file mode 100644 index 000000000..7d5f2f443 --- /dev/null +++ b/pg-migrator/src/schemas/secret-approval-requests.ts @@ -0,0 +1,26 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const SecretApprovalRequestsSchema = z.object({ + id: z.string().uuid(), + policyId: z.string().uuid(), + hasMerged: z.boolean().default(false), + status: z.string().default('open'), + conflicts: z.unknown().nullable().optional(), + slug: z.string(), + folderId: z.string().uuid(), + statusChangeBy: z.string().uuid().nullable().optional(), + committerId: z.string().uuid(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TSecretApprovalRequests = z.infer; +export type TSecretApprovalRequestsInsert = Omit; +export type TSecretApprovalRequestsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-blind-indexes.ts b/pg-migrator/src/schemas/secret-blind-indexes.ts new file mode 100644 index 000000000..17eacb473 --- /dev/null +++ b/pg-migrator/src/schemas/secret-blind-indexes.ts @@ -0,0 +1,24 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const SecretBlindIndexesSchema = z.object({ + id: z.string().uuid(), + encryptedSaltCipherText: z.string(), + saltIV: z.string(), + saltTag: z.string(), + algorithm: z.string().default('aes-256-gcm'), + keyEncoding: z.string().default('utf8'), + projectId: z.string(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TSecretBlindIndexes = z.infer; +export type TSecretBlindIndexesInsert = Omit; +export type TSecretBlindIndexesUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-folder-versions.ts b/pg-migrator/src/schemas/secret-folder-versions.ts new file mode 100644 index 000000000..895f81ebc --- /dev/null +++ b/pg-migrator/src/schemas/secret-folder-versions.ts @@ -0,0 +1,22 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const SecretFolderVersionsSchema = z.object({ + id: z.string().uuid(), + name: z.string(), + version: z.number().default(1).nullable().optional(), + createdAt: z.date(), + updatedAt: z.date(), + envId: z.string().uuid(), + folderId: z.string().uuid(), +}); + +export type TSecretFolderVersions = z.infer; +export type TSecretFolderVersionsInsert = Omit; +export type TSecretFolderVersionsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-folders.ts b/pg-migrator/src/schemas/secret-folders.ts new file mode 100644 index 000000000..aa437c753 --- /dev/null +++ b/pg-migrator/src/schemas/secret-folders.ts @@ -0,0 +1,22 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const SecretFoldersSchema = z.object({ + id: z.string().uuid(), + name: z.string(), + version: z.number().default(1).nullable().optional(), + createdAt: z.date(), + updatedAt: z.date(), + envId: z.string().uuid(), + parentId: z.string().uuid().nullable().optional(), +}); + +export type TSecretFolders = z.infer; +export type TSecretFoldersInsert = Omit; +export type TSecretFoldersUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-imports.ts b/pg-migrator/src/schemas/secret-imports.ts new file mode 100644 index 000000000..109d41ec2 --- /dev/null +++ b/pg-migrator/src/schemas/secret-imports.ts @@ -0,0 +1,23 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const SecretImportsSchema = z.object({ + id: z.string().uuid(), + version: z.number().default(1).nullable().optional(), + importPath: z.string(), + importEnv: z.string().uuid(), + position: z.number(), + createdAt: z.date(), + updatedAt: z.date(), + folderId: z.string().uuid(), +}); + +export type TSecretImports = z.infer; +export type TSecretImportsInsert = Omit; +export type TSecretImportsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-rotation-outputs.ts b/pg-migrator/src/schemas/secret-rotation-outputs.ts new file mode 100644 index 000000000..b98338c75 --- /dev/null +++ b/pg-migrator/src/schemas/secret-rotation-outputs.ts @@ -0,0 +1,19 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const SecretRotationOutputsSchema = z.object({ + id: z.string().uuid(), + key: z.string(), + secretId: z.string().uuid(), + rotationId: z.string().uuid(), +}); + +export type TSecretRotationOutputs = z.infer; +export type TSecretRotationOutputsInsert = Omit; +export type TSecretRotationOutputsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-rotations.ts b/pg-migrator/src/schemas/secret-rotations.ts new file mode 100644 index 000000000..6e2bf6547 --- /dev/null +++ b/pg-migrator/src/schemas/secret-rotations.ts @@ -0,0 +1,30 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const SecretRotationsSchema = z.object({ + id: z.string().uuid(), + provider: z.string(), + secretPath: z.string(), + interval: z.number(), + lastRotatedAt: z.date().nullable().optional(), + status: z.string().nullable().optional(), + statusMessage: z.string().nullable().optional(), + encryptedData: z.string().nullable().optional(), + encryptedDataIV: z.string().nullable().optional(), + encryptedDataTag: z.string().nullable().optional(), + algorithm: z.string().nullable().optional(), + keyEncoding: z.string().nullable().optional(), + envId: z.string().uuid(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TSecretRotations = z.infer; +export type TSecretRotationsInsert = Omit; +export type TSecretRotationsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-scanning-git-risks.ts b/pg-migrator/src/schemas/secret-scanning-git-risks.ts new file mode 100644 index 000000000..0951d3ba5 --- /dev/null +++ b/pg-migrator/src/schemas/secret-scanning-git-risks.ts @@ -0,0 +1,46 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const SecretScanningGitRisksSchema = z.object({ + id: z.string().uuid(), + description: z.string().nullable().optional(), + startLine: z.string().nullable().optional(), + endLine: z.string().nullable().optional(), + startColumn: z.string().nullable().optional(), + endColumn: z.string().nullable().optional(), + file: z.string().nullable().optional(), + symlinkFile: z.string().nullable().optional(), + commit: z.string().nullable().optional(), + entropy: z.string().nullable().optional(), + author: z.string().nullable().optional(), + email: z.string().nullable().optional(), + date: z.string().nullable().optional(), + message: z.string().nullable().optional(), + tags: z.string().array().nullable().optional(), + ruleID: z.string().nullable().optional(), + fingerprint: z.string().nullable().optional(), + fingerPrintWithoutCommitId: z.string().nullable().optional(), + isFalsePositive: z.boolean().default(false).nullable().optional(), + isResolved: z.boolean().default(false).nullable().optional(), + riskOwner: z.string().nullable().optional(), + installationId: z.string(), + repositoryId: z.string().nullable().optional(), + repositoryLink: z.string().nullable().optional(), + repositoryFullName: z.string().nullable().optional(), + pusherName: z.string().nullable().optional(), + pusherEmail: z.string().nullable().optional(), + status: z.string().nullable().optional(), + orgId: z.string().uuid(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TSecretScanningGitRisks = z.infer; +export type TSecretScanningGitRisksInsert = Omit; +export type TSecretScanningGitRisksUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-snapshot-folders.ts b/pg-migrator/src/schemas/secret-snapshot-folders.ts new file mode 100644 index 000000000..5f3b1a88c --- /dev/null +++ b/pg-migrator/src/schemas/secret-snapshot-folders.ts @@ -0,0 +1,21 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const SecretSnapshotFoldersSchema = z.object({ + id: z.string().uuid(), + envId: z.string().uuid(), + folderVersionId: z.string().uuid(), + snapshotId: z.string().uuid(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TSecretSnapshotFolders = z.infer; +export type TSecretSnapshotFoldersInsert = Omit; +export type TSecretSnapshotFoldersUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-snapshot-secrets.ts b/pg-migrator/src/schemas/secret-snapshot-secrets.ts new file mode 100644 index 000000000..f8a69a695 --- /dev/null +++ b/pg-migrator/src/schemas/secret-snapshot-secrets.ts @@ -0,0 +1,21 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const SecretSnapshotSecretsSchema = z.object({ + id: z.string().uuid(), + envId: z.string().uuid(), + secretVersionId: z.string().uuid(), + snapshotId: z.string().uuid(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TSecretSnapshotSecrets = z.infer; +export type TSecretSnapshotSecretsInsert = Omit; +export type TSecretSnapshotSecretsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-snapshots.ts b/pg-migrator/src/schemas/secret-snapshots.ts new file mode 100644 index 000000000..ef9e0b7d0 --- /dev/null +++ b/pg-migrator/src/schemas/secret-snapshots.ts @@ -0,0 +1,21 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const SecretSnapshotsSchema = z.object({ + id: z.string().uuid(), + envId: z.string().uuid(), + folderId: z.string().uuid(), + parentFolderId: z.string().uuid().nullable().optional(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TSecretSnapshots = z.infer; +export type TSecretSnapshotsInsert = Omit; +export type TSecretSnapshotsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-tag-junction.ts b/pg-migrator/src/schemas/secret-tag-junction.ts new file mode 100644 index 000000000..467ef7b15 --- /dev/null +++ b/pg-migrator/src/schemas/secret-tag-junction.ts @@ -0,0 +1,18 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const SecretTagJunctionSchema = z.object({ + id: z.string().uuid(), + secretsId: z.string().uuid(), + secret_tagsId: z.string().uuid(), +}); + +export type TSecretTagJunction = z.infer; +export type TSecretTagJunctionInsert = Omit; +export type TSecretTagJunctionUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-tags.ts b/pg-migrator/src/schemas/secret-tags.ts new file mode 100644 index 000000000..78f03dedd --- /dev/null +++ b/pg-migrator/src/schemas/secret-tags.ts @@ -0,0 +1,23 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const SecretTagsSchema = z.object({ + id: z.string().uuid(), + name: z.string(), + slug: z.string(), + color: z.string().nullable().optional(), + createdAt: z.date(), + updatedAt: z.date(), + createdBy: z.string().uuid().nullable().optional(), + projectId: z.string(), +}); + +export type TSecretTags = z.infer; +export type TSecretTagsInsert = Omit; +export type TSecretTagsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-version-tag-junction.ts b/pg-migrator/src/schemas/secret-version-tag-junction.ts new file mode 100644 index 000000000..11b3f0032 --- /dev/null +++ b/pg-migrator/src/schemas/secret-version-tag-junction.ts @@ -0,0 +1,18 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const SecretVersionTagJunctionSchema = z.object({ + id: z.string().uuid(), + secret_versionsId: z.string().uuid(), + secret_tagsId: z.string().uuid(), +}); + +export type TSecretVersionTagJunction = z.infer; +export type TSecretVersionTagJunctionInsert = Omit; +export type TSecretVersionTagJunctionUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-versions.ts b/pg-migrator/src/schemas/secret-versions.ts new file mode 100644 index 000000000..3a04a8cd9 --- /dev/null +++ b/pg-migrator/src/schemas/secret-versions.ts @@ -0,0 +1,40 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const SecretVersionsSchema = z.object({ + id: z.string().uuid(), + version: z.number().default(1), + type: z.string().default('shared'), + secretBlindIndex: z.string(), + secretKeyCiphertext: z.string(), + secretKeyIV: z.string(), + secretKeyTag: z.string(), + secretValueCiphertext: z.string(), + secretValueIV: z.string(), + secretValueTag: z.string(), + secretCommentCiphertext: z.string().nullable().optional(), + secretCommentIV: z.string().nullable().optional(), + secretCommentTag: z.string().nullable().optional(), + secretReminderNote: z.string().nullable().optional(), + secretReminderRepeatDays: z.number().nullable().optional(), + skipMultilineEncoding: z.boolean().default(false).nullable().optional(), + algorithm: z.string().default('aes-256-gcm'), + keyEncoding: z.string().default('utf8'), + metadata: z.unknown().nullable().optional(), + envId: z.string().uuid().nullable().optional(), + secretId: z.string().uuid(), + folderId: z.string().uuid(), + userId: z.string().uuid().nullable().optional(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TSecretVersions = z.infer; +export type TSecretVersionsInsert = Omit; +export type TSecretVersionsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secrets.ts b/pg-migrator/src/schemas/secrets.ts new file mode 100644 index 000000000..a284ae770 --- /dev/null +++ b/pg-migrator/src/schemas/secrets.ts @@ -0,0 +1,38 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const SecretsSchema = z.object({ + id: z.string().uuid(), + version: z.number().default(1), + type: z.string().default('shared'), + secretBlindIndex: z.string(), + secretKeyCiphertext: z.string(), + secretKeyIV: z.string(), + secretKeyTag: z.string(), + secretValueCiphertext: z.string(), + secretValueIV: z.string(), + secretValueTag: z.string(), + secretCommentCiphertext: z.string().nullable().optional(), + secretCommentIV: z.string().nullable().optional(), + secretCommentTag: z.string().nullable().optional(), + secretReminderNote: z.string().nullable().optional(), + secretReminderRepeatDays: z.number().nullable().optional(), + skipMultilineEncoding: z.boolean().default(false).nullable().optional(), + algorithm: z.string().default('aes-256-gcm'), + keyEncoding: z.string().default('utf8'), + metadata: z.unknown().nullable().optional(), + userId: z.string().uuid().nullable().optional(), + folderId: z.string().uuid(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TSecrets = z.infer; +export type TSecretsInsert = Omit; +export type TSecretsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/service-tokens.ts b/pg-migrator/src/schemas/service-tokens.ts new file mode 100644 index 000000000..29b0cd49f --- /dev/null +++ b/pg-migrator/src/schemas/service-tokens.ts @@ -0,0 +1,29 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const ServiceTokensSchema = z.object({ + id: z.string().uuid(), + name: z.string(), + scopes: z.unknown(), + permissions: z.string().array(), + lastUsed: z.date().nullable().optional(), + expiresAt: z.date().nullable().optional(), + secretHash: z.string(), + encryptedKey: z.string().nullable().optional(), + iv: z.string().nullable().optional(), + tag: z.string().nullable().optional(), + createdAt: z.date(), + updatedAt: z.date(), + createdBy: z.string(), + projectId: z.string(), +}); + +export type TServiceTokens = z.infer; +export type TServiceTokensInsert = Omit; +export type TServiceTokensUpdate = Partial>; diff --git a/pg-migrator/src/schemas/super-admin.ts b/pg-migrator/src/schemas/super-admin.ts new file mode 100644 index 000000000..f998cf325 --- /dev/null +++ b/pg-migrator/src/schemas/super-admin.ts @@ -0,0 +1,20 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const SuperAdminSchema = z.object({ + id: z.string().uuid(), + initialized: z.boolean().default(false).nullable().optional(), + allowSignUp: z.boolean().default(true).nullable().optional(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TSuperAdmin = z.infer; +export type TSuperAdminInsert = Omit; +export type TSuperAdminUpdate = Partial>; diff --git a/pg-migrator/src/schemas/trusted-ips.ts b/pg-migrator/src/schemas/trusted-ips.ts new file mode 100644 index 000000000..c3311340d --- /dev/null +++ b/pg-migrator/src/schemas/trusted-ips.ts @@ -0,0 +1,24 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const TrustedIpsSchema = z.object({ + id: z.string().uuid(), + ipAddress: z.string(), + type: z.string(), + prefix: z.number().nullable().optional(), + isActive: z.boolean().default(true).nullable().optional(), + comment: z.string().nullable().optional(), + projectId: z.string(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TTrustedIps = z.infer; +export type TTrustedIpsInsert = Omit; +export type TTrustedIpsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/user-actions.ts b/pg-migrator/src/schemas/user-actions.ts new file mode 100644 index 000000000..a3a07d699 --- /dev/null +++ b/pg-migrator/src/schemas/user-actions.ts @@ -0,0 +1,20 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const UserActionsSchema = z.object({ + id: z.string().uuid(), + action: z.string(), + createdAt: z.date(), + updatedAt: z.date(), + userId: z.string().uuid(), +}); + +export type TUserActions = z.infer; +export type TUserActionsInsert = Omit; +export type TUserActionsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/user-encryption-keys.ts b/pg-migrator/src/schemas/user-encryption-keys.ts new file mode 100644 index 000000000..0fde37ae7 --- /dev/null +++ b/pg-migrator/src/schemas/user-encryption-keys.ts @@ -0,0 +1,29 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const UserEncryptionKeysSchema = z.object({ + id: z.string().uuid(), + clientPublicKey: z.string().nullable().optional(), + serverPrivateKey: z.string().nullable().optional(), + encryptionVersion: z.number().default(2).nullable().optional(), + protectedKey: z.string(), + protectedKeyIV: z.string(), + protectedKeyTag: z.string(), + publicKey: z.string(), + encryptedPrivateKey: z.string(), + iv: z.string(), + tag: z.string(), + salt: z.string(), + verifier: z.string(), + userId: z.string().uuid(), +}); + +export type TUserEncryptionKeys = z.infer; +export type TUserEncryptionKeysInsert = Omit; +export type TUserEncryptionKeysUpdate = Partial>; diff --git a/pg-migrator/src/schemas/users.ts b/pg-migrator/src/schemas/users.ts new file mode 100644 index 000000000..b9689883d --- /dev/null +++ b/pg-migrator/src/schemas/users.ts @@ -0,0 +1,27 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const UsersSchema = z.object({ + id: z.string().uuid(), + email: z.string(), + authMethods: z.string().array().nullable().optional(), + superAdmin: z.boolean().default(false).nullable().optional(), + firstName: z.string().nullable().optional(), + lastName: z.string().nullable().optional(), + isAccepted: z.boolean().default(false).nullable().optional(), + isMfaEnabled: z.boolean().default(false).nullable().optional(), + mfaMethods: z.string().array().nullable().optional(), + devices: z.unknown().nullable().optional(), + createdAt: z.date(), + updatedAt: z.date(), +}); + +export type TUsers = z.infer; +export type TUsersInsert = Omit; +export type TUsersUpdate = Partial>; diff --git a/pg-migrator/src/schemas/webhooks.ts b/pg-migrator/src/schemas/webhooks.ts new file mode 100644 index 000000000..2b7e36cab --- /dev/null +++ b/pg-migrator/src/schemas/webhooks.ts @@ -0,0 +1,29 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const WebhooksSchema = z.object({ + id: z.string().uuid(), + secretPath: z.string().default('/'), + url: z.string(), + lastStatus: z.string().nullable().optional(), + lastRunErrorMessage: z.string().nullable().optional(), + isDisabled: z.boolean().default(false), + encryptedSecretKey: z.string().nullable().optional(), + iv: z.string().nullable().optional(), + tag: z.string().nullable().optional(), + algorithm: z.string().nullable().optional(), + keyEncoding: z.string().nullable().optional(), + createdAt: z.date(), + updatedAt: z.date(), + envId: z.string().uuid(), +}); + +export type TWebhooks = z.infer; +export type TWebhooksInsert = Omit; +export type TWebhooksUpdate = Partial>; diff --git a/pg-migrator/tsconfig.json b/pg-migrator/tsconfig.json new file mode 100644 index 000000000..f17360603 --- /dev/null +++ b/pg-migrator/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "lib": ["es6"], + "typeRoots": ["./node_modules/@types", "./src/@types", "./node_modules"], + "allowJs": true, + "outDir": "build", + "rootDir": "src", + "strict": true, + "noImplicitAny": true, + "esModuleInterop": true, + "resolveJsonModule": true + } +}