From 752ebaa3ebfeb779734df9b6bb421fe5c8d8a969 Mon Sep 17 00:00:00 2001 From: Reginald Bondoc Date: Sun, 11 Dec 2022 22:36:46 +0100 Subject: [PATCH 01/15] Add healthchecks and test image before push --- .github/resources/docker-compose.be-test.yml | 30 ++++ .github/resources/healthcheck.sh | 26 ++++ .github/workflows/docker-image.yml | 88 +++++------ backend/Dockerfile | 9 +- backend/healthcheck.js | 27 ++++ backend/package-lock.json | 155 ++++++++++++++++++- backend/package.json | 1 + backend/src/index.ts | 113 +++++++++----- docker-compose.yml | 4 +- frontend/Dockerfile | 3 + frontend/scripts/healthcheck.js | 26 ++++ 11 files changed, 389 insertions(+), 93 deletions(-) create mode 100644 .github/resources/docker-compose.be-test.yml create mode 100755 .github/resources/healthcheck.sh create mode 100644 backend/healthcheck.js create mode 100644 frontend/scripts/healthcheck.js diff --git a/.github/resources/docker-compose.be-test.yml b/.github/resources/docker-compose.be-test.yml new file mode 100644 index 0000000000..6efdd87f64 --- /dev/null +++ b/.github/resources/docker-compose.be-test.yml @@ -0,0 +1,30 @@ +version: '3' + +services: + backend: + container_name: infisical-backend-test + restart: unless-stopped + depends_on: + - mongo + image: infisical/backend:test + command: npm run start + environment: + - NODE_ENV=production + - MONGO_URL=mongodb://test:example@mongo:27017/?authSource=admin + - MONGO_USERNAME=test + - MONGO_PASSWORD=example + networks: + - infisical-test + + mongo: + container_name: infisical-mongo-test + image: mongo + restart: always + environment: + - MONGO_INITDB_ROOT_USERNAME=test + - MONGO_INITDB_ROOT_PASSWORD=example + networks: + - infisical-test + +networks: + infisical-test: diff --git a/.github/resources/healthcheck.sh b/.github/resources/healthcheck.sh new file mode 100755 index 0000000000..bc28e36071 --- /dev/null +++ b/.github/resources/healthcheck.sh @@ -0,0 +1,26 @@ +# Name of the target container to check +container_name="$1" +# Timeout in seconds. Default: 60 +timeout=$((${2:-60})); + +if [ -z $container_name ]; then + echo "No container name specified"; + exit 1; +fi + +echo "Container: $container_name"; +echo "Timeout: $timeout sec"; + +try=0; +is_healthy="false"; +while [ $is_healthy != "true" ]; +do + try=$(($try + 1)); + printf "■"; + is_healthy=$(docker inspect --format='{{json .State.Health}}' $container_name | jq '.Status == "healthy"'); + sleep 1; + if [[ $try -eq $timeout ]]; then + echo " Container was not ready within timeout"; + exit 1; + fi +done diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index e85ddcfd56..1e836a1782 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -3,40 +3,38 @@ name: Push to Docker Hub on: [workflow_dispatch] jobs: - backend-image: name: Build backend image runs-on: ubuntu-latest steps: - - - name: ☁️ Checkout source + - name: ☁️ Checkout source uses: actions/checkout@v3 - - - name: 🔧 Set up QEMU + - name: 🔧 Set up QEMU uses: docker/setup-qemu-action@v2 - - - name: 🔧 Set up Docker Buildx + - name: 🔧 Set up Docker Buildx uses: docker/setup-buildx-action@v2 - - - name: 🐋 Login to Docker Hub + - name: 🐋 Login to Docker Hub uses: docker/login-action@v2 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - # - - # name: 📦 Build backend and export to Docker - # uses: docker/build-push-action@v3 - # with: - # load: true - # context: backend - # tags: infisical/backend:test - # - - # name: 🧪 Test backend image - # run: | - # docker run --rm infisical/backend:test - - - name: 🏗️ Build backend and push + - name: 📦 Build backend and export to Docker + uses: docker/build-push-action@v3 + with: + load: true + context: backend + tags: infisical/backend:test + - name: ⏻ Spawn backend container and dependencies + run: | + docker compose -f .github/resources/docker-compose.be-test.yml up --wait --quiet-pull + - name: 🧪 Test backend image + run: | + ./.github/resources/healthcheck.sh infisical-backend-test + - name: ⏻ Shut down backend container and dependencies + run: | + docker compose -f .github/resources/docker-compose.be-test.yml down + - name: 🏗️ Build backend and push uses: docker/build-push-action@v3 with: push: true @@ -44,42 +42,40 @@ jobs: tags: infisical/backend:latest platforms: linux/amd64,linux/arm64 - frontend-image: name: Build frontend image runs-on: ubuntu-latest steps: - - - name: ☁️ Checkout source + - name: ☁️ Checkout source uses: actions/checkout@v3 - - - name: 🔧 Set up QEMU + - name: 🔧 Set up QEMU uses: docker/setup-qemu-action@v2 - - - name: 🔧 Set up Docker Buildx + - name: 🔧 Set up Docker Buildx uses: docker/setup-buildx-action@v2 - - - name: 🐋 Login to Docker Hub + - name: 🐋 Login to Docker Hub uses: docker/login-action@v2 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - # - - # name: 📦 Build frontend and export to Docker - # uses: docker/build-push-action@v3 - # with: - # load: true - # context: frontend - # tags: infisical/frontend:test - # build-args: | - # POSTHOG_API_KEY=${{ secrets.PUBLIC_POSTHOG_API_KEY }} - # - - # name: 🧪 Test frontend image - # run: | - # docker run --rm infisical/frontend:test - - - name: 🏗️ Build frontend and push + - name: 📦 Build frontend and export to Docker + uses: docker/build-push-action@v3 + with: + load: true + context: frontend + tags: infisical/frontend:test + build-args: | + POSTHOG_API_KEY=${{ secrets.PUBLIC_POSTHOG_API_KEY }} + - name: ⏻ Spawn frontend container + run: | + docker run -d --rm --name infisical-frontend-test infisical/frontend:test + - name: 🧪 Test frontend image + run: | + ./.github/resources/healthcheck.sh infisical-frontend-test + - name: ⏻ Shut down frontend container + run: | + docker stop infisical-frontend-test + - name: 🏗️ Build frontend and push uses: docker/build-push-action@v3 with: push: true diff --git a/backend/Dockerfile b/backend/Dockerfile index 2cc2709476..ccc76e66e5 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -2,11 +2,14 @@ FROM node:16-bullseye-slim WORKDIR /app -COPY package*.json . +COPY package.json package-lock.json ./ -RUN npm install +RUN npm ci --only-production COPY . . -CMD ["npm", "run", "start"] +HEALTHCHECK --interval=10s --timeout=3s --start-period=10s \ + CMD node healthcheck.js + +CMD ["npm", "run", "start"] diff --git a/backend/healthcheck.js b/backend/healthcheck.js new file mode 100644 index 0000000000..7b798eb0a8 --- /dev/null +++ b/backend/healthcheck.js @@ -0,0 +1,27 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ +/* eslint-disable no-console */ +/* eslint-disable no-undef */ +const http = require('http'); +const PORT = process.env.PORT || 4000; +const options = { + host: 'localhost', + port: PORT, + timeout: 2000, + path: '/healthcheck' +}; + +const healthCheck = http.request(options, (res) => { + console.log(`HEALTHCHECK STATUS: ${res.statusCode}`); + if (res.statusCode == 200) { + process.exit(0); + } else { + process.exit(1); + } +}); + +healthCheck.on('error', function (err) { + console.error(err); + process.exit(1); +}); + +healthCheck.end(); diff --git a/backend/package-lock.json b/backend/package-lock.json index d4c3d36a6b..c13f138d4c 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "@godaddy/terminus": "^4.11.2", "@sentry/node": "^7.14.0", "@sentry/tracing": "^7.19.0", "@types/crypto-js": "^4.1.1", @@ -2028,6 +2029,14 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@godaddy/terminus": { + "version": "4.11.2", + "resolved": "https://registry.npmjs.org/@godaddy/terminus/-/terminus-4.11.2.tgz", + "integrity": "sha512-e/kbOWpGKME42eltM/wXM3RxSUOrfureZxEd6Dt6NXyFoJ7E8lnmm7znXydJsL3B7ky4HRFZI+eHrep54NZbeQ==", + "dependencies": { + "stoppable": "^1.1.0" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.7", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", @@ -6731,7 +6740,129 @@ "treeverse", "validate-npm-package-name", "which", - "write-file-atomic" + "write-file-atomic", + "@colors/colors", + "@gar/promisify", + "@npmcli/disparity-colors", + "@npmcli/git", + "@npmcli/installed-package-contents", + "@npmcli/metavuln-calculator", + "@npmcli/move-file", + "@npmcli/name-from-folder", + "@npmcli/node-gyp", + "@npmcli/promise-spawn", + "@npmcli/query", + "@tootallnate/once", + "agent-base", + "agentkeepalive", + "aggregate-error", + "ansi-regex", + "ansi-styles", + "aproba", + "are-we-there-yet", + "asap", + "balanced-match", + "bin-links", + "binary-extensions", + "brace-expansion", + "builtins", + "cidr-regex", + "clean-stack", + "clone", + "cmd-shim", + "color-convert", + "color-name", + "color-support", + "common-ancestor-path", + "concat-map", + "console-control-strings", + "cssesc", + "debug", + "debuglog", + "defaults", + "delegates", + "depd", + "dezalgo", + "diff", + "emoji-regex", + "encoding", + "env-paths", + "err-code", + "fs.realpath", + "function-bind", + "gauge", + "has", + "has-flag", + "has-unicode", + "http-cache-semantics", + "http-proxy-agent", + "https-proxy-agent", + "humanize-ms", + "iconv-lite", + "ignore-walk", + "imurmurhash", + "indent-string", + "infer-owner", + "inflight", + "inherits", + "ip", + "ip-regex", + "is-core-module", + "is-fullwidth-code-point", + "is-lambda", + "isexe", + "json-stringify-nice", + "jsonparse", + "just-diff", + "just-diff-apply", + "lru-cache", + "minipass-collect", + "minipass-fetch", + "minipass-flush", + "minipass-json-stream", + "minipass-sized", + "minizlib", + "mute-stream", + "negotiator", + "normalize-package-data", + "npm-bundled", + "npm-normalize-package-bin", + "npm-packlist", + "once", + "path-is-absolute", + "postcss-selector-parser", + "promise-all-reject-late", + "promise-call-limit", + "promise-inflight", + "promise-retry", + "promzard", + "read-cmd-shim", + "readable-stream", + "retry", + "safe-buffer", + "safer-buffer", + "set-blocking", + "signal-exit", + "smart-buffer", + "socks", + "socks-proxy-agent", + "spdx-correct", + "spdx-exceptions", + "spdx-expression-parse", + "spdx-license-ids", + "string_decoder", + "string-width", + "strip-ansi", + "supports-color", + "unique-filename", + "unique-slug", + "util-deprecate", + "validate-npm-package-license", + "walk-up-path", + "wcwidth", + "wide-align", + "wrappy", + "yallist" ], "dev": true, "dependencies": { @@ -10192,6 +10323,15 @@ "node": ">= 0.8" } }, + "node_modules/stoppable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", + "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==", + "engines": { + "node": ">=4", + "npm": ">=6" + } + }, "node_modules/strict-uri-encode": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", @@ -12607,6 +12747,14 @@ "strip-json-comments": "^3.1.1" } }, + "@godaddy/terminus": { + "version": "4.11.2", + "resolved": "https://registry.npmjs.org/@godaddy/terminus/-/terminus-4.11.2.tgz", + "integrity": "sha512-e/kbOWpGKME42eltM/wXM3RxSUOrfureZxEd6Dt6NXyFoJ7E8lnmm7znXydJsL3B7ky4HRFZI+eHrep54NZbeQ==", + "requires": { + "stoppable": "^1.1.0" + } + }, "@humanwhocodes/config-array": { "version": "0.11.7", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", @@ -18631,6 +18779,11 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" }, + "stoppable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", + "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==" + }, "strict-uri-encode": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", diff --git a/backend/package.json b/backend/package.json index 7e0dc7ad9b..32ca68b192 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,5 +1,6 @@ { "dependencies": { + "@godaddy/terminus": "^4.11.2", "@sentry/node": "^7.14.0", "@sentry/tracing": "^7.19.0", "@types/crypto-js": "^4.1.1", diff --git a/backend/src/index.ts b/backend/src/index.ts index a5ae449695..f9789c04d0 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -1,3 +1,5 @@ +/* eslint-disable no-console */ +import http from 'http'; import express from 'express'; import helmet from 'helmet'; import cors from 'cors'; @@ -7,63 +9,67 @@ import dotenv from 'dotenv'; dotenv.config(); import * as Sentry from '@sentry/node'; -import { PORT, SENTRY_DSN, NODE_ENV, MONGO_URL, SITE_URL, POSTHOG_PROJECT_API_KEY, POSTHOG_HOST, TELEMETRY_ENABLED } from './config'; +import { PORT, SENTRY_DSN, NODE_ENV, MONGO_URL, SITE_URL } from './config'; import { apiLimiter } from './helpers/rateLimiter'; +import { createTerminus } from '@godaddy/terminus'; const app = express(); Sentry.init({ - dsn: SENTRY_DSN, - tracesSampleRate: 1.0, - debug: NODE_ENV === 'production' ? false : true, - environment: NODE_ENV + dsn: SENTRY_DSN, + tracesSampleRate: 1.0, + debug: NODE_ENV === 'production' ? false : true, + environment: NODE_ENV }); import { - signup as signupRouter, - auth as authRouter, - organization as organizationRouter, - workspace as workspaceRouter, - membershipOrg as membershipOrgRouter, - membership as membershipRouter, - key as keyRouter, - inviteOrg as inviteOrgRouter, - user as userRouter, - userAction as userActionRouter, - secret as secretRouter, - serviceToken as serviceTokenRouter, - password as passwordRouter, - stripe as stripeRouter, - integration as integrationRouter, - integrationAuth as integrationAuthRouter + signup as signupRouter, + auth as authRouter, + organization as organizationRouter, + workspace as workspaceRouter, + membershipOrg as membershipOrgRouter, + membership as membershipRouter, + key as keyRouter, + inviteOrg as inviteOrgRouter, + user as userRouter, + userAction as userActionRouter, + secret as secretRouter, + serviceToken as serviceTokenRouter, + password as passwordRouter, + stripe as stripeRouter, + integration as integrationRouter, + integrationAuth as integrationAuthRouter } from './routes'; const connectWithRetry = () => { - mongoose.connect(MONGO_URL) - .then(() => console.log('Successfully connected to DB')) - .catch((e) => { - console.log('Failed to connect to DB ', e); - setTimeout(() => { - console.log(e); - }, 5000); - }); -} + mongoose + .connect(MONGO_URL) + .then(() => console.log('Successfully connected to DB')) + .catch((e) => { + console.log('Failed to connect to DB ', e); + setTimeout(() => { + console.log(e); + }, 5000); + }); +}; connectWithRetry(); app.enable('trust proxy'); app.use(cookieParser()); -app.use(cors({ - credentials: true, - origin: SITE_URL -})); +app.use( + cors({ + credentials: true, + origin: SITE_URL + }) +); if (NODE_ENV === 'production') { - // enable app-wide rate-limiting + helmet security - // in production - app.disable('x-powered-by'); - app.use(apiLimiter); - app.use(helmet()); + // enable app-wide rate-limiting + helmet security + // in production + app.disable('x-powered-by'); + app.use(apiLimiter); + app.use(helmet()); } app.use(express.json()); @@ -86,6 +92,31 @@ app.use('/api/v1/stripe', stripeRouter); app.use('/api/v1/integration', integrationRouter); app.use('/api/v1/integration-auth', integrationAuthRouter); -app.listen(PORT, () => { - console.log('Listening on PORT ' + PORT); +const server = http.createServer(app); + +const onSignal = () => { + console.log('Server is starting clean-up'); + return Promise.all([ + // your clean logic, like closing database connections + ]); +}; + +const healthCheck = () => { + // `state.isShuttingDown` (boolean) shows whether the server is shutting down or not + return Promise + .resolve + // optionally include a resolve value to be included as + // info in the health check response + (); +}; + +createTerminus(server, { + healthChecks: { + '/healthcheck': healthCheck, + onSignal + } +}); + +server.listen(PORT, () => { + console.log('Listening on PORT ' + PORT); }); diff --git a/docker-compose.yml b/docker-compose.yml index cc92e14063..bd9022cef8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -15,7 +15,7 @@ services: - backend networks: - infisical - + backend: container_name: infisical-backend restart: unless-stopped @@ -28,7 +28,7 @@ services: - NODE_ENV=production networks: - infisical - + frontend: container_name: infisical-frontend restart: unless-stopped diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 5e59c68aad..5deb468f74 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -60,5 +60,8 @@ EXPOSE 3000 ENV PORT 3000 ENV NEXT_TELEMETRY_DISABLED 1 +HEALTHCHECK --interval=10s --timeout=3s --start-period=10s \ + CMD node scripts/healthcheck.js + CMD ["/app/scripts/start.sh"] diff --git a/frontend/scripts/healthcheck.js b/frontend/scripts/healthcheck.js new file mode 100644 index 0000000000..b29d70f44d --- /dev/null +++ b/frontend/scripts/healthcheck.js @@ -0,0 +1,26 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ +/* eslint-disable no-console */ +/* eslint-disable no-undef */ +const http = require('http'); +const options = { + host: 'localhost', + port: 3000, + timeout: 2000, + path: '/' +}; + +const healthCheck = http.request(options, (res) => { + console.log(`HEALTHCHECK STATUS: ${res.statusCode}`); + if (res.statusCode == 200) { + process.exit(0); + } else { + process.exit(1); + } +}); + +healthCheck.on('error', function (err) { + console.error(err); + process.exit(1); +}); + +healthCheck.end(); From bcd18ab0afbe1c186766b4179102408e2703db4a Mon Sep 17 00:00:00 2001 From: Reginald Bondoc Date: Mon, 12 Dec 2022 19:11:44 +0100 Subject: [PATCH 02/15] Ignore linting healthcheck & exclue in rate-limiting --- .eslintignore | 3 +++ backend/healthcheck.js | 5 +---- backend/src/helpers/rateLimiter.ts | 33 +++++++++++++++--------------- backend/src/index.ts | 9 ++++++-- frontend/scripts/healthcheck.js | 5 +---- 5 files changed, 29 insertions(+), 26 deletions(-) create mode 100644 .eslintignore diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000000..7a3d615587 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,3 @@ +node_modules +built +healthcheck.js diff --git a/backend/healthcheck.js b/backend/healthcheck.js index 7b798eb0a8..8cb3dfcaaf 100644 --- a/backend/healthcheck.js +++ b/backend/healthcheck.js @@ -1,6 +1,3 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ -/* eslint-disable no-console */ -/* eslint-disable no-undef */ const http = require('http'); const PORT = process.env.PORT || 4000; const options = { @@ -20,7 +17,7 @@ const healthCheck = http.request(options, (res) => { }); healthCheck.on('error', function (err) { - console.error(err); + console.error(`HEALTH CHECK ERROR: ${err}`); process.exit(1); }); diff --git a/backend/src/helpers/rateLimiter.ts b/backend/src/helpers/rateLimiter.ts index a0788246aa..6153369e38 100644 --- a/backend/src/helpers/rateLimiter.ts +++ b/backend/src/helpers/rateLimiter.ts @@ -2,34 +2,35 @@ import rateLimit from 'express-rate-limit'; // 300 requests per 15 minutes const apiLimiter = rateLimit({ - windowMs: 15 * 60 * 1000, - max: 400, - standardHeaders: true, - legacyHeaders: false + windowMs: 15 * 60 * 1000, + max: 400, + standardHeaders: true, + legacyHeaders: false, + skip: (request) => request.path === '/healthcheck' }); // 5 requests per hour const signupLimiter = rateLimit({ - windowMs: 60 * 60 * 1000, - max: 10, - standardHeaders: true, - legacyHeaders: false + windowMs: 60 * 60 * 1000, + max: 10, + standardHeaders: true, + legacyHeaders: false }); // 10 requests per hour const loginLimiter = rateLimit({ - windowMs: 60 * 60 * 1000, - max: 20, - standardHeaders: true, - legacyHeaders: false + windowMs: 60 * 60 * 1000, + max: 20, + standardHeaders: true, + legacyHeaders: false }); // 5 requests per hour const passwordLimiter = rateLimit({ - windowMs: 60 * 60 * 1000, - max: 10, - standardHeaders: true, - legacyHeaders: false + windowMs: 60 * 60 * 1000, + max: 10, + standardHeaders: true, + legacyHeaders: false }); export { apiLimiter, signupLimiter, loginLimiter, passwordLimiter }; diff --git a/backend/src/index.ts b/backend/src/index.ts index f9789c04d0..28e27cc9af 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -51,9 +51,10 @@ const connectWithRetry = () => { console.log(e); }, 5000); }); + return mongoose.connection; }; -connectWithRetry(); +const dbConnection = connectWithRetry(); app.enable('trust proxy'); app.use(cookieParser()); @@ -97,7 +98,11 @@ const server = http.createServer(app); const onSignal = () => { console.log('Server is starting clean-up'); return Promise.all([ - // your clean logic, like closing database connections + () => { + dbConnection.close(() => { + console.info('Database connection closed'); + }); + } ]); }; diff --git a/frontend/scripts/healthcheck.js b/frontend/scripts/healthcheck.js index b29d70f44d..30a964d9df 100644 --- a/frontend/scripts/healthcheck.js +++ b/frontend/scripts/healthcheck.js @@ -1,6 +1,3 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ -/* eslint-disable no-console */ -/* eslint-disable no-undef */ const http = require('http'); const options = { host: 'localhost', @@ -19,7 +16,7 @@ const healthCheck = http.request(options, (res) => { }); healthCheck.on('error', function (err) { - console.error(err); + console.error(`HEALTH CHECK ERROR: ${err}`); process.exit(1); }); From 07bb3496e75672e0bd32cc409d87d0c42438ed6d Mon Sep 17 00:00:00 2001 From: Vladyslav Matsiiako Date: Mon, 12 Dec 2022 20:42:16 -0500 Subject: [PATCH 03/15] Added the account recovery flow --- backend/src/models/token.ts | 32 +- frontend/components/basic/InputField.tsx | 2 - frontend/components/basic/Layout.tsx | 10 +- .../api/auth/EmailVerifyOnPasswordReset.ts | 34 ++ .../api/auth/SendEmailOnPasswordReset.ts | 33 ++ .../api/auth/getBackupEncryptedPrivateKey.ts | 26 ++ .../auth/resetPasswordOnAccountRecovery.ts | 50 +++ frontend/pages/email-not-verified.js | 22 ++ frontend/pages/{login.js => login.tsx} | 84 ++--- frontend/pages/password-reset.tsx | 290 ++++++++++++++++++ frontend/pages/signupinvite.js | 6 +- frontend/pages/verify-email.tsx | 94 ++++++ 12 files changed, 616 insertions(+), 67 deletions(-) create mode 100644 frontend/pages/api/auth/EmailVerifyOnPasswordReset.ts create mode 100644 frontend/pages/api/auth/SendEmailOnPasswordReset.ts create mode 100644 frontend/pages/api/auth/getBackupEncryptedPrivateKey.ts create mode 100644 frontend/pages/api/auth/resetPasswordOnAccountRecovery.ts create mode 100644 frontend/pages/email-not-verified.js rename frontend/pages/{login.js => login.tsx} (62%) create mode 100644 frontend/pages/password-reset.tsx create mode 100644 frontend/pages/verify-email.tsx diff --git a/backend/src/models/token.ts b/backend/src/models/token.ts index 9bf8836f5a..5481365a06 100644 --- a/backend/src/models/token.ts +++ b/backend/src/models/token.ts @@ -2,25 +2,25 @@ import { Schema, model } from 'mongoose'; import { EMAIL_TOKEN_LIFETIME } from '../config'; export interface IToken { - email: String; - token: String; - createdAt: Date; + email: string; + token: string; + createdAt: Date; } const tokenSchema = new Schema({ - email: { - type: String, - required: true - }, - token: { - type: String, - required: true - }, - createdAt: { - type: Date, - expires: parseInt(EMAIL_TOKEN_LIFETIME), - default: Date.now - } + email: { + type: String, + required: true + }, + token: { + type: String, + required: true + }, + createdAt: { + type: Date, + expires: parseInt(EMAIL_TOKEN_LIFETIME), + default: Date.now + } }); const Token = model('Token', tokenSchema); diff --git a/frontend/components/basic/InputField.tsx b/frontend/components/basic/InputField.tsx index 1415782142..46b42c15ca 100644 --- a/frontend/components/basic/InputField.tsx +++ b/frontend/components/basic/InputField.tsx @@ -1,5 +1,4 @@ import React, { useState } from 'react'; -import { useRouter } from 'next/router'; import { faCircle, faEye, faEyeSlash } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; @@ -26,7 +25,6 @@ const InputField = ( Pick ) => { const [passwordVisible, setPasswordVisible] = useState(false); - const router = useRouter(); if (props.static === true) { return ( diff --git a/frontend/components/basic/Layout.tsx b/frontend/components/basic/Layout.tsx index 5057f70ce4..56a16cb3de 100644 --- a/frontend/components/basic/Layout.tsx +++ b/frontend/components/basic/Layout.tsx @@ -41,7 +41,7 @@ interface LayoutProps { export default function Layout({ children }: LayoutProps) { const router = useRouter(); const [workspaceList, setWorkspaceList] = useState([]); - const [workspaceMapping, setWorkspaceMapping] = useState([{ 1: 2 }]); + const [workspaceMapping, setWorkspaceMapping] = useState([{ '1': '2' }]); const [workspaceSelected, setWorkspaceSelected] = useState('∞'); const [newWorkspaceName, setNewWorkspaceName] = useState(''); const [isOpen, setIsOpen] = useState(false); @@ -221,20 +221,20 @@ export default function Layout({ children }: LayoutProps) { useEffect(() => { try { if ( - workspaceMapping[Number(workspaceSelected)] && - `${workspaceMapping[Number(workspaceSelected)]}` !== + workspaceMapping[workspaceSelected as any] && + `${workspaceMapping[workspaceSelected as any]}` !== router.asPath .split('/') [router.asPath.split('/').length - 1].split('?')[0] ) { router.push( '/dashboard/' + - workspaceMapping[Number(workspaceSelected)] + + workspaceMapping[workspaceSelected as any] + '?Development' ); localStorage.setItem( 'projectData.id', - `${workspaceMapping[Number(workspaceSelected)]}` + `${workspaceMapping[workspaceSelected as any]}` ); } } catch (error) { diff --git a/frontend/pages/api/auth/EmailVerifyOnPasswordReset.ts b/frontend/pages/api/auth/EmailVerifyOnPasswordReset.ts new file mode 100644 index 0000000000..b3d5e3d558 --- /dev/null +++ b/frontend/pages/api/auth/EmailVerifyOnPasswordReset.ts @@ -0,0 +1,34 @@ +interface Props { + email: string; + code: string; +} + +/** + * This is the second part of the account recovery step (a user needs to verify their email). + * A user need to click on a button in a magic link page + * @param {object} obj + * @param {object} obj.email - email of a user that is trying to recover access to their account + * @param {object} obj.code - token that a use received via the magic link + * @returns + */ +const EmailVerifyOnPasswordReset = async ({ email, code }: Props) => { + const response = await fetch('/api/v1/password/email/password-reset-verify', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + email: email, + code: code + }) + }); + if (response?.status === 200) { + return response; + } + + throw new Error( + 'Something went wrong during email verification on password reset.' + ); +}; + +export default EmailVerifyOnPasswordReset; diff --git a/frontend/pages/api/auth/SendEmailOnPasswordReset.ts b/frontend/pages/api/auth/SendEmailOnPasswordReset.ts new file mode 100644 index 0000000000..abe610f07d --- /dev/null +++ b/frontend/pages/api/auth/SendEmailOnPasswordReset.ts @@ -0,0 +1,33 @@ +interface Props { + email: string; +} + +/** + * This is the first of the account recovery step (a user needs to verify their email). + * It will send an email containing a magic link to start the account recovery flow. + * @param {object} obj + * @param {object} obj.email - email of a user that is trying to recover access to their account + * @returns + */ +const SendEmailOnPasswordReset = async ({ email }: Props) => { + const response = await fetch('/api/v1/password/email/password-reset', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + email: email + }) + }); + // need precise error handling about the status code + if (response?.status === 200) { + const data = await response.json(); + return data; + } + + throw new Error( + 'Something went wrong while sending the email verification for password reset.' + ); +}; + +export default SendEmailOnPasswordReset; diff --git a/frontend/pages/api/auth/getBackupEncryptedPrivateKey.ts b/frontend/pages/api/auth/getBackupEncryptedPrivateKey.ts new file mode 100644 index 0000000000..826085263e --- /dev/null +++ b/frontend/pages/api/auth/getBackupEncryptedPrivateKey.ts @@ -0,0 +1,26 @@ +/** + * This is the route that get an encrypted private key (will be decrypted with a backup key) + * @param {object} obj + * @param {object} obj.verificationToken - this is the token that confirms that a user is the right one + * @returns + */ +const getBackupEncryptedPrivateKey = ({ + verificationToken +}: { + verificationToken: string; +}) => { + return fetch('/api/v1/password/backup-private-key', { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer ' + verificationToken + } + }).then(async (res) => { + if (res?.status !== 200) { + console.log('Failed to get the backup key'); + } + return (await res?.json())?.backupPrivateKey; + }); +}; + +export default getBackupEncryptedPrivateKey; diff --git a/frontend/pages/api/auth/resetPasswordOnAccountRecovery.ts b/frontend/pages/api/auth/resetPasswordOnAccountRecovery.ts new file mode 100644 index 0000000000..f2b5ad98ea --- /dev/null +++ b/frontend/pages/api/auth/resetPasswordOnAccountRecovery.ts @@ -0,0 +1,50 @@ +interface Props { + verificationToken: string; + encryptedPrivateKey: string; + iv: string; + tag: string; + salt: string; + verifier: string; +} + +/** + * This is the route that resets the account password if all the previus steps were passed + * @param {object} obj + * @param {object} obj.verificationToken - this is the token that confirms that a user is the right one + * @param {object} obj.encryptedPrivateKey - the new encrypted private key (encrypted using the new password) + * @param {object} obj.iv + * @param {object} obj.tag + * @param {object} obj.salt + * @param {object} obj.verifier + * @returns + */ +const resetPasswordOnAccountRecovery = ({ + verificationToken, + encryptedPrivateKey, + iv, + tag, + salt, + verifier +}: Props) => { + return fetch('/api/v1/password/password-reset', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer ' + verificationToken + }, + body: JSON.stringify({ + encryptedPrivateKey: encryptedPrivateKey, + iv: iv, + tag: tag, + salt: salt, + verifier: verifier + }) + }).then(async (res) => { + if (res?.status !== 200) { + console.log('Failed to get the backup key'); + } + return res; + }); +}; + +export default resetPasswordOnAccountRecovery; diff --git a/frontend/pages/email-not-verified.js b/frontend/pages/email-not-verified.js new file mode 100644 index 0000000000..11aec70bd4 --- /dev/null +++ b/frontend/pages/email-not-verified.js @@ -0,0 +1,22 @@ +import React from 'react'; +import Head from 'next/head'; + +export default function Activity() { + return ( +
+ + Request a New Invite + + +
+

Oops.

+

Your email was not verified.

+

Please try again.

+

+ Note: If it still {"doesn't work"}, please reach out to us at + support@infisical.com +

+
+
+ ); +} diff --git a/frontend/pages/login.js b/frontend/pages/login.tsx similarity index 62% rename from frontend/pages/login.js rename to frontend/pages/login.tsx index 2b5d6062c7..63dae65a76 100644 --- a/frontend/pages/login.js +++ b/frontend/pages/login.tsx @@ -1,34 +1,37 @@ -import React, { useEffect, useState } from "react"; -import Head from "next/head"; -import Image from "next/image"; -import Link from "next/link"; -import { useRouter } from "next/router"; -import { faWarning } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import React, { useEffect, useState } from 'react'; +import Head from 'next/head'; +import Image from 'next/image'; +import Link from 'next/link'; +import { useRouter } from 'next/router'; +import { faWarning } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import Button from "~/components/basic/buttons/Button"; -import Error from "~/components/basic/Error"; -import InputField from "~/components/basic/InputField"; -import attemptLogin from "~/utilities/attemptLogin"; +import Button from '~/components/basic/buttons/Button'; +import Error from '~/components/basic/Error'; +import InputField from '~/components/basic/InputField'; +import attemptLogin from '~/utilities/attemptLogin'; -import getWorkspaces from "./api/workspace/getWorkspaces"; +import getWorkspaces from './api/workspace/getWorkspaces'; export default function Login() { - const [email, setEmail] = useState(""); - const [password, setPassword] = useState(""); + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); const [errorLogin, setErrorLogin] = useState(false); const [isLoading, setIsLoading] = useState(false); const router = useRouter(); - useEffect(async () => { - let userWorkspace; - try { - const userWorkspaces = await getWorkspaces(); - userWorkspace = userWorkspaces[0]._id; - router.push("/dashboard/" + userWorkspace); - } catch (error) { - console.log("Error - Not logged in yet"); - } + useEffect(() => { + const redirectToDashboard = async () => { + let userWorkspace; + try { + const userWorkspaces = await getWorkspaces(); + userWorkspace = userWorkspaces[0]._id; + router.push('/dashboard/' + userWorkspace); + } catch (error) { + console.log('Error - Not logged in yet'); + } + }; + redirectToDashboard(); }, []); /** @@ -73,23 +76,9 @@ export default function Login() {
-

- Log In +

+ Log in to your account

-
-

- Need an Infisical account? -

-
-
- - - -
-
+
+
+ Forgot password? +
{errorLogin && }
@@ -135,6 +127,16 @@ export default function Login() { solving it right now. Please come back in a few minutes.
)} +
+

+ Need an Infisical account? +

+ + + +
); } diff --git a/frontend/pages/password-reset.tsx b/frontend/pages/password-reset.tsx new file mode 100644 index 0000000000..a09b85ab08 --- /dev/null +++ b/frontend/pages/password-reset.tsx @@ -0,0 +1,290 @@ +import React, { useState } from 'react'; +import Image from 'next/image'; +import { useRouter } from 'next/router'; +import { faCheck, faX } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; + +import Button from '~/components/basic/buttons/Button'; +import InputField from '~/components/basic/InputField'; +import passwordCheck from '~/components/utilities/checks/PasswordCheck'; +import Aes256Gcm from '~/components/utilities/cryptography/aes-256-gcm'; + +import EmailVerifyOnPasswordReset from './api/auth/EmailVerifyOnPasswordReset'; +import getBackupEncryptedPrivateKey from './api/auth/getBackupEncryptedPrivateKey'; +import resetPasswordOnAccountRecovery from './api/auth/resetPasswordOnAccountRecovery'; + +const queryString = require('query-string'); +const nacl = require('tweetnacl'); +const jsrp = require('jsrp'); +nacl.util = require('tweetnacl-util'); +const client = new jsrp.client(); + +export default function PasswordReset() { + const router = useRouter(); + const parsedUrl = queryString.parse(router.asPath.split('?')[1]); + const token = parsedUrl.token; + const email = parsedUrl.to?.replace(' ', '+').trim(); + const [verificationToken, setVerificationToken] = useState(''); + const [step, setStep] = useState(1); + const [backupKey, setBackupKey] = useState(''); + const [privateKey, setPrivateKey] = useState(''); + const [newPassword, setNewPassword] = useState(''); + const [backupKeyError, setBackupKeyError] = useState(false); + const [passwordErrorLength, setPasswordErrorLength] = useState(false); + const [passwordErrorNumber, setPasswordErrorNumber] = useState(false); + const [passwordErrorLowerCase, setPasswordErrorLowerCase] = useState(false); + + // Unencrypt the private key with a backup key + const getEncryptedKeyHandler = async () => { + try { + const result = await getBackupEncryptedPrivateKey({ verificationToken }); + setPrivateKey( + Aes256Gcm.decrypt({ + ciphertext: result.encryptedPrivateKey, + iv: result.iv, + tag: result.tag, + secret: backupKey + }) + ); + setStep(3); + } catch { + setBackupKeyError(true); + } + }; + + // If everything is correct, reset the password + const resetPasswordHandler = async () => { + let errorCheck = false; + errorCheck = passwordCheck({ + password: newPassword, + setPasswordErrorLength, + setPasswordErrorNumber, + setPasswordErrorLowerCase, + currentErrorCheck: errorCheck + }); + + if (!errorCheck) { + // Generate a random pair of a public and a private key + const { ciphertext, iv, tag } = Aes256Gcm.encrypt({ + text: privateKey, + secret: newPassword + .slice(0, 32) + .padStart( + 32 + + (newPassword.slice(0, 32).length - new Blob([newPassword]).size), + '0' + ) + }) as { ciphertext: string; iv: string; tag: string }; + + client.init( + { + username: email, + password: newPassword + }, + async () => { + client.createVerifier( + async (err: any, result: { salt: string; verifier: string }) => { + const response = await resetPasswordOnAccountRecovery({ + verificationToken, + encryptedPrivateKey: ciphertext, + iv, + tag, + salt: result.salt, + verifier: result.verifier + }); + + // if everything works, go the main dashboard page. + if (response?.status === 200) { + router.push('/login'); + } + } + ); + } + ); + } + }; + + // Click a button to confirm email + const stepConfirmEmail = ( +
+

+ Confirm your email +

+ verify email +
+
+
+ ); + + // Input backup key + const stepInputBackupKey = ( +
+

+ Enter your backup key +

+
+

+ You can find it in your emrgency kit. You had to download the enrgency + kit during signup. +

+
+
+ +
+
+
+
+
+
+ ); + + // Enter new password + const stepEnterNewPassword = ( +
+

+ Enter new password +

+
+

+ Make sure you save it somewhere save. +

+
+
+ { + setNewPassword(password); + passwordCheck({ + password, + setPasswordErrorLength, + setPasswordErrorNumber, + setPasswordErrorLowerCase, + currentErrorCheck: false + }); + }} + type="password" + value={newPassword} + isRequired + error={ + passwordErrorLength && passwordErrorLowerCase && passwordErrorNumber + } + autoComplete="new-password" + id="new-password" + /> +
+ {passwordErrorLength || passwordErrorLowerCase || passwordErrorNumber ? ( +
+
+ Password should contain at least: +
+
+ {passwordErrorLength ? ( + + ) : ( + + )} +
+ 14 characters +
+
+
+ {passwordErrorLowerCase ? ( + + ) : ( + + )} +
+ 1 lowercase character +
+
+
+ {passwordErrorNumber ? ( + + ) : ( + + )} +
+ 1 number +
+
+
+ ) : ( +
+ )} +
+
+
+
+
+ ); + + return ( +
+ {step === 1 && stepConfirmEmail} + {step === 2 && stepInputBackupKey} + {step === 3 && stepEnterNewPassword} +
+ ); +} diff --git a/frontend/pages/signupinvite.js b/frontend/pages/signupinvite.js index 26b6e1544f..1c1d9be370 100644 --- a/frontend/pages/signupinvite.js +++ b/frontend/pages/signupinvite.js @@ -33,7 +33,7 @@ export default function SignupInvite() { const [passwordErrorLowerCase, setPasswordErrorLowerCase] = useState(false); const router = useRouter(); const parsedUrl = queryString.parse(router.asPath.split('?')[1]); - const [email, setEmail] = useState(parsedUrl.to); + const [email, setEmail] = useState(parsedUrl.to.replace(' ', '+').trim()); const token = parsedUrl.token; const [errorLogin, setErrorLogin] = useState(false); const [isLoading, setIsLoading] = useState(false); @@ -150,7 +150,7 @@ export default function SignupInvite() { width={410} alt="verify email" > -
+
+
+
+ )} + {step == 2 && ( +
+

+ Look for an email in your inbox. +

+
+

+ An email with instructions has been sent to {email}. +

+
+
+ )} + + ); +} From 584d309b803ea81e0167854b263d49883bb85a60 Mon Sep 17 00:00:00 2001 From: mv-turtle <78047717+mv-turtle@users.noreply.github.com> Date: Tue, 13 Dec 2022 09:52:30 -0500 Subject: [PATCH 04/15] Fixed the TS bug in signupinvite --- frontend/pages/signupinvite.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/pages/signupinvite.js b/frontend/pages/signupinvite.js index 1c1d9be370..04ec73eb25 100644 --- a/frontend/pages/signupinvite.js +++ b/frontend/pages/signupinvite.js @@ -33,7 +33,7 @@ export default function SignupInvite() { const [passwordErrorLowerCase, setPasswordErrorLowerCase] = useState(false); const router = useRouter(); const parsedUrl = queryString.parse(router.asPath.split('?')[1]); - const [email, setEmail] = useState(parsedUrl.to.replace(' ', '+').trim()); + const [email, setEmail] = useState(parsedUrl.to?.replace(' ', '+').trim()); const token = parsedUrl.token; const [errorLogin, setErrorLogin] = useState(false); const [isLoading, setIsLoading] = useState(false); From 63253d515fc72207ed59dbae6b8213c504a6afdb Mon Sep 17 00:00:00 2001 From: Maidul Islam Date: Tue, 13 Dec 2022 12:46:19 -0500 Subject: [PATCH 05/15] quote secrets for template --- helm-charts/infisical/templates/backend-deployment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helm-charts/infisical/templates/backend-deployment.yaml b/helm-charts/infisical/templates/backend-deployment.yaml index c2620ff8ac..0c239867bc 100644 --- a/helm-charts/infisical/templates/backend-deployment.yaml +++ b/helm-charts/infisical/templates/backend-deployment.yaml @@ -26,7 +26,7 @@ spec: {{ fail "Environment variables are not set. Please set all environment variables to continue." }} {{ end }} - name: {{ $key }} - value: {{ $value }} + value: {{ quote $value }} {{- end }} --- From d1c38513f7725032c2d2a0142f4cb01284e00759 Mon Sep 17 00:00:00 2001 From: Maidul Islam Date: Tue, 13 Dec 2022 12:48:29 -0500 Subject: [PATCH 06/15] update chart version --- helm-charts/infisical/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helm-charts/infisical/Chart.yaml b/helm-charts/infisical/Chart.yaml index 48eb5d4dc0..a9297b385e 100644 --- a/helm-charts/infisical/Chart.yaml +++ b/helm-charts/infisical/Chart.yaml @@ -7,7 +7,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.2 +version: 0.1.3 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to From 62f0b3f6dfa65b8165cdad49869a647f84cd4619 Mon Sep 17 00:00:00 2001 From: Tuan Dang Date: Tue, 13 Dec 2022 15:22:07 -0500 Subject: [PATCH 07/15] Patch EMAIL_TOKEN_LIFETIME expiring early --- backend/src/models/token.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/backend/src/models/token.ts b/backend/src/models/token.ts index 5481365a06..9569aee0bc 100644 --- a/backend/src/models/token.ts +++ b/backend/src/models/token.ts @@ -18,11 +18,16 @@ const tokenSchema = new Schema({ }, createdAt: { type: Date, - expires: parseInt(EMAIL_TOKEN_LIFETIME), default: Date.now } }); +tokenSchema.index({ + createdAt: 1 +}, { + expireAfterSeconds: parseInt(EMAIL_TOKEN_LIFETIME) +}); + const Token = model('Token', tokenSchema); export default Token; From 1a3d3906da8bb3d67ea4a3357474dc561c4aeaf1 Mon Sep 17 00:00:00 2001 From: Tuan Dang Date: Tue, 13 Dec 2022 16:25:19 -0500 Subject: [PATCH 08/15] Change jid path --- backend/src/controllers/authController.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/controllers/authController.ts b/backend/src/controllers/authController.ts index eb537f2b98..4522af9c65 100644 --- a/backend/src/controllers/authController.ts +++ b/backend/src/controllers/authController.ts @@ -103,7 +103,7 @@ export const login2 = async (req: Request, res: Response) => { // store (refresh) token in httpOnly cookie res.cookie('jid', tokens.refreshToken, { httpOnly: true, - path: '/token', + path: '/', sameSite: 'strict', secure: NODE_ENV === 'production' ? true : false }); From 5db60c0dad72956d7a50939c0c1417223a6cb032 Mon Sep 17 00:00:00 2001 From: Maidul Islam Date: Tue, 13 Dec 2022 17:55:43 -0500 Subject: [PATCH 09/15] update helm template; check for non string --- helm-charts/infisical/templates/backend-deployment.yaml | 2 +- helm-charts/infisical/templates/frontend-deployment.yaml | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/helm-charts/infisical/templates/backend-deployment.yaml b/helm-charts/infisical/templates/backend-deployment.yaml index 0c239867bc..6a2faa6885 100644 --- a/helm-charts/infisical/templates/backend-deployment.yaml +++ b/helm-charts/infisical/templates/backend-deployment.yaml @@ -22,7 +22,7 @@ spec: - containerPort: 4000 env: {{- range $key, $value := .Values.backendEnvironmentVariables }} - {{- if eq $value "MUST_REPLACE" }} + {{- if $value | quote | eq "MUST_REPLACE" }} {{ fail "Environment variables are not set. Please set all environment variables to continue." }} {{ end }} - name: {{ $key }} diff --git a/helm-charts/infisical/templates/frontend-deployment.yaml b/helm-charts/infisical/templates/frontend-deployment.yaml index 79bf8837b7..3cd29f326c 100644 --- a/helm-charts/infisical/templates/frontend-deployment.yaml +++ b/helm-charts/infisical/templates/frontend-deployment.yaml @@ -20,6 +20,9 @@ spec: imagePullPolicy: {{ .Values.frontend.image.pullPolicy }} env: {{- range $key, $value := .Values.frontendEnvironmentVariables }} + {{- if $value | quote | eq "MUST_REPLACE" }} + {{ fail "Environment variables are not set. Please set all environment variables to continue." }} + {{ end }} - name: {{ $key }} value: {{ quote $value }} {{- end }} From c33b043f5f2c0e44a927f31fb1474649454ec770 Mon Sep 17 00:00:00 2001 From: Maidul Islam Date: Tue, 13 Dec 2022 18:54:45 -0500 Subject: [PATCH 10/15] remove cookie path temporary --- backend/src/controllers/authController.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/controllers/authController.ts b/backend/src/controllers/authController.ts index 4522af9c65..20ac813d4d 100644 --- a/backend/src/controllers/authController.ts +++ b/backend/src/controllers/authController.ts @@ -147,7 +147,7 @@ export const logout = async (req: Request, res: Response) => { // clear httpOnly cookie res.cookie('jid', '', { httpOnly: true, - path: '/token', + path: '/', sameSite: 'strict', secure: NODE_ENV === 'production' ? true : false }); From 2f54c4dd7e0b3e496fb341652833cd104afe664a Mon Sep 17 00:00:00 2001 From: Maidul Islam Date: Tue, 13 Dec 2022 20:07:53 -0500 Subject: [PATCH 11/15] add sharp for prod nextjs build --- frontend/package-lock.json | 639 +++++++++++++++++++++++++++++++++++-- frontend/package.json | 1 + 2 files changed, 620 insertions(+), 20 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 229fd05fca..5e3bb010b9 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -41,6 +41,7 @@ "react-redux": "^8.0.2", "react-table": "^7.8.0", "set-cookie-parser": "^2.5.1", + "sharp": "^0.31.2", "styled-components": "^5.3.5", "tweetnacl": "^1.0.3", "tweetnacl-util": "^0.15.1", @@ -2025,6 +2026,25 @@ "node": ">= 0.6.0" } }, + "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/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -2034,6 +2054,16 @@ "node": ">=8" } }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -2094,6 +2124,29 @@ "node": ">= 0.4.0" } }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "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.1.13" + } + }, "node_modules/buffer-from": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-0.1.2.tgz", @@ -2229,6 +2282,11 @@ "node": ">= 6" } }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, "node_modules/cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", @@ -2251,11 +2309,22 @@ "node": ">=6" } }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -2266,8 +2335,16 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } }, "node_modules/combined-stream": { "version": "1.0.8", @@ -2474,6 +2551,28 @@ "node": ">=0.10" } }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -2544,6 +2643,14 @@ "node": ">=6" } }, + "node_modules/detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "engines": { + "node": ">=8" + } + }, "node_modules/detective": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", @@ -2657,6 +2764,14 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/enhanced-resolve": { "version": "5.12.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", @@ -3421,6 +3536,14 @@ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "engines": { + "node": ">=6" + } + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -3619,6 +3742,11 @@ "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", "integrity": "sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==" }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -3724,6 +3852,11 @@ "resolved": "https://registry.npmjs.org/github-buttons/-/github-buttons-2.22.0.tgz", "integrity": "sha512-N5bk01s1WgK1FVtoeSUVkRkJpkaSu8yHMPcjye+PTa0jsRjMRNrYqVLgpUf2RA5Kvec05DfHYAT6/68fwkdqPw==" }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" + }, "node_modules/glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -3981,6 +4114,25 @@ "node": ">=8.0.0" } }, + "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/ignore": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", @@ -4038,6 +4190,11 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, "node_modules/inline-style-parser": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", @@ -4057,6 +4214,11 @@ "node": ">= 0.4" } }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -4605,7 +4767,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -5205,6 +5366,17 @@ "node": ">= 0.6" } }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -5222,6 +5394,11 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, "node_modules/mri": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", @@ -5255,6 +5432,11 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -5319,6 +5501,22 @@ } } }, + "node_modules/node-abi": { + "version": "3.30.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.30.0.tgz", + "integrity": "sha512-qWO5l3SCqbwQavymOmtTVuCWZE23++S+rxyoHjXqUmPyzRcaoI4lA2gO55/drddGnedAyjA7sk76SfQ5lfUMnw==", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-addon-api": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.0.0.tgz", + "integrity": "sha512-CvkDw2OEnme7ybCykJpVcKH+uAOLV2qLqiyla128dN9TkEWfrYmxG6C2boDe5KcNQqZF3orkqzGgOMvZ/JNekA==" + }, "node_modules/node-releases": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", @@ -5465,7 +5663,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "dependencies": { "wrappy": "1" } @@ -5768,6 +5965,31 @@ "rrweb-snapshot": "^1.1.14" } }, + "node_modules/prebuild-install": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", + "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -5816,6 +6038,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -5896,6 +6127,28 @@ "safe-buffer": "^5.1.0" } }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/react": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", @@ -6465,7 +6718,6 @@ "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -6498,6 +6750,28 @@ "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" }, + "node_modules/sharp": { + "version": "0.31.2", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.31.2.tgz", + "integrity": "sha512-DUdNVEXgS5A97cTagSLIIp8dUZ/lZtk78iNVZgHdHbx1qnQR7JAHY0BnXnwwH39Iw+VKhO08CTYhIg0p98vQ5Q==", + "hasInstallScript": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.1", + "node-addon-api": "^5.0.0", + "prebuild-install": "^7.1.1", + "semver": "^7.3.8", + "simple-get": "^4.0.1", + "tar-fs": "^2.1.1", + "tunnel-agent": "^0.6.0" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -6533,6 +6807,57 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "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/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "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": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -6851,6 +7176,32 @@ "node": ">=6" } }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/text-segmentation": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", @@ -7028,6 +7379,17 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, "node_modules/tweetnacl": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", @@ -7363,8 +7725,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/xtend": { "version": "4.0.2", @@ -7378,8 +7739,7 @@ "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/yaml": { "version": "1.10.2", @@ -8796,12 +9156,27 @@ "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", "optional": true }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -8837,6 +9212,15 @@ "resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz", "integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==" }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "buffer-from": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-0.1.2.tgz", @@ -8931,6 +9315,11 @@ } } }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", @@ -8950,11 +9339,19 @@ "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==" }, + "color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "requires": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + } + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "requires": { "color-name": "~1.1.4" } @@ -8962,8 +9359,16 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } }, "combined-stream": { "version": "1.0.8", @@ -9130,6 +9535,19 @@ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==" }, + "decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "requires": { + "mimic-response": "^3.1.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, "deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -9181,6 +9599,11 @@ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==" }, + "detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==" + }, "detective": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", @@ -9281,6 +9704,14 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, "enhanced-resolve": { "version": "5.12.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", @@ -9848,6 +10279,11 @@ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" }, + "expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==" + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -9997,6 +10433,11 @@ "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", "integrity": "sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==" }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -10071,6 +10512,11 @@ "resolved": "https://registry.npmjs.org/github-buttons/-/github-buttons-2.22.0.tgz", "integrity": "sha512-N5bk01s1WgK1FVtoeSUVkRkJpkaSu8yHMPcjye+PTa0jsRjMRNrYqVLgpUf2RA5Kvec05DfHYAT6/68fwkdqPw==" }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" + }, "glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -10269,6 +10715,11 @@ "requires-port": "^1.0.0" } }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, "ignore": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", @@ -10310,6 +10761,11 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, "inline-style-parser": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", @@ -10326,6 +10782,11 @@ "side-channel": "^1.0.4" } }, + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -10713,7 +11174,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "requires": { "yallist": "^4.0.0" } @@ -11065,6 +11525,11 @@ "mime-db": "1.52.0" } }, + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -11079,6 +11544,11 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, "mri": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", @@ -11103,6 +11573,11 @@ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" }, + "napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -11141,6 +11616,19 @@ "use-sync-external-store": "1.2.0" } }, + "node-abi": { + "version": "3.30.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.30.0.tgz", + "integrity": "sha512-qWO5l3SCqbwQavymOmtTVuCWZE23++S+rxyoHjXqUmPyzRcaoI4lA2gO55/drddGnedAyjA7sk76SfQ5lfUMnw==", + "requires": { + "semver": "^7.3.5" + } + }, + "node-addon-api": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.0.0.tgz", + "integrity": "sha512-CvkDw2OEnme7ybCykJpVcKH+uAOLV2qLqiyla128dN9TkEWfrYmxG6C2boDe5KcNQqZF3orkqzGgOMvZ/JNekA==" + }, "node-releases": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", @@ -11247,7 +11735,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "requires": { "wrappy": "1" } @@ -11438,6 +11925,25 @@ "rrweb-snapshot": "^1.1.14" } }, + "prebuild-install": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", + "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "requires": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + } + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -11470,6 +11976,15 @@ "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.1.1.tgz", "integrity": "sha512-hrzC564QIl0r0vy4l6MvRLhafmUowhO/O3KgVSoXIbbA2Sz4j8HGpJc6T2cubRVwMwpdiG/vKGfhT4IixmKN9w==" }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -11521,6 +12036,24 @@ "safe-buffer": "^5.1.0" } }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==" + } + } + }, "react": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", @@ -11924,7 +12457,6 @@ "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, "requires": { "lru-cache": "^6.0.0" } @@ -11948,6 +12480,21 @@ "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" }, + "sharp": { + "version": "0.31.2", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.31.2.tgz", + "integrity": "sha512-DUdNVEXgS5A97cTagSLIIp8dUZ/lZtk78iNVZgHdHbx1qnQR7JAHY0BnXnwwH39Iw+VKhO08CTYhIg0p98vQ5Q==", + "requires": { + "color": "^4.2.3", + "detect-libc": "^2.0.1", + "node-addon-api": "^5.0.0", + "prebuild-install": "^7.1.1", + "semver": "^7.3.8", + "simple-get": "^4.0.1", + "tar-fs": "^2.1.1", + "tunnel-agent": "^0.6.0" + } + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -11974,6 +12521,29 @@ "object-inspect": "^1.9.0" } }, + "simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" + }, + "simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "requires": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "requires": { + "is-arrayish": "^0.3.1" + } + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -12189,6 +12759,29 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "dev": true }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + }, "text-segmentation": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", @@ -12343,6 +12936,14 @@ } } }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, "tweetnacl": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", @@ -12578,8 +13179,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "xtend": { "version": "4.0.2", @@ -12590,8 +13190,7 @@ "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "yaml": { "version": "1.10.2", diff --git a/frontend/package.json b/frontend/package.json index 8842aa2965..7f7926c880 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -44,6 +44,7 @@ "react-redux": "^8.0.2", "react-table": "^7.8.0", "set-cookie-parser": "^2.5.1", + "sharp": "^0.31.2", "styled-components": "^5.3.5", "tweetnacl": "^1.0.3", "tweetnacl-util": "^0.15.1", From f3900213b52532a0ea25950af19726b32e22b340 Mon Sep 17 00:00:00 2001 From: Tuan Dang Date: Tue, 13 Dec 2022 21:59:12 -0500 Subject: [PATCH 12/15] Add telemetry output at backend container start --- backend/src/services/PostHogClient.ts | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/backend/src/services/PostHogClient.ts b/backend/src/services/PostHogClient.ts index eaf56aa6ab..4096ac8ec4 100644 --- a/backend/src/services/PostHogClient.ts +++ b/backend/src/services/PostHogClient.ts @@ -1,15 +1,19 @@ import { PostHog } from 'posthog-node'; -import { NODE_ENV, POSTHOG_HOST, POSTHOG_PROJECT_API_KEY, TELEMETRY_ENABLED } from '../config'; +import { + NODE_ENV, + POSTHOG_HOST, + POSTHOG_PROJECT_API_KEY, + TELEMETRY_ENABLED +} from '../config'; + +console.log('TELEMETRY_ENABLED: ', TELEMETRY_ENABLED); let postHogClient: any; -if ( - NODE_ENV === 'production' - && TELEMETRY_ENABLED -) { - // case: enable opt-out telemetry in production - postHogClient = new PostHog(POSTHOG_PROJECT_API_KEY, { - host: POSTHOG_HOST - }); +if (NODE_ENV === 'production' && TELEMETRY_ENABLED) { + // case: enable opt-out telemetry in production + postHogClient = new PostHog(POSTHOG_PROJECT_API_KEY, { + host: POSTHOG_HOST + }); } -export default postHogClient; \ No newline at end of file +export default postHogClient; From c9448656bf41d3a8c04ea8008fd3dd52ecf67027 Mon Sep 17 00:00:00 2001 From: Vladyslav Matsiiako Date: Tue, 13 Dec 2022 23:30:53 -0500 Subject: [PATCH 13/15] Fixed the TS error with signup invites --- frontend/pages/signupinvite.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/pages/signupinvite.js b/frontend/pages/signupinvite.js index 04ec73eb25..a41010aeaf 100644 --- a/frontend/pages/signupinvite.js +++ b/frontend/pages/signupinvite.js @@ -58,13 +58,13 @@ export default function SignupInvite() { } else { setLastNameError(false); } - errorCheck = passwordCheck( + errorCheck = passwordCheck({ password, setPasswordErrorLength, setPasswordErrorNumber, setPasswordErrorLowerCase, errorCheck - ); + }); if (!errorCheck) { // Generate a random pair of a public and a private key @@ -329,7 +329,7 @@ export default function SignupInvite() { It contains your Secret Key which we cannot access or recover for you if you lose it. -
+