From b01a8e62f83947a251144e04797a1f62799f34d3 Mon Sep 17 00:00:00 2001 From: fenos Date: Thu, 12 Oct 2023 11:12:18 +0100 Subject: [PATCH 1/2] fix: healthcheck refactor --- package-lock.json | 710 +++++++++++++++++++++++++- package.json | 10 +- src/admin-app.ts | 3 +- src/app.ts | 3 +- src/database/client.ts | 43 +- src/http/plugins/db.ts | 7 +- src/http/plugins/tenant-id.ts | 1 - src/http/routes/health/healthcheck.ts | 25 + src/http/routes/health/index.ts | 10 + src/http/routes/index.ts | 1 + src/http/routes/tenant/index.ts | 76 +-- src/storage/database/adapter.ts | 1 + src/storage/database/knex.ts | 6 + src/storage/storage.ts | 4 + 14 files changed, 797 insertions(+), 103 deletions(-) create mode 100644 src/http/routes/health/healthcheck.ts create mode 100644 src/http/routes/health/index.ts diff --git a/package-lock.json b/package-lock.json index cc2c8a9a..7425bfcf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -75,8 +75,8 @@ "pino-pretty": "^8.1.0", "prettier": "^2.5.1", "ts-jest": "^29.0.3", - "ts-node": "^10.9.1", "ts-node-dev": "^1.1.8", + "tsx": "^3.13.0", "tus-js-client": "^3.1.0", "typescript": "^4.5.5" }, @@ -2010,6 +2010,8 @@ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -2022,11 +2024,365 @@ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint/eslintrc": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.1.0.tgz", @@ -3355,25 +3711,33 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/@tsconfig/node16": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/@tus/file-store": { "version": "1.0.0-beta.1", @@ -3860,6 +4224,8 @@ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=0.4.0" } @@ -4985,6 +5351,43 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -5724,9 +6127,9 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "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, @@ -5799,6 +6202,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "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", @@ -8514,6 +8929,15 @@ "node": ">=4" } }, + "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/resolve.exports": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", @@ -9102,6 +9526,8 @@ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -9274,6 +9700,23 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, + "node_modules/tsx": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-3.13.0.tgz", + "integrity": "sha512-rjmRpTu3as/5fjNq/kOkOtihgLxuIz6pbKdj9xwP4J5jOLkBxw/rjN5ANw+KyrrOXV5uB7HC8+SrrSJxT65y+A==", + "dev": true, + "dependencies": { + "esbuild": "~0.18.20", + "get-tsconfig": "^4.7.2", + "source-map-support": "^0.5.21" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, "node_modules/tus-js-client": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/tus-js-client/-/tus-js-client-3.1.0.tgz", @@ -9459,7 +9902,9 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/v8-to-istanbul": { "version": "9.0.1", @@ -11303,6 +11748,8 @@ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, + "optional": true, + "peer": true, "requires": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -11312,6 +11759,8 @@ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, + "optional": true, + "peer": true, "requires": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -11319,6 +11768,160 @@ } } }, + "@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "dev": true, + "optional": true + }, "@eslint/eslintrc": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.1.0.tgz", @@ -12404,25 +13007,33 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "@tsconfig/node16": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "@tus/file-store": { "version": "1.0.0-beta.1", @@ -12788,7 +13399,9 @@ "version": "8.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "agentkeepalive": { "version": "4.2.1", @@ -13640,6 +14253,36 @@ "is-arrayish": "^0.2.1" } }, + "esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "requires": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -14207,9 +14850,9 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "optional": true }, @@ -14257,6 +14900,15 @@ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true }, + "get-tsconfig": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", + "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", + "dev": true, + "requires": { + "resolve-pkg-maps": "^1.0.0" + } + }, "getopts": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.3.0.tgz", @@ -16299,6 +16951,12 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "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 + }, "resolve.exports": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", @@ -16716,6 +17374,8 @@ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dev": true, + "optional": true, + "peer": true, "requires": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -16829,6 +17489,18 @@ } } }, + "tsx": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-3.13.0.tgz", + "integrity": "sha512-rjmRpTu3as/5fjNq/kOkOtihgLxuIz6pbKdj9xwP4J5jOLkBxw/rjN5ANw+KyrrOXV5uB7HC8+SrrSJxT65y+A==", + "dev": true, + "requires": { + "esbuild": "~0.18.20", + "fsevents": "~2.3.3", + "get-tsconfig": "^4.7.2", + "source-map-support": "^0.5.21" + } + }, "tus-js-client": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/tus-js-client/-/tus-js-client-3.1.0.tgz", @@ -16972,7 +17644,9 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "v8-to-istanbul": { "version": "9.0.1", diff --git a/package.json b/package.json index 9bb90bc7..3a26a82d 100644 --- a/package.json +++ b/package.json @@ -4,12 +4,12 @@ "description": "Supabase storage middleend", "main": "index.js", "scripts": { - "dev": "ts-node-dev --log-error --files ./src/server.ts --stack_trace_limit=100 -r trace -r clarify | pino-pretty", + "dev": "tsx watch ./src/server.ts | pino-pretty", "build": "tsc -p tsconfig.json", "start": "NODE_ENV=production node dist/server.js", - "migration:run": "ts-node-dev ./src/scripts/migrate-call.ts", - "docs:export": "ts-node-dev ./src/scripts/export-docs.ts", - "test:dummy-data": "ts-node-dev -r dotenv/config ./src/test/db/import-dummy-data.ts", + "migration:run": "tsx ./src/scripts/migrate-call.ts", + "docs:export": "tsx ./src/scripts/export-docs.ts", + "test:dummy-data": "tsx -r dotenv/config ./src/test/db/import-dummy-data.ts", "test": "npm run infra:restart && npm run test:dummy-data && jest --runInBand --forceExit", "test:coverage": "npm run infra:restart && npm run test:dummy-data && jest --runInBand --coverage --forceExit", "prettier:check": "prettier -c src/**", @@ -88,8 +88,8 @@ "pino-pretty": "^8.1.0", "prettier": "^2.5.1", "ts-jest": "^29.0.3", - "ts-node": "^10.9.1", "ts-node-dev": "^1.1.8", + "tsx": "^3.13.0", "tus-js-client": "^3.1.0", "typescript": "^4.5.5" }, diff --git a/src/admin-app.ts b/src/admin-app.ts index 294c43e1..b1be2d76 100644 --- a/src/admin-app.ts +++ b/src/admin-app.ts @@ -6,7 +6,7 @@ const build = (opts: FastifyServerOptions = {}, appInstance?: FastifyInstance): const app = fastify(opts) app.register(plugins.adminTenantId) app.register(plugins.logTenantId) - app.register(plugins.logRequest({ excludeUrls: ['/status', '/metrics'] })) + app.register(plugins.logRequest({ excludeUrls: ['/status', '/metrics', '/health'] })) app.register(routes.tenant, { prefix: 'tenants' }) let registriesToMerge: Registry[] = [] @@ -36,6 +36,7 @@ const build = (opts: FastifyServerOptions = {}, appInstance?: FastifyInstance): } app.get('/status', async (_, response) => response.status(200).send()) + return app } diff --git a/src/app.ts b/src/app.ts index 1c427599..9585b377 100644 --- a/src/app.ts +++ b/src/app.ts @@ -58,11 +58,12 @@ const build = (opts: buildOpts = {}): FastifyInstance => { app.register(plugins.tenantId) app.register(plugins.metrics({ enabledEndpoint: !isMultitenant })) app.register(plugins.logTenantId) - app.register(plugins.logRequest({ excludeUrls: ['/status', '/metrics'] })) + app.register(plugins.logRequest({ excludeUrls: ['/status', '/metrics', '/health'] })) app.register(routes.multiPart, { prefix: 'upload/resumable' }) app.register(routes.bucket, { prefix: 'bucket' }) app.register(routes.object, { prefix: 'object' }) app.register(routes.render, { prefix: 'render/image' }) + app.register(routes.healthcheck, { prefix: 'health' }) setErrorHandler(app) diff --git a/src/database/client.ts b/src/database/client.ts index c6853a46..28c4a642 100644 --- a/src/database/client.ts +++ b/src/database/client.ts @@ -11,6 +11,7 @@ interface ConnectionOptions { path?: string user: User superUser: User + disableHostCheck?: boolean } /** @@ -18,7 +19,9 @@ interface ConnectionOptions { * @param options */ export async function getPostgresConnection(options: ConnectionOptions): Promise { - const dbCredentials = await getDbCredentials(options.tenantId, options.host) + const dbCredentials = await getDbCredentials(options.tenantId, options.host, { + disableHostCheck: options.disableHostCheck, + }) return await TenantConnection.create({ ...dbCredentials, @@ -26,7 +29,11 @@ export async function getPostgresConnection(options: ConnectionOptions): Promise }) } -async function getDbCredentials(tenantId: string, host: string | undefined) { +async function getDbCredentials( + tenantId: string, + host: string | undefined, + options?: { disableHostCheck?: boolean } +) { const { isMultitenant, databasePoolURL, @@ -39,26 +46,28 @@ async function getDbCredentials(tenantId: string, host: string | undefined) { let maxConnections = databaseMaxConnections let isExternalPool = Boolean(databasePoolURL) - if (isMultitenant && xForwardedHostRegExp) { + if (isMultitenant) { if (!tenantId) { throw new StorageBackendError('Invalid Tenant Id', 400, 'Tenant id not provided') } - const xForwardedHost = host + if (xForwardedHostRegExp && !options?.disableHostCheck) { + const xForwardedHost = host - if (typeof xForwardedHost !== 'string') { - throw new StorageBackendError( - 'Invalid Header', - 400, - 'X-Forwarded-Host header is not a string' - ) - } - if (!new RegExp(xForwardedHostRegExp).test(xForwardedHost)) { - throw new StorageBackendError( - 'Invalid Header', - 400, - 'X-Forwarded-Host header does not match regular expression' - ) + if (typeof xForwardedHost !== 'string') { + throw new StorageBackendError( + 'Invalid Header', + 400, + 'X-Forwarded-Host header is not a string' + ) + } + if (!new RegExp(xForwardedHostRegExp).test(xForwardedHost)) { + throw new StorageBackendError( + 'Invalid Header', + 400, + 'X-Forwarded-Host header does not match regular expression' + ) + } } const tenant = await getTenantConfig(tenantId) diff --git a/src/http/plugins/db.ts b/src/http/plugins/db.ts index 08e69036..2dcaa8c2 100644 --- a/src/http/plugins/db.ts +++ b/src/http/plugins/db.ts @@ -70,7 +70,11 @@ export const db = fastifyPlugin(async (fastify) => { }) }) -export const dbSuperUser = fastifyPlugin(async (fastify) => { +interface DbSuperUserPluginOptions { + disableHostCheck?: boolean +} + +export const dbSuperUser = fastifyPlugin(async (fastify, opts) => { fastify.decorateRequest('db', null) fastify.addHook('preHandler', async (request) => { @@ -84,6 +88,7 @@ export const dbSuperUser = fastifyPlugin(async (fastify) => { path: request.url, method: request.method, headers: request.headers, + disableHostCheck: opts.disableHostCheck, }) }) diff --git a/src/http/plugins/tenant-id.ts b/src/http/plugins/tenant-id.ts index 207df37d..b2e55f6b 100644 --- a/src/http/plugins/tenant-id.ts +++ b/src/http/plugins/tenant-id.ts @@ -21,7 +21,6 @@ export const tenantId = fastifyPlugin(async (fastify) => { }) export const adminTenantId = fastifyPlugin(async (fastify) => { - fastify.register(tenantId) fastify.addHook('onRequest', async (request) => { const tenantId = (request.params as Record).tenantId if (!tenantId) return diff --git a/src/http/routes/health/healthcheck.ts b/src/http/routes/health/healthcheck.ts new file mode 100644 index 00000000..2cffa1f1 --- /dev/null +++ b/src/http/routes/health/healthcheck.ts @@ -0,0 +1,25 @@ +import { FastifyInstance } from 'fastify' + +export default async function routes(fastify: FastifyInstance) { + const summary = 'healthcheck' + + fastify.get( + '/', + { + schema: { + summary, + }, + }, + async (req, res) => { + try { + await req.storage.healthcheck() + res.send({ healthy: true }) + } catch (e) { + if (e instanceof Error) { + res.executionError = e + } + res.send({ healthy: false }) + } + } + ) +} diff --git a/src/http/routes/health/index.ts b/src/http/routes/health/index.ts new file mode 100644 index 00000000..5f1513e3 --- /dev/null +++ b/src/http/routes/health/index.ts @@ -0,0 +1,10 @@ +import { FastifyInstance } from 'fastify' +import { dbSuperUser, jwt, storage } from '../../plugins' +import healthcheck from './healthcheck' + +export default async function routes(fastify: FastifyInstance) { + fastify.register(jwt) + fastify.register(dbSuperUser) + fastify.register(storage) + fastify.register(healthcheck) +} diff --git a/src/http/routes/index.ts b/src/http/routes/index.ts index e0a5eb3c..0bf7e036 100644 --- a/src/http/routes/index.ts +++ b/src/http/routes/index.ts @@ -3,3 +3,4 @@ export { default as object } from './object' export { default as render } from './render' export { default as tenant } from './tenant' export { default as multiPart } from './tus' +export { default as healthcheck } from './health' diff --git a/src/http/routes/tenant/index.ts b/src/http/routes/tenant/index.ts index bfd1c4b8..f728cc1a 100644 --- a/src/http/routes/tenant/index.ts +++ b/src/http/routes/tenant/index.ts @@ -3,18 +3,8 @@ import { FromSchema } from 'json-schema-to-ts' import apiKey from '../../plugins/apikey' import { decrypt, encrypt } from '../../../auth' import { knex } from '../../../database/multitenant-db' -import { - deleteTenantConfig, - getServiceKeyUser, - getTenantConfig, - runMigrations, -} from '../../../database/tenant' -import { TenantConnection } from '../../../database/connection' -import { Knex } from 'knex' -import { getConfig } from '../../../config' -import { StorageBackendError } from '../../../storage' - -const { databaseMaxConnections } = getConfig() +import { deleteTenantConfig, runMigrations } from '../../../database/tenant' +import { dbSuperUser, storage } from '../../plugins' const patchSchema = { body: { @@ -257,54 +247,22 @@ export default async function routes(fastify: FastifyInstance) { reply.code(204).send() }) - fastify.get('/:tenantId/health', async (req, res) => { - let isExternalPool = false - let connection: TenantConnection | undefined - let tx: Knex.Transaction | undefined - - try { - const { databasePoolUrl, databaseUrl } = await getTenantConfig(req.params.tenantId) - const adminUser = await getServiceKeyUser(req.params.tenantId) - - isExternalPool = Boolean(databasePoolUrl) - connection = await TenantConnection.create({ - tenantId: req.params.tenantId, - headers: {}, - maxConnections: isExternalPool ? 1 : databaseMaxConnections, - dbUrl: databasePoolUrl || databaseUrl, - isExternalPool, - user: adminUser, - superUser: adminUser, - }) - } catch (e) { - if (e instanceof StorageBackendError) { - res.status(200).send({ healthy: false, error: e.message }) - return - } - res.status(200).send({ healthy: false, error: 'Could not create connection' }) - return - } - - try { - tx = await connection.transaction() - } catch (e) { - res.status(500).send({ healthy: false, error: 'Could not acquire connection' }) - return - } + fastify.register(async (fastify) => { + fastify.register(dbSuperUser, { + disableHostCheck: true, + }) + fastify.register(storage) - try { - await tx.raw('SELECT id from storage.buckets limit 1') - await tx.commit() - res.send({ healthy: true }) - } catch (e) { - await tx.rollback(e) - res.status(200).send({ healthy: false }) - } finally { - if (isExternalPool && connection) { - connection.dispose().catch(() => { - // ignore - }) + fastify.get('/:tenantId/health', async (req, res) => { + try { + await req.storage.healthcheck() + res.send({ healthy: true }) + } catch (e) { + if (e instanceof Error) { + res.executionError = e + } + res.send({ healthy: false }) } - } + }) }) } diff --git a/src/storage/database/adapter.ts b/src/storage/database/adapter.ts index ade9fac8..55c71c53 100644 --- a/src/storage/database/adapter.ts +++ b/src/storage/database/adapter.ts @@ -117,4 +117,5 @@ export interface Database { ): Promise searchObjects(bucketId: string, prefix: string, options: SearchObjectOption): Promise + healthcheck(): Promise } diff --git a/src/storage/database/knex.ts b/src/storage/database/knex.ts index 9a4c2d8f..9f3e8924 100644 --- a/src/storage/database/knex.ts +++ b/src/storage/database/knex.ts @@ -455,6 +455,12 @@ export class StorageKnexDB implements Database { }) } + healthcheck() { + return this.runQuery('Healthcheck', (knex) => { + return knex.raw('SELECT id from storage.buckets limit 1') + }) + } + protected async runQuery Promise>( queryName: string, fn: T, diff --git a/src/storage/storage.ts b/src/storage/storage.ts index 3fcbae78..ff5f8484 100644 --- a/src/storage/storage.ts +++ b/src/storage/storage.ts @@ -248,6 +248,10 @@ export class Storage { return true } + healthcheck() { + return this.db.asSuperUser().healthcheck() + } + protected async parseMaxSizeLimit(maxFileLimit: number | string) { if (typeof maxFileLimit === 'string') { maxFileLimit = parseFileSizeToBytes(maxFileLimit) From f63fb45807d8e40ceec87ab7bc828dcd0970ccb1 Mon Sep 17 00:00:00 2001 From: fenos Date: Fri, 20 Oct 2023 11:01:24 +0100 Subject: [PATCH 2/2] fix: queue params --- src/config.ts | 13 ++++++++----- src/queue/events/base-event.ts | 3 ++- src/queue/events/object-admin-delete.ts | 12 +++++++++++- src/queue/events/webhook.ts | 20 ++++++++++++++++---- src/storage/uploader.ts | 4 +++- 5 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/config.ts b/src/config.ts index fa32afa2..ed95ac9c 100644 --- a/src/config.ts +++ b/src/config.ts @@ -164,11 +164,14 @@ export function getConfig(): StorageConfigType { webhookQueuePullInterval: parseInt( getOptionalConfigFromEnv('WEBHOOK_QUEUE_PULL_INTERVAL') || '700' ), - webhookQueueTeamSize: parseInt('QUEUE_WEBHOOKS_TEAM_SIZE') || 50, - webhookQueueConcurrency: parseInt('QUEUE_WEBHOOK_CONCURRENCY') || 5, - adminDeleteQueueTeamSize: parseInt('QUEUE_ADMIN_DELETE_TEAM_SIZE') || 50, - adminDeleteConcurrency: parseInt('QUEUE_ADMIN_DELETE_CONCURRENCY') || 5, - + webhookQueueTeamSize: parseInt(getOptionalConfigFromEnv('QUEUE_WEBHOOKS_TEAM_SIZE') || '50'), + webhookQueueConcurrency: parseInt(getOptionalConfigFromEnv('QUEUE_WEBHOOK_CONCURRENCY') || '5'), + adminDeleteQueueTeamSize: parseInt( + getOptionalConfigFromEnv('QUEUE_ADMIN_DELETE_TEAM_SIZE') || '50' + ), + adminDeleteConcurrency: parseInt( + getOptionalConfigFromEnv('QUEUE_ADMIN_DELETE_CONCURRENCY') || '5' + ), enableImageTransformation: getOptionalConfigFromEnv('ENABLE_IMAGE_TRANSFORMATION') === 'true', imgProxyRequestTimeout: parseInt( getOptionalConfigFromEnv('IMGPROXY_REQUEST_TIMEOUT') || '15', diff --git a/src/queue/events/base-event.ts b/src/queue/events/base-event.ts index fcce589d..e5c82dcc 100644 --- a/src/queue/events/base-event.ts +++ b/src/queue/events/base-event.ts @@ -80,11 +80,12 @@ export abstract class BaseEvent> { } catch (e) { logger.error( { + error: e, event: { type: eventType, $version: (this as any).version, applyTime: Date.now(), - payload, + payload: JSON.stringify(payload), }, tenant: payload.tenant, }, diff --git a/src/queue/events/object-admin-delete.ts b/src/queue/events/object-admin-delete.ts index 046a1ce9..2f88dfad 100644 --- a/src/queue/events/object-admin-delete.ts +++ b/src/queue/events/object-admin-delete.ts @@ -45,11 +45,21 @@ export class ObjectAdminDelete extends BaseEvent { withOptionalVersion(s3Key, version) + '.info', ]) } catch (e) { + const s3Key = `${job.data.tenant.ref}/${job.data.bucketId}/${job.data.name}` + logger.error( { error: e, + jodId: job.id, + type: 'event', + event: 'ObjectAdminDelete', + payload: JSON.stringify(job.data), + objectPath: s3Key, + tenantId: job.data.tenant.ref, + project: job.data.tenant.ref, + reqId: job.data.reqId, }, - 'Error Deleting files from queue' + `[Admin]: ObjectAdminDelete ${s3Key} - FAILED` ) throw e } diff --git a/src/queue/events/webhook.ts b/src/queue/events/webhook.ts index e3f6b489..ab53f898 100644 --- a/src/queue/events/webhook.ts +++ b/src/queue/events/webhook.ts @@ -16,11 +16,10 @@ interface WebhookEvent { event: { $version: string type: string - payload: object + payload: object & { reqId?: string } applyTime: number } sentAt: string - traceId?: string tenant: { ref: string host: string @@ -55,7 +54,7 @@ export class Webhook extends BaseEvent { objectPath: path, tenantId: job.data.tenant.ref, project: job.data.tenant.ref, - reqId: job.data.traceId, + reqId: job.data.event.payload.reqId, }) try { @@ -74,7 +73,20 @@ export class Webhook extends BaseEvent { } ) } catch (e) { - logger.error({ error: e }, 'Webhook failed') + logger.error( + { + error: e, + jodId: job.id, + type: 'event', + event: job.data.event.type, + payload: JSON.stringify(job.data.event.payload), + objectPath: path, + tenantId: job.data.tenant.ref, + project: job.data.tenant.ref, + reqId: job.data.event.payload.reqId, + }, + `[Lifecycle]: ${job.data.event.type} ${path} - FAILED` + ) throw e } diff --git a/src/storage/uploader.ts b/src/storage/uploader.ts index fdc421c1..8fe82263 100644 --- a/src/storage/uploader.ts +++ b/src/storage/uploader.ts @@ -170,6 +170,7 @@ export class Uploader { // schedule the deletion of the previous file if (currentObj && currentObj.version !== id) { + console.log('deleted') events.push( ObjectAdminDelete.send({ name: objectName, @@ -205,7 +206,8 @@ export class Uploader { ) } - await Promise.all(events) + console.log(events) + console.log(await Promise.all(events)) FileUploadedSuccess.inc({ tenant_id: db.tenantId,