diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000..1ffdeb3374 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "workbench.editor.wrapTabs": true +} diff --git a/backend/.eslintrc b/backend/.eslintrc index c1ca1a1eba..64b049ea7d 100644 --- a/backend/.eslintrc +++ b/backend/.eslintrc @@ -1,12 +1,21 @@ { "parser": "@typescript-eslint/parser", - "plugins": ["@typescript-eslint"], + "plugins": ["@typescript-eslint", "unused-imports"], "extends": [ "eslint:recommended", "plugin:@typescript-eslint/eslint-recommended", "plugin:@typescript-eslint/recommended" ], "rules": { - "no-console": 2 + "no-console": 2, + "quotes": ["error", "double", { "avoidEscape": true }], + "comma-dangle": ["error", "only-multiline"], + "@typescript-eslint/no-unused-vars": "off", + "unused-imports/no-unused-imports": "error", + "unused-imports/no-unused-vars": [ + "warn", + { "vars": "all", "varsIgnorePattern": "^_", "args": "after-used", "argsIgnorePattern": "^_" } + ], + "sort-imports": ["error", { "ignoreDeclarationSort": true }] } } diff --git a/backend/.prettierrc b/backend/.prettierrc new file mode 100644 index 0000000000..0b8ef54d2f --- /dev/null +++ b/backend/.prettierrc @@ -0,0 +1,7 @@ +{ + "singleQuote": false, + "printWidth": 100, + "trailingComma": "none", + "tabWidth": 2, + "semi": true +} diff --git a/backend/environment.d.ts b/backend/environment.d.ts index 3793552b1b..9bbff7a240 100644 --- a/backend/environment.d.ts +++ b/backend/environment.d.ts @@ -14,7 +14,7 @@ declare global { JWT_SIGNUP_LIFETIME: string; JWT_SIGNUP_SECRET: string; MONGO_URL: string; - NODE_ENV: 'development' | 'staging' | 'testing' | 'production'; + NODE_ENV: "development" | "staging" | "testing" | "production"; VERBOSE_ERROR_OUTPUT: string; LOKI_HOST: string; CLIENT_ID_HEROKU: string; diff --git a/backend/jest.config.ts b/backend/jest.config.ts index 8a72ad84c0..7c657505b9 100644 --- a/backend/jest.config.ts +++ b/backend/jest.config.ts @@ -1,9 +1,9 @@ export default { - preset: 'ts-jest', - testEnvironment: 'node', - collectCoverageFrom: ['src/*.{js,ts}', '!**/node_modules/**'], - modulePaths: ['/src'], - testMatch: ['/tests/**/*.test.ts'], - setupFiles: ['/test-resources/env-vars.js'], - setupFilesAfterEnv: ['/tests/setupTests.ts'] + preset: "ts-jest", + testEnvironment: "node", + collectCoverageFrom: ["src/*.{js,ts}", "!**/node_modules/**"], + modulePaths: ["/src"], + testMatch: ["/tests/**/*.test.ts"], + setupFiles: ["/test-resources/env-vars.js"], + setupFilesAfterEnv: ["/tests/setupTests.ts"], }; diff --git a/backend/package-lock.json b/backend/package-lock.json index 302ade10b9..2405cd370a 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -1,12455 +1,8 @@ { "name": "infisical-api", "version": "1.0.0", - "lockfileVersion": 2, + "lockfileVersion": 1, "requires": true, - "packages": { - "": { - "name": "infisical-api", - "version": "1.0.0", - "license": "ISC", - "dependencies": { - "@aws-sdk/client-secrets-manager": "^3.319.0", - "@godaddy/terminus": "^4.12.0", - "@octokit/rest": "^19.0.5", - "@sentry/node": "^7.49.0", - "@sentry/tracing": "^7.48.0", - "@types/crypto-js": "^4.1.1", - "@types/libsodium-wrappers": "^0.7.10", - "argon2": "^0.30.3", - "await-to-js": "^3.0.0", - "aws-sdk": "^2.1364.0", - "axios": "^1.3.5", - "axios-retry": "^3.4.0", - "bcrypt": "^5.1.0", - "bigint-conversion": "^2.4.0", - "builder-pattern": "^2.2.0", - "cookie-parser": "^1.4.6", - "cors": "^2.8.5", - "crypto-js": "^4.1.1", - "dotenv": "^16.0.1", - "express": "^4.18.1", - "express-async-errors": "^3.1.1", - "express-rate-limit": "^6.7.0", - "express-validator": "^6.14.2", - "handlebars": "^4.7.7", - "helmet": "^5.1.1", - "infisical-node": "^1.2.1", - "js-yaml": "^4.1.0", - "jsonwebtoken": "^9.0.0", - "jsrp": "^0.2.4", - "libsodium-wrappers": "^0.7.10", - "lodash": "^4.17.21", - "mongoose": "^6.10.5", - "nanoid": "^3.3.6", - "node-cache": "^5.1.2", - "nodemailer": "^6.8.0", - "passport": "^0.6.0", - "passport-google-oauth20": "^2.0.0", - "posthog-node": "^2.6.0", - "query-string": "^7.1.3", - "rate-limit-mongo": "^2.3.2", - "rimraf": "^3.0.2", - "stripe": "^10.7.0", - "swagger-autogen": "^2.22.0", - "swagger-ui-express": "^4.6.2", - "tweetnacl": "^1.0.3", - "tweetnacl-util": "^0.15.1", - "typescript": "^4.9.3", - "utility-types": "^3.10.0", - "winston": "^3.8.2", - "winston-loki": "^6.0.6" - }, - "devDependencies": { - "@jest/globals": "^29.3.1", - "@posthog/plugin-scaffold": "^1.3.4", - "@types/bcrypt": "^5.0.0", - "@types/bcryptjs": "^2.4.2", - "@types/cookie-parser": "^1.4.3", - "@types/cors": "^2.8.12", - "@types/express": "^4.17.14", - "@types/jest": "^29.5.0", - "@types/jsonwebtoken": "^8.5.9", - "@types/lodash": "^4.14.191", - "@types/node": "^18.11.3", - "@types/nodemailer": "^6.4.6", - "@types/passport": "^1.0.12", - "@types/supertest": "^2.0.12", - "@types/swagger-jsdoc": "^6.0.1", - "@types/swagger-ui-express": "^4.1.3", - "@typescript-eslint/eslint-plugin": "^5.54.0", - "@typescript-eslint/parser": "^5.40.1", - "cross-env": "^7.0.3", - "eslint": "^8.26.0", - "install": "^0.13.0", - "jest": "^29.3.1", - "jest-junit": "^15.0.0", - "nodemon": "^2.0.19", - "npm": "^8.19.3", - "supertest": "^6.3.3", - "ts-jest": "^29.0.3", - "ts-node": "^10.9.1" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@aws-crypto/crc32": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-3.0.0.tgz", - "integrity": "sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==", - "dependencies": { - "@aws-crypto/util": "^3.0.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^1.11.1" - } - }, - "node_modules/@aws-crypto/crc32/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@aws-crypto/ie11-detection": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz", - "integrity": "sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==", - "dependencies": { - "tslib": "^1.11.1" - } - }, - "node_modules/@aws-crypto/ie11-detection/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@aws-crypto/sha256-browser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-3.0.0.tgz", - "integrity": "sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ==", - "dependencies": { - "@aws-crypto/ie11-detection": "^3.0.0", - "@aws-crypto/sha256-js": "^3.0.0", - "@aws-crypto/supports-web-crypto": "^3.0.0", - "@aws-crypto/util": "^3.0.0", - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-locate-window": "^3.0.0", - "@aws-sdk/util-utf8-browser": "^3.0.0", - "tslib": "^1.11.1" - } - }, - "node_modules/@aws-crypto/sha256-browser/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@aws-crypto/sha256-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-3.0.0.tgz", - "integrity": "sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==", - "dependencies": { - "@aws-crypto/util": "^3.0.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^1.11.1" - } - }, - "node_modules/@aws-crypto/sha256-js/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@aws-crypto/supports-web-crypto": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-3.0.0.tgz", - "integrity": "sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==", - "dependencies": { - "tslib": "^1.11.1" - } - }, - "node_modules/@aws-crypto/supports-web-crypto/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@aws-crypto/util": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-3.0.0.tgz", - "integrity": "sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==", - "dependencies": { - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-utf8-browser": "^3.0.0", - "tslib": "^1.11.1" - } - }, - "node_modules/@aws-crypto/util/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@aws-sdk/abort-controller": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.347.0.tgz", - "integrity": "sha512-P/2qE6ntYEmYG4Ez535nJWZbXqgbkJx8CMz7ChEuEg3Gp3dvVYEKg+iEUEvlqQ2U5dWP5J3ehw5po9t86IsVPQ==", - "dependencies": { - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/client-cognito-identity": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.347.0.tgz", - "integrity": "sha512-Z92GT2SC1y1r0bl3XI6ZH6QMsL2AaG3IR6ORXeiA94OY9/eF/tQT0zDbwn/MZUwJuBnR0CfO8bq7IQgCAguQ4A==", - "optional": true, - "dependencies": { - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.347.0", - "@aws-sdk/config-resolver": "3.347.0", - "@aws-sdk/credential-provider-node": "3.347.0", - "@aws-sdk/fetch-http-handler": "3.347.0", - "@aws-sdk/hash-node": "3.347.0", - "@aws-sdk/invalid-dependency": "3.347.0", - "@aws-sdk/middleware-content-length": "3.347.0", - "@aws-sdk/middleware-endpoint": "3.347.0", - "@aws-sdk/middleware-host-header": "3.347.0", - "@aws-sdk/middleware-logger": "3.347.0", - "@aws-sdk/middleware-recursion-detection": "3.347.0", - "@aws-sdk/middleware-retry": "3.347.0", - "@aws-sdk/middleware-serde": "3.347.0", - "@aws-sdk/middleware-signing": "3.347.0", - "@aws-sdk/middleware-stack": "3.347.0", - "@aws-sdk/middleware-user-agent": "3.347.0", - "@aws-sdk/node-config-provider": "3.347.0", - "@aws-sdk/node-http-handler": "3.347.0", - "@aws-sdk/smithy-client": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/url-parser": "3.347.0", - "@aws-sdk/util-base64": "3.310.0", - "@aws-sdk/util-body-length-browser": "3.310.0", - "@aws-sdk/util-body-length-node": "3.310.0", - "@aws-sdk/util-defaults-mode-browser": "3.347.0", - "@aws-sdk/util-defaults-mode-node": "3.347.0", - "@aws-sdk/util-endpoints": "3.347.0", - "@aws-sdk/util-retry": "3.347.0", - "@aws-sdk/util-user-agent-browser": "3.347.0", - "@aws-sdk/util-user-agent-node": "3.347.0", - "@aws-sdk/util-utf8": "3.310.0", - "@smithy/protocol-http": "^1.0.1", - "@smithy/types": "^1.0.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/client-secrets-manager": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.347.0.tgz", - "integrity": "sha512-lqBBJobdpVGx5OJpI3P52SaOilPkVW9zKVwPndoou8hpPYMMUVbVZ/Q0rSmjXC7wi9VzMB4SlENDM519Hu/tdQ==", - "dependencies": { - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.347.0", - "@aws-sdk/config-resolver": "3.347.0", - "@aws-sdk/credential-provider-node": "3.347.0", - "@aws-sdk/fetch-http-handler": "3.347.0", - "@aws-sdk/hash-node": "3.347.0", - "@aws-sdk/invalid-dependency": "3.347.0", - "@aws-sdk/middleware-content-length": "3.347.0", - "@aws-sdk/middleware-endpoint": "3.347.0", - "@aws-sdk/middleware-host-header": "3.347.0", - "@aws-sdk/middleware-logger": "3.347.0", - "@aws-sdk/middleware-recursion-detection": "3.347.0", - "@aws-sdk/middleware-retry": "3.347.0", - "@aws-sdk/middleware-serde": "3.347.0", - "@aws-sdk/middleware-signing": "3.347.0", - "@aws-sdk/middleware-stack": "3.347.0", - "@aws-sdk/middleware-user-agent": "3.347.0", - "@aws-sdk/node-config-provider": "3.347.0", - "@aws-sdk/node-http-handler": "3.347.0", - "@aws-sdk/smithy-client": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/url-parser": "3.347.0", - "@aws-sdk/util-base64": "3.310.0", - "@aws-sdk/util-body-length-browser": "3.310.0", - "@aws-sdk/util-body-length-node": "3.310.0", - "@aws-sdk/util-defaults-mode-browser": "3.347.0", - "@aws-sdk/util-defaults-mode-node": "3.347.0", - "@aws-sdk/util-endpoints": "3.347.0", - "@aws-sdk/util-retry": "3.347.0", - "@aws-sdk/util-user-agent-browser": "3.347.0", - "@aws-sdk/util-user-agent-node": "3.347.0", - "@aws-sdk/util-utf8": "3.310.0", - "@smithy/protocol-http": "^1.0.1", - "@smithy/types": "^1.0.0", - "tslib": "^2.5.0", - "uuid": "^8.3.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/client-sso": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.347.0.tgz", - "integrity": "sha512-AZehWCNLUXTrDavsZYRi7d84Uef20ppYJ2FY0KxqrKB3lx89mO29SfSJSC4woeW5+6ooBokq8HtKxw5ImPfRhA==", - "dependencies": { - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/config-resolver": "3.347.0", - "@aws-sdk/fetch-http-handler": "3.347.0", - "@aws-sdk/hash-node": "3.347.0", - "@aws-sdk/invalid-dependency": "3.347.0", - "@aws-sdk/middleware-content-length": "3.347.0", - "@aws-sdk/middleware-endpoint": "3.347.0", - "@aws-sdk/middleware-host-header": "3.347.0", - "@aws-sdk/middleware-logger": "3.347.0", - "@aws-sdk/middleware-recursion-detection": "3.347.0", - "@aws-sdk/middleware-retry": "3.347.0", - "@aws-sdk/middleware-serde": "3.347.0", - "@aws-sdk/middleware-stack": "3.347.0", - "@aws-sdk/middleware-user-agent": "3.347.0", - "@aws-sdk/node-config-provider": "3.347.0", - "@aws-sdk/node-http-handler": "3.347.0", - "@aws-sdk/smithy-client": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/url-parser": "3.347.0", - "@aws-sdk/util-base64": "3.310.0", - "@aws-sdk/util-body-length-browser": "3.310.0", - "@aws-sdk/util-body-length-node": "3.310.0", - "@aws-sdk/util-defaults-mode-browser": "3.347.0", - "@aws-sdk/util-defaults-mode-node": "3.347.0", - "@aws-sdk/util-endpoints": "3.347.0", - "@aws-sdk/util-retry": "3.347.0", - "@aws-sdk/util-user-agent-browser": "3.347.0", - "@aws-sdk/util-user-agent-node": "3.347.0", - "@aws-sdk/util-utf8": "3.310.0", - "@smithy/protocol-http": "^1.0.1", - "@smithy/types": "^1.0.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/client-sso-oidc": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.347.0.tgz", - "integrity": "sha512-IBxRfPqb8f9FqpmDbzcRDfoiasj/Y47C4Gj+j3kA5T1XWyGwbDI9QnPW/rnkZTWxLUUG1LSbBNwbPD6TLoff8A==", - "dependencies": { - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/config-resolver": "3.347.0", - "@aws-sdk/fetch-http-handler": "3.347.0", - "@aws-sdk/hash-node": "3.347.0", - "@aws-sdk/invalid-dependency": "3.347.0", - "@aws-sdk/middleware-content-length": "3.347.0", - "@aws-sdk/middleware-endpoint": "3.347.0", - "@aws-sdk/middleware-host-header": "3.347.0", - "@aws-sdk/middleware-logger": "3.347.0", - "@aws-sdk/middleware-recursion-detection": "3.347.0", - "@aws-sdk/middleware-retry": "3.347.0", - "@aws-sdk/middleware-serde": "3.347.0", - "@aws-sdk/middleware-stack": "3.347.0", - "@aws-sdk/middleware-user-agent": "3.347.0", - "@aws-sdk/node-config-provider": "3.347.0", - "@aws-sdk/node-http-handler": "3.347.0", - "@aws-sdk/smithy-client": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/url-parser": "3.347.0", - "@aws-sdk/util-base64": "3.310.0", - "@aws-sdk/util-body-length-browser": "3.310.0", - "@aws-sdk/util-body-length-node": "3.310.0", - "@aws-sdk/util-defaults-mode-browser": "3.347.0", - "@aws-sdk/util-defaults-mode-node": "3.347.0", - "@aws-sdk/util-endpoints": "3.347.0", - "@aws-sdk/util-retry": "3.347.0", - "@aws-sdk/util-user-agent-browser": "3.347.0", - "@aws-sdk/util-user-agent-node": "3.347.0", - "@aws-sdk/util-utf8": "3.310.0", - "@smithy/protocol-http": "^1.0.1", - "@smithy/types": "^1.0.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/client-sts": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.347.0.tgz", - "integrity": "sha512-QcJCUlzJZLAFTFSuELKd4BF5I5W38TR/m7NX2y1tn2la9JIrWSrz+tj598zfp2V4pJPzRJ1i8RglTZxSRIvsxQ==", - "dependencies": { - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/config-resolver": "3.347.0", - "@aws-sdk/credential-provider-node": "3.347.0", - "@aws-sdk/fetch-http-handler": "3.347.0", - "@aws-sdk/hash-node": "3.347.0", - "@aws-sdk/invalid-dependency": "3.347.0", - "@aws-sdk/middleware-content-length": "3.347.0", - "@aws-sdk/middleware-endpoint": "3.347.0", - "@aws-sdk/middleware-host-header": "3.347.0", - "@aws-sdk/middleware-logger": "3.347.0", - "@aws-sdk/middleware-recursion-detection": "3.347.0", - "@aws-sdk/middleware-retry": "3.347.0", - "@aws-sdk/middleware-sdk-sts": "3.347.0", - "@aws-sdk/middleware-serde": "3.347.0", - "@aws-sdk/middleware-signing": "3.347.0", - "@aws-sdk/middleware-stack": "3.347.0", - "@aws-sdk/middleware-user-agent": "3.347.0", - "@aws-sdk/node-config-provider": "3.347.0", - "@aws-sdk/node-http-handler": "3.347.0", - "@aws-sdk/smithy-client": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/url-parser": "3.347.0", - "@aws-sdk/util-base64": "3.310.0", - "@aws-sdk/util-body-length-browser": "3.310.0", - "@aws-sdk/util-body-length-node": "3.310.0", - "@aws-sdk/util-defaults-mode-browser": "3.347.0", - "@aws-sdk/util-defaults-mode-node": "3.347.0", - "@aws-sdk/util-endpoints": "3.347.0", - "@aws-sdk/util-retry": "3.347.0", - "@aws-sdk/util-user-agent-browser": "3.347.0", - "@aws-sdk/util-user-agent-node": "3.347.0", - "@aws-sdk/util-utf8": "3.310.0", - "@smithy/protocol-http": "^1.0.1", - "@smithy/types": "^1.0.0", - "fast-xml-parser": "4.1.2", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/config-resolver": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/config-resolver/-/config-resolver-3.347.0.tgz", - "integrity": "sha512-2ja+Sf/VnUO7IQ3nKbDQ5aumYKKJUaTm/BuVJ29wNho8wYHfuf7wHZV0pDTkB8RF5SH7IpHap7zpZAj39Iq+EA==", - "dependencies": { - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-config-provider": "3.310.0", - "@aws-sdk/util-middleware": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-cognito-identity": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.347.0.tgz", - "integrity": "sha512-7NiVVQC51HvomI44OyD+UekZ7qxauJeFGwQILbQ0beAxNuPZL7Ect/jB6A5MeleyqP+sVn8cB7qBMZjFJRhoJA==", - "optional": true, - "dependencies": { - "@aws-sdk/client-cognito-identity": "3.347.0", - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.347.0.tgz", - "integrity": "sha512-UnEM+LKGpXKzw/1WvYEQsC6Wj9PupYZdQOE+e2Dgy2dqk/pVFy4WueRtFXYDT2B41ppv3drdXUuKZRIDVqIgNQ==", - "dependencies": { - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-imds": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.347.0.tgz", - "integrity": "sha512-7scCy/DCDRLIhlqTxff97LQWDnRwRXji3bxxMg+xWOTTaJe7PWx+etGSbBWaL42vsBHFShQjSLvJryEgoBktpw==", - "dependencies": { - "@aws-sdk/node-config-provider": "3.347.0", - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/url-parser": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.347.0.tgz", - "integrity": "sha512-84TNF34ryabmVbILOq7f+/Jy8tJaskvHdax3X90qxFtXRU11kX0bf5NYL616KT0epR0VGpy50ThfIqvBwxeJfQ==", - "dependencies": { - "@aws-sdk/credential-provider-env": "3.347.0", - "@aws-sdk/credential-provider-imds": "3.347.0", - "@aws-sdk/credential-provider-process": "3.347.0", - "@aws-sdk/credential-provider-sso": "3.347.0", - "@aws-sdk/credential-provider-web-identity": "3.347.0", - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/shared-ini-file-loader": "3.347.0", - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.347.0.tgz", - "integrity": "sha512-ds2uxE0krl94RdQ7bstwafUXdlMeEOPgedhaheVVlj8kH+XqlZdwUUaUv1uoEI9iBzuSjKftUkIHo0xsTiwtaw==", - "dependencies": { - "@aws-sdk/credential-provider-env": "3.347.0", - "@aws-sdk/credential-provider-imds": "3.347.0", - "@aws-sdk/credential-provider-ini": "3.347.0", - "@aws-sdk/credential-provider-process": "3.347.0", - "@aws-sdk/credential-provider-sso": "3.347.0", - "@aws-sdk/credential-provider-web-identity": "3.347.0", - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/shared-ini-file-loader": "3.347.0", - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.347.0.tgz", - "integrity": "sha512-yl1z4MsaBdXd4GQ2halIvYds23S67kElyOwz7g8kaQ4kHj+UoYWxz3JVW/DGusM6XmQ9/F67utBrUVA0uhQYyw==", - "dependencies": { - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/shared-ini-file-loader": "3.347.0", - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.347.0.tgz", - "integrity": "sha512-M1d7EnUaJbSNCmNalEbINmtFkc9wJufx7UhKtEeFwSq9KEzOMroH1MEOeiqIw9f/zE8NI/iPkVeEhw123vmBrQ==", - "dependencies": { - "@aws-sdk/client-sso": "3.347.0", - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/shared-ini-file-loader": "3.347.0", - "@aws-sdk/token-providers": "3.347.0", - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.347.0.tgz", - "integrity": "sha512-DxoTlVK8lXjS1zVphtz/Ab+jkN/IZor9d6pP2GjJHNoAIIzXfRwwj5C8vr4eTayx/5VJ7GRP91J8GJ2cKly8Qw==", - "dependencies": { - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/credential-providers": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.347.0.tgz", - "integrity": "sha512-ny8tnuLToQIYbS+ztRh4/fViDDV1xk+WuapSK2T1MAIuPvhyD1IDulTyqv6P9ROoNIqt1NAoLctkWxdkLvqyQA==", - "optional": true, - "dependencies": { - "@aws-sdk/client-cognito-identity": "3.347.0", - "@aws-sdk/client-sso": "3.347.0", - "@aws-sdk/client-sts": "3.347.0", - "@aws-sdk/credential-provider-cognito-identity": "3.347.0", - "@aws-sdk/credential-provider-env": "3.347.0", - "@aws-sdk/credential-provider-imds": "3.347.0", - "@aws-sdk/credential-provider-ini": "3.347.0", - "@aws-sdk/credential-provider-node": "3.347.0", - "@aws-sdk/credential-provider-process": "3.347.0", - "@aws-sdk/credential-provider-sso": "3.347.0", - "@aws-sdk/credential-provider-web-identity": "3.347.0", - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/eventstream-codec": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-codec/-/eventstream-codec-3.347.0.tgz", - "integrity": "sha512-61q+SyspjsaQ4sdgjizMyRgVph2CiW4aAtfpoH69EJFJfTxTR/OqnZ9Jx/3YiYi0ksrvDenJddYodfWWJqD8/w==", - "dependencies": { - "@aws-crypto/crc32": "3.0.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-hex-encoding": "3.310.0", - "tslib": "^2.5.0" - } - }, - "node_modules/@aws-sdk/fetch-http-handler": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.347.0.tgz", - "integrity": "sha512-sQ5P7ivY8//7wdxfA76LT1sF6V2Tyyz1qF6xXf9sihPN5Q1Y65c+SKpMzXyFSPqWZ82+SQQuDliYZouVyS6kQQ==", - "dependencies": { - "@aws-sdk/protocol-http": "3.347.0", - "@aws-sdk/querystring-builder": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-base64": "3.310.0", - "tslib": "^2.5.0" - } - }, - "node_modules/@aws-sdk/hash-node": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/hash-node/-/hash-node-3.347.0.tgz", - "integrity": "sha512-96+ml/4EaUaVpzBdOLGOxdoXOjkPgkoJp/0i1fxOJEvl8wdAQSwc3IugVK9wZkCxy2DlENtgOe6DfIOhfffm/g==", - "dependencies": { - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-buffer-from": "3.310.0", - "@aws-sdk/util-utf8": "3.310.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/invalid-dependency": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/invalid-dependency/-/invalid-dependency-3.347.0.tgz", - "integrity": "sha512-8imQcwLwqZ/wTJXZqzXT9pGLIksTRckhGLZaXT60tiBOPKuerTsus2L59UstLs5LP8TKaVZKFFSsjRIn9dQdmQ==", - "dependencies": { - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - } - }, - "node_modules/@aws-sdk/is-array-buffer": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/is-array-buffer/-/is-array-buffer-3.310.0.tgz", - "integrity": "sha512-urnbcCR+h9NWUnmOtet/s4ghvzsidFmspfhYaHAmSRdy9yDjdjBJMFjjsn85A1ODUktztm+cVncXjQ38WCMjMQ==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/middleware-content-length": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-content-length/-/middleware-content-length-3.347.0.tgz", - "integrity": "sha512-i4qtWTDImMaDUtwKQPbaZpXsReiwiBomM1cWymCU4bhz81HL01oIxOxOBuiM+3NlDoCSPr3KI6txZSz/8cqXCQ==", - "dependencies": { - "@aws-sdk/protocol-http": "3.347.0", - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/middleware-endpoint": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint/-/middleware-endpoint-3.347.0.tgz", - "integrity": "sha512-unF0c6dMaUL1ffU+37Ugty43DgMnzPWXr/Jup/8GbK5fzzWT5NQq6dj9KHPubMbWeEjQbmczvhv25JuJdK8gNQ==", - "dependencies": { - "@aws-sdk/middleware-serde": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/url-parser": "3.347.0", - "@aws-sdk/util-middleware": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.347.0.tgz", - "integrity": "sha512-kpKmR9OvMlnReqp5sKcJkozbj1wmlblbVSbnQAIkzeQj2xD5dnVR3Nn2ogQKxSmU1Fv7dEroBtrruJ1o3fY38A==", - "dependencies": { - "@aws-sdk/protocol-http": "3.347.0", - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/middleware-logger": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.347.0.tgz", - "integrity": "sha512-NYC+Id5UCkVn+3P1t/YtmHt75uED06vwaKyxDy0UmB2K66PZLVtwWbLpVWrhbroaw1bvUHYcRyQ9NIfnVcXQjA==", - "dependencies": { - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.347.0.tgz", - "integrity": "sha512-qfnSvkFKCAMjMHR31NdsT0gv5Sq/ZHTUD4yQsSLpbVQ6iYAS834lrzXt41iyEHt57Y514uG7F/Xfvude3u4icQ==", - "dependencies": { - "@aws-sdk/protocol-http": "3.347.0", - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/middleware-retry": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-retry/-/middleware-retry-3.347.0.tgz", - "integrity": "sha512-CpdM+8dCSbX96agy4FCzOfzDmhNnGBM/pxrgIVLm5nkYTLuXp/d7ubpFEUHULr+4hCd5wakHotMt7yO29NFaVw==", - "dependencies": { - "@aws-sdk/protocol-http": "3.347.0", - "@aws-sdk/service-error-classification": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-middleware": "3.347.0", - "@aws-sdk/util-retry": "3.347.0", - "tslib": "^2.5.0", - "uuid": "^8.3.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/middleware-sdk-sts": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.347.0.tgz", - "integrity": "sha512-38LJ0bkIoVF3W97x6Jyyou72YV9Cfbml4OaDEdnrCOo0EssNZM5d7RhjMvQDwww7/3OBY/BzeOcZKfJlkYUXGw==", - "dependencies": { - "@aws-sdk/middleware-signing": "3.347.0", - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/middleware-serde": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-serde/-/middleware-serde-3.347.0.tgz", - "integrity": "sha512-x5Foi7jRbVJXDu9bHfyCbhYDH5pKK+31MmsSJ3k8rY8keXLBxm2XEEg/AIoV9/TUF9EeVvZ7F1/RmMpJnWQsEg==", - "dependencies": { - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/middleware-signing": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.347.0.tgz", - "integrity": "sha512-zVBF/4MGKnvhAE/J+oAL/VAehiyv+trs2dqSQXwHou9j8eA8Vm8HS2NdOwpkZQchIxTuwFlqSusDuPEdYFbvGw==", - "dependencies": { - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/protocol-http": "3.347.0", - "@aws-sdk/signature-v4": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-middleware": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/middleware-stack": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-stack/-/middleware-stack-3.347.0.tgz", - "integrity": "sha512-Izidg4rqtYMcKuvn2UzgEpPLSmyd8ub9+LQ2oIzG3mpIzCBITq7wp40jN1iNkMg+X6KEnX9vdMJIYZsPYMCYuQ==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.347.0.tgz", - "integrity": "sha512-wJbGN3OE1/daVCrwk49whhIr9E0j1N4gWwN/wi4WuyYIA+5lMUfVp0aGIOvZR+878DxuFz2hQ4XcZVT4K2WvQw==", - "dependencies": { - "@aws-sdk/protocol-http": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-endpoints": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/node-config-provider": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/node-config-provider/-/node-config-provider-3.347.0.tgz", - "integrity": "sha512-faU93d3+5uTTUcotGgMXF+sJVFjrKh+ufW+CzYKT4yUHammyaIab/IbTPWy2hIolcEGtuPeVoxXw8TXbkh/tuw==", - "dependencies": { - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/shared-ini-file-loader": "3.347.0", - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/node-http-handler": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/node-http-handler/-/node-http-handler-3.347.0.tgz", - "integrity": "sha512-eluPf3CeeEaPbETsPw7ee0Rb0FP79amu8vdLMrQmkrD+KP4owupUXOEI4drxWJgBSd+3PRowPWCDA8wUtraHKg==", - "dependencies": { - "@aws-sdk/abort-controller": "3.347.0", - "@aws-sdk/protocol-http": "3.347.0", - "@aws-sdk/querystring-builder": "3.347.0", - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/property-provider": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/property-provider/-/property-provider-3.347.0.tgz", - "integrity": "sha512-t3nJ8CYPLKAF2v9nIHOHOlF0CviQbTvbFc2L4a+A+EVd/rM4PzL3+3n8ZJsr0h7f6uD04+b5YRFgKgnaqLXlEg==", - "dependencies": { - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/protocol-http": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.347.0.tgz", - "integrity": "sha512-2YdBhc02Wvy03YjhGwUxF0UQgrPWEy8Iq75pfS42N+/0B/+eWX1aQgfjFxIpLg7YSjT5eKtYOQGlYd4MFTgj9g==", - "dependencies": { - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/querystring-builder": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.347.0.tgz", - "integrity": "sha512-phtKTe6FXoV02MoPkIVV6owXI8Mwr5IBN3bPoxhcPvJG2AjEmnetSIrhb8kwc4oNhlwfZwH6Jo5ARW/VEWbZtg==", - "dependencies": { - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-uri-escape": "3.310.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/querystring-parser": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-parser/-/querystring-parser-3.347.0.tgz", - "integrity": "sha512-5VXOhfZz78T2W7SuXf2avfjKglx1VZgZgp9Zfhrt/Rq+MTu2D+PZc5zmJHhYigD7x83jLSLogpuInQpFMA9LgA==", - "dependencies": { - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/service-error-classification": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/service-error-classification/-/service-error-classification-3.347.0.tgz", - "integrity": "sha512-xZ3MqSY81Oy2gh5g0fCtooAbahqh9VhsF8vcKjVX8+XPbGC8y+kej82+MsMg4gYL8gRFB9u4hgYbNgIS6JTAvg==", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/shared-ini-file-loader": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.347.0.tgz", - "integrity": "sha512-Xw+zAZQVLb+xMNHChXQ29tzzLqm3AEHsD8JJnlkeFjeMnWQtXdUfOARl5s8NzAppcKQNlVe2gPzjaKjoy2jz1Q==", - "dependencies": { - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/signature-v4": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4/-/signature-v4-3.347.0.tgz", - "integrity": "sha512-58Uq1do+VsTHYkP11dTK+DF53fguoNNJL9rHRWhzP+OcYv3/mBMLoS2WPz/x9FO5mBg4ESFsug0I6mXbd36tjw==", - "dependencies": { - "@aws-sdk/eventstream-codec": "3.347.0", - "@aws-sdk/is-array-buffer": "3.310.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-hex-encoding": "3.310.0", - "@aws-sdk/util-middleware": "3.347.0", - "@aws-sdk/util-uri-escape": "3.310.0", - "@aws-sdk/util-utf8": "3.310.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/smithy-client": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/smithy-client/-/smithy-client-3.347.0.tgz", - "integrity": "sha512-PaGTDsJLGK0sTjA6YdYQzILRlPRN3uVFyqeBUkfltXssvUzkm8z2t1lz2H4VyJLAhwnG5ZuZTNEV/2mcWrU7JQ==", - "dependencies": { - "@aws-sdk/middleware-stack": "3.347.0", - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/token-providers": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.347.0.tgz", - "integrity": "sha512-DZS9UWEy105zsaBJTgcvv1U+0jl7j1OzfMpnLf/lEYjEvx/4FqY2Ue/OZUACJorZgm/dWNqrhY17tZXtS/S3ew==", - "dependencies": { - "@aws-sdk/client-sso-oidc": "3.347.0", - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/shared-ini-file-loader": "3.347.0", - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/types": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.347.0.tgz", - "integrity": "sha512-GkCMy79mdjU9OTIe5KT58fI/6uqdf8UmMdWqVHmFJ+UpEzOci7L/uw4sOXWo7xpPzLs6cJ7s5ouGZW4GRPmHFA==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/url-parser": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/url-parser/-/url-parser-3.347.0.tgz", - "integrity": "sha512-lhrnVjxdV7hl+yCnJfDZOaVLSqKjxN20MIOiijRiqaWGLGEAiSqBreMhL89X1WKCifxAs4zZf9YB9SbdziRpAA==", - "dependencies": { - "@aws-sdk/querystring-parser": "3.347.0", - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - } - }, - "node_modules/@aws-sdk/util-base64": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64/-/util-base64-3.310.0.tgz", - "integrity": "sha512-v3+HBKQvqgdzcbL+pFswlx5HQsd9L6ZTlyPVL2LS9nNXnCcR3XgGz9jRskikRUuUvUXtkSG1J88GAOnJ/apTPg==", - "dependencies": { - "@aws-sdk/util-buffer-from": "3.310.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/util-body-length-browser": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-browser/-/util-body-length-browser-3.310.0.tgz", - "integrity": "sha512-sxsC3lPBGfpHtNTUoGXMQXLwjmR0zVpx0rSvzTPAuoVILVsp5AU/w5FphNPxD5OVIjNbZv9KsKTuvNTiZjDp9g==", - "dependencies": { - "tslib": "^2.5.0" - } - }, - "node_modules/@aws-sdk/util-body-length-node": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-node/-/util-body-length-node-3.310.0.tgz", - "integrity": "sha512-2tqGXdyKhyA6w4zz7UPoS8Ip+7sayOg9BwHNidiGm2ikbDxm1YrCfYXvCBdwaJxa4hJfRVz+aL9e+d3GqPI9pQ==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/util-buffer-from": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-buffer-from/-/util-buffer-from-3.310.0.tgz", - "integrity": "sha512-i6LVeXFtGih5Zs8enLrt+ExXY92QV25jtEnTKHsmlFqFAuL3VBeod6boeMXkN2p9lbSVVQ1sAOOYZOHYbYkntw==", - "dependencies": { - "@aws-sdk/is-array-buffer": "3.310.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/util-config-provider": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-config-provider/-/util-config-provider-3.310.0.tgz", - "integrity": "sha512-xIBaYo8dwiojCw8vnUcIL4Z5tyfb1v3yjqyJKJWV/dqKUFOOS0U591plmXbM+M/QkXyML3ypon1f8+BoaDExrg==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/util-defaults-mode-browser": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-browser/-/util-defaults-mode-browser-3.347.0.tgz", - "integrity": "sha512-+JHFA4reWnW/nMWwrLKqL2Lm/biw/Dzi/Ix54DAkRZ08C462jMKVnUlzAI+TfxQE3YLm99EIa0G7jiEA+p81Qw==", - "dependencies": { - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/types": "3.347.0", - "bowser": "^2.11.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@aws-sdk/util-defaults-mode-node": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-node/-/util-defaults-mode-node-3.347.0.tgz", - "integrity": "sha512-A8BzIVhAAZE5WEukoAN2kYebzTc99ZgncbwOmgCCbvdaYlk5tzguR/s+uoT4G0JgQGol/4hAMuJEl7elNgU6RQ==", - "dependencies": { - "@aws-sdk/config-resolver": "3.347.0", - "@aws-sdk/credential-provider-imds": "3.347.0", - "@aws-sdk/node-config-provider": "3.347.0", - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@aws-sdk/util-endpoints": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.347.0.tgz", - "integrity": "sha512-/WUkirizeNAqwVj0zkcrqdQ9pUm1HY5kU+qy7xTR0OebkuJauglkmSTMD+56L1JPunWqHhlwCMVRaz5eaJdSEQ==", - "dependencies": { - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/util-hex-encoding": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.310.0.tgz", - "integrity": "sha512-sVN7mcCCDSJ67pI1ZMtk84SKGqyix6/0A1Ab163YKn+lFBQRMKexleZzpYzNGxYzmQS6VanP/cfU7NiLQOaSfA==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/util-locate-window": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.310.0.tgz", - "integrity": "sha512-qo2t/vBTnoXpjKxlsC2e1gBrRm80M3bId27r0BRB2VniSSe7bL1mmzM+/HFtujm0iAxtPM+aLEflLJlJeDPg0w==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/util-middleware": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-middleware/-/util-middleware-3.347.0.tgz", - "integrity": "sha512-8owqUA3ePufeYTUvlzdJ7Z0miLorTwx+rNol5lourGQZ9JXsVMo23+yGA7nOlFuXSGkoKpMOtn6S0BT2bcfeiw==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/util-retry": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-retry/-/util-retry-3.347.0.tgz", - "integrity": "sha512-NxnQA0/FHFxriQAeEgBonA43Q9/VPFQa8cfJDuT2A1YZruMasgjcltoZszi1dvoIRWSZsFTW42eY2gdOd0nffQ==", - "dependencies": { - "@aws-sdk/service-error-classification": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@aws-sdk/util-uri-escape": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-uri-escape/-/util-uri-escape-3.310.0.tgz", - "integrity": "sha512-drzt+aB2qo2LgtDoiy/3sVG8w63cgLkqFIa2NFlGpUgHFWTXkqtbgf4L5QdjRGKWhmZsnqkbtL7vkSWEcYDJ4Q==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.347.0.tgz", - "integrity": "sha512-ydxtsKVtQefgbk1Dku1q7pMkjDYThauG9/8mQkZUAVik55OUZw71Zzr3XO8J8RKvQG8lmhPXuAQ0FKAyycc0RA==", - "dependencies": { - "@aws-sdk/types": "3.347.0", - "bowser": "^2.11.0", - "tslib": "^2.5.0" - } - }, - "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.347.0.tgz", - "integrity": "sha512-6X0b9qGsbD1s80PmbaB6v1/ZtLfSx6fjRX8caM7NN0y/ObuLoX8LhYnW6WlB2f1+xb4EjaCNgpP/zCf98MXosw==", - "dependencies": { - "@aws-sdk/node-config-provider": "3.347.0", - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "aws-crt": ">=1.0.0" - }, - "peerDependenciesMeta": { - "aws-crt": { - "optional": true - } - } - }, - "node_modules/@aws-sdk/util-utf8": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8/-/util-utf8-3.310.0.tgz", - "integrity": "sha512-DnLfFT8uCO22uOJc0pt0DsSNau1GTisngBCDw8jQuWT5CqogMJu4b/uXmwEqfj8B3GX6Xsz8zOd6JpRlPftQoA==", - "dependencies": { - "@aws-sdk/util-buffer-from": "3.310.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/util-utf8-browser": { - "version": "3.259.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", - "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", - "dependencies": { - "tslib": "^2.3.1" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", - "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.22.3", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.3.tgz", - "integrity": "sha512-aNtko9OPOwVESUFp3MZfD8Uzxl7JzSeJpd7npIoxCasU37PFbAQRpKglkaKwlHOyeJdrREpo8TW8ldrkYWwvIQ==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.22.1", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.1.tgz", - "integrity": "sha512-Hkqu7J4ynysSXxmAahpN1jjRwVJ+NdpraFLIWflgjpVob3KNyK3/tIUc7Q7szed8WMp0JNa7Qtd1E9Oo22F9gA==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.22.0", - "@babel/helper-compilation-targets": "^7.22.1", - "@babel/helper-module-transforms": "^7.22.1", - "@babel/helpers": "^7.22.0", - "@babel/parser": "^7.22.0", - "@babel/template": "^7.21.9", - "@babel/traverse": "^7.22.1", - "@babel/types": "^7.22.0", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.22.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.3.tgz", - "integrity": "sha512-C17MW4wlk//ES/CJDL51kPNwl+qiBQyN7b9SKyVp11BLGFeSPoVaHrv+MNt8jwQFhQWowW88z1eeBx3pFz9v8A==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.3", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.1", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.1.tgz", - "integrity": "sha512-Rqx13UM3yVB5q0D/KwQ8+SPfX/+Rnsy1Lw1k/UwOC4KC6qrzIQoY3lYnBu5EHKBlEHHcj0M0W8ltPSkD8rqfsQ==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.22.0", - "@babel/helper-validator-option": "^7.21.0", - "browserslist": "^4.21.3", - "lru-cache": "^5.1.1", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.1", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.1.tgz", - "integrity": "sha512-Z2tgopurB/kTbidvzeBrc2To3PUP/9i5MUe+fU6QJCQDyPwSH2oRapkLw3KGECDYSjhQZCNxEvNvZlLw8JjGwA==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", - "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", - "dev": true, - "dependencies": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", - "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.21.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.22.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.1.tgz", - "integrity": "sha512-dxAe9E7ySDGbQdCVOY/4+UcD8M9ZFqZcZhSPsPacvCG4M+9lwtDDQfI2EoaSvmf7W/8yCBkGU0m7Pvt1ru3UZw==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.1", - "@babel/helper-module-imports": "^7.21.4", - "@babel/helper-simple-access": "^7.21.5", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.21.9", - "@babel/traverse": "^7.22.1", - "@babel/types": "^7.22.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.21.5.tgz", - "integrity": "sha512-0WDaIlXKOX/3KfBK/dwP1oQGiPh6rjMkT7HIRv7i5RR2VUMwrx5ZL0dwBkKx7+SW1zwNdgjHd34IMk5ZjTeHVg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.21.5.tgz", - "integrity": "sha512-ENPDAMC1wAjR0uaCUwliBdiSl1KBJAVnMTzXqi64c2MG8MPR6ii4qf7bSXDqSFbr4W6W028/rf5ivoHop5/mkg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.21.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz", - "integrity": "sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", - "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.22.3", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.3.tgz", - "integrity": "sha512-jBJ7jWblbgr7r6wYZHMdIqKc73ycaTcCaWRq4/2LpuPHcx7xMlZvpGQkOYc9HeSjn6rcx15CPlgVcBtZ4WZJ2w==", - "dev": true, - "dependencies": { - "@babel/template": "^7.21.9", - "@babel/traverse": "^7.22.1", - "@babel/types": "^7.22.3" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.22.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.3.tgz", - "integrity": "sha512-vrukxyW/ep8UD1UDzOYpTKQ6abgjFoeG6L+4ar9+c5TN9QnlqiOi6QK7LSR5ewm/ERyGkT/Ai6VboNrxhbr9Uw==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz", - "integrity": "sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.21.4.tgz", - "integrity": "sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.22.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.3.tgz", - "integrity": "sha512-XsDuspWKLUsxwCp6r7EhsExHtYfbe5oAGQ19kqngTdCPUoPQzOPdUbD/pB9PJiwb2ptYKQDjSJT3R6dC+EPqfQ==", - "dependencies": { - "regenerator-runtime": "^0.13.11" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.21.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.21.9.tgz", - "integrity": "sha512-MK0X5k8NKOuWRamiEfc3KEJiHMTkGZNUjzMipqCGDDc6ijRl/B7RGSKVGncu4Ro/HdyzzY6cmoXuKI2Gffk7vQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.21.4", - "@babel/parser": "^7.21.9", - "@babel/types": "^7.21.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.22.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.1.tgz", - "integrity": "sha512-lAWkdCoUFnmwLBhIRLciFntGYsIIoC6vIbN8zrLPqBnJmPu7Z6nzqnKd7FsxQUNAvZfVZ0x6KdNvNp8zWIOHSQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.22.0", - "@babel/helper-environment-visitor": "^7.22.1", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.22.0", - "@babel/types": "^7.22.0", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/types": { - "version": "7.22.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.3.tgz", - "integrity": "sha512-P3na3xIQHTKY4L0YOG7pM8M8uoUIB910WQaSiiMCZUC2Cy8XFEQONGABFnHWBa2gpGKODTAJcNhi5Zk0sLRrzg==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.21.5", - "@babel/helper-validator-identifier": "^7.19.1", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@dabh/diagnostics": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", - "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", - "dependencies": { - "colorspace": "1.1.x", - "enabled": "2.0.x", - "kuler": "^2.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", - "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", - "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.5.2", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.41.0.tgz", - "integrity": "sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@godaddy/terminus": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@godaddy/terminus/-/terminus-4.12.0.tgz", - "integrity": "sha512-zbl6gKxPAnAoAAGCyRN1kOMHTXgiW3C09w8McLKZWSSHQlsiRZlMZzBwSv1aK9PaRU25w80cnOlt3ow+uQwR1Q==", - "dependencies": { - "stoppable": "^1.1.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.5.0.tgz", - "integrity": "sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ==", - "dev": true, - "dependencies": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/core": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.5.0.tgz", - "integrity": "sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ==", - "dev": true, - "dependencies": { - "@jest/console": "^29.5.0", - "@jest/reporters": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.5.0", - "jest-config": "^29.5.0", - "jest-haste-map": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-resolve-dependencies": "^29.5.0", - "jest-runner": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "jest-watcher": "^29.5.0", - "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/environment": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.5.0.tgz", - "integrity": "sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ==", - "dev": true, - "dependencies": { - "@jest/fake-timers": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "jest-mock": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/expect": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.5.0.tgz", - "integrity": "sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g==", - "dev": true, - "dependencies": { - "expect": "^29.5.0", - "jest-snapshot": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/expect-utils": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.5.0.tgz", - "integrity": "sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg==", - "dev": true, - "dependencies": { - "jest-get-type": "^29.4.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/fake-timers": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.5.0.tgz", - "integrity": "sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg==", - "dev": true, - "dependencies": { - "@jest/types": "^29.5.0", - "@sinonjs/fake-timers": "^10.0.2", - "@types/node": "*", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", - "jest-util": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/globals": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.5.0.tgz", - "integrity": "sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/expect": "^29.5.0", - "@jest/types": "^29.5.0", - "jest-mock": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/reporters": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.5.0.tgz", - "integrity": "sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA==", - "dev": true, - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@jridgewell/trace-mapping": "^0.3.15", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "jest-worker": "^29.5.0", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "v8-to-istanbul": "^9.0.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/schemas": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", - "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", - "dev": true, - "dependencies": { - "@sinclair/typebox": "^0.25.16" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/source-map": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.3.tgz", - "integrity": "sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.15", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/test-result": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.5.0.tgz", - "integrity": "sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ==", - "dev": true, - "dependencies": { - "@jest/console": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/test-sequencer": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.5.0.tgz", - "integrity": "sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ==", - "dev": true, - "dependencies": { - "@jest/test-result": "^29.5.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/transform": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.5.0.tgz", - "integrity": "sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==", - "dev": true, - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.5.0", - "@jridgewell/trace-mapping": "^0.3.15", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/types": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", - "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.4.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - } - }, - "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, - "node_modules/@juanelas/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@juanelas/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-mr2pfRQpWap0Uq4tlrCgp3W+Yjx1/Bpq4QJsYeAQUh1mExgyQvXz7xUhmYT2HcLLspuAL5dpnos8P2QhaCSXsQ==" - }, - "node_modules/@mapbox/node-pre-gyp": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz", - "integrity": "sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==", - "dependencies": { - "detect-libc": "^2.0.0", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.7", - "nopt": "^5.0.0", - "npmlog": "^5.0.1", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.11" - }, - "bin": { - "node-pre-gyp": "bin/node-pre-gyp" - } - }, - "node_modules/@maxmind/geoip2-node": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@maxmind/geoip2-node/-/geoip2-node-3.5.0.tgz", - "integrity": "sha512-WG2TNxMwDWDOrljLwyZf5bwiEYubaHuICvQRlgz74lE9OZA/z4o+ZT6OisjDBAZh/yRJVNK6mfHqmP5lLlAwsA==", - "dev": true, - "dependencies": { - "camelcase-keys": "^7.0.0", - "ip6addr": "^0.2.5", - "maxmind": "^4.2.0" - } - }, - "node_modules/@napi-rs/snappy-android-arm-eabi": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-android-arm-eabi/-/snappy-android-arm-eabi-7.1.1.tgz", - "integrity": "sha512-NKd/ztuVEgQaAaNVQ5zZaCB9VV+7+uBXBHqhaE5iSapQhLc41szTlT0s68FCee75OoT3vhqdA6Jp5TrzZ2WOaw==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/snappy-android-arm64": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-android-arm64/-/snappy-android-arm64-7.1.1.tgz", - "integrity": "sha512-DktruMAO0K0toTnxNHg2GWNIAPJqdvIchCsdsRaKyuEnG101qBg0mYiRCAhxHgbT6RJlOGbUPKkbA9KKRhEJUg==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/snappy-darwin-arm64": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-darwin-arm64/-/snappy-darwin-arm64-7.1.1.tgz", - "integrity": "sha512-3LZyoAw3Qa5F7sCCTkSkhmGlydwUKU6L3Jl46eKHO2Ctm8Gcjxww6T7MfwlwGZ6JqAM6d1d++WLzUZPCGXVmag==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/snappy-darwin-x64": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-darwin-x64/-/snappy-darwin-x64-7.1.1.tgz", - "integrity": "sha512-X1D2F67bQkPwr5iSR29/RnOrLwAkB55YO6t41toABzla3mflLDpzZcakz6FokIukykf7ey31/t73v/4pbgaBkg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/snappy-freebsd-x64": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-freebsd-x64/-/snappy-freebsd-x64-7.1.1.tgz", - "integrity": "sha512-vSeuf+An8jFVHPAn5IbWE9hTGU9PFAaZLj/X7rKTQQtZstnDsHgWe6u4g7FHLuOdwQ8TvhcxAEpNlYIXIk4AJg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/snappy-linux-arm-gnueabihf": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-arm-gnueabihf/-/snappy-linux-arm-gnueabihf-7.1.1.tgz", - "integrity": "sha512-/yyN6QsnOs3D1+jI3SfRX+gtnD86rbixdfmgxv9g40+FrDaDTLAu/3VuZIqH02qqq/xiWbDnkO+42RGxXDzTCw==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/snappy-linux-arm64-gnu": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-arm64-gnu/-/snappy-linux-arm64-gnu-7.1.1.tgz", - "integrity": "sha512-StEeUCSwUoajgrBtiCQPTkHu+0Q4QlYndghGZNdbN1zJ1ny70YzPpevaFBUyjI/eJ+FN9uICKtwTPtQNSILS5g==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/snappy-linux-arm64-musl": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-arm64-musl/-/snappy-linux-arm64-musl-7.1.1.tgz", - "integrity": "sha512-jWEBRzj+lswZVYf0b5eY0fjMlBL9L9yqjmTuv2UIMjJNHPuR282LK/s3Fm9sYIXQtKkiCo5JyhmIcoghZ3v0Eg==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/snappy-linux-x64-gnu": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-x64-gnu/-/snappy-linux-x64-gnu-7.1.1.tgz", - "integrity": "sha512-41DPoAUFAU9VNrj/96qKfStH2Xq88ZYIsSz8BlITDm2ScoeDGOGbmaWguCXU7I+bC2uKWTmUVMXKqk6tVY6LEg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/snappy-linux-x64-musl": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-x64-musl/-/snappy-linux-x64-musl-7.1.1.tgz", - "integrity": "sha512-xR4hzFQqVq6J8Zf6XyUVtFJBaRgDyAQYUoBsCr92tZ7gI/0RlWCV6Q6JMO/wP5CSsvyFJIAtSUXXqlzIpw0GPA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/snappy-win32-arm64-msvc": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-win32-arm64-msvc/-/snappy-win32-arm64-msvc-7.1.1.tgz", - "integrity": "sha512-2mHPadctsaYtrfSV5Na8ooTdI5rflPxP1pceY4us6vbjeWrfgB+KQCuEFOHsGXqFNfsi6L9nWH8nB9swnxnSyw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/snappy-win32-ia32-msvc": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-win32-ia32-msvc/-/snappy-win32-ia32-msvc-7.1.1.tgz", - "integrity": "sha512-FOMgs9W71hdgjyl3T9F7b/WEIuoryfgBqsyhtHjAaa/98R0BUHl0bOoHg8ka0b5GgnhLBHkX2Yd6VD+Si9Q2ww==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/snappy-win32-x64-msvc": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-win32-x64-msvc/-/snappy-win32-x64-msvc-7.1.1.tgz", - "integrity": "sha512-Mu3yELySvzhBcNTVCq+hYxVh+lH3/KjoQ5HIEb3DDPoX0AGRTm3XZa+usq8pFWjl91Cgp9nWK+9lVSkCCIRaKA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@octokit/auth-token": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.3.tgz", - "integrity": "sha512-/aFM2M4HVDBT/jjDBa84sJniv1t9Gm/rLkalaz9htOm+L+8JMj1k9w0CkUdcxNyNxZPlTxKPVko+m1VlM58ZVA==", - "dependencies": { - "@octokit/types": "^9.0.0" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@octokit/core": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.1.tgz", - "integrity": "sha512-tEDxFx8E38zF3gT7sSMDrT1tGumDgsw5yPG6BBh/X+5ClIQfMH/Yqocxz1PnHx6CHyF6pxmovUTOfZAUvQ0Lvw==", - "dependencies": { - "@octokit/auth-token": "^3.0.0", - "@octokit/graphql": "^5.0.0", - "@octokit/request": "^6.0.0", - "@octokit/request-error": "^3.0.0", - "@octokit/types": "^9.0.0", - "before-after-hook": "^2.2.0", - "universal-user-agent": "^6.0.0" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@octokit/endpoint": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.5.tgz", - "integrity": "sha512-LG4o4HMY1Xoaec87IqQ41TQ+glvIeTKqfjkCEmt5AIwDZJwQeVZFIEYXrYY6yLwK+pAScb9Gj4q+Nz2qSw1roA==", - "dependencies": { - "@octokit/types": "^9.0.0", - "is-plain-object": "^5.0.0", - "universal-user-agent": "^6.0.0" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@octokit/graphql": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz", - "integrity": "sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==", - "dependencies": { - "@octokit/request": "^6.0.0", - "@octokit/types": "^9.0.0", - "universal-user-agent": "^6.0.0" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@octokit/openapi-types": { - "version": "17.2.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-17.2.0.tgz", - "integrity": "sha512-MazrFNx4plbLsGl+LFesMo96eIXkFgEtaKbnNpdh4aQ0VM10aoylFsTYP1AEjkeoRNZiiPe3T6Gl2Hr8dJWdlQ==" - }, - "node_modules/@octokit/plugin-paginate-rest": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz", - "integrity": "sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==", - "dependencies": { - "@octokit/tsconfig": "^1.0.2", - "@octokit/types": "^9.2.3" - }, - "engines": { - "node": ">= 14" - }, - "peerDependencies": { - "@octokit/core": ">=4" - } - }, - "node_modules/@octokit/plugin-request-log": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", - "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", - "peerDependencies": { - "@octokit/core": ">=3" - } - }, - "node_modules/@octokit/plugin-rest-endpoint-methods": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.1.2.tgz", - "integrity": "sha512-R0oJ7j6f/AdqPLtB9qRXLO+wjI9pctUn8Ka8UGfGaFCcCv3Otx14CshQ89K4E88pmyYZS8p0rNTiprML/81jig==", - "dependencies": { - "@octokit/types": "^9.2.3", - "deprecation": "^2.3.1" - }, - "engines": { - "node": ">= 14" - }, - "peerDependencies": { - "@octokit/core": ">=3" - } - }, - "node_modules/@octokit/request": { - "version": "6.2.5", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.5.tgz", - "integrity": "sha512-z83E8UIlPNaJUsXpjD8E0V5o/5f+vJJNbNcBwVZsX3/vC650U41cOkTLjq4PKk9BYonQGOnx7N17gvLyNjgGcQ==", - "dependencies": { - "@octokit/endpoint": "^7.0.0", - "@octokit/request-error": "^3.0.0", - "@octokit/types": "^9.0.0", - "is-plain-object": "^5.0.0", - "node-fetch": "^2.6.7", - "universal-user-agent": "^6.0.0" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@octokit/request-error": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz", - "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==", - "dependencies": { - "@octokit/types": "^9.0.0", - "deprecation": "^2.0.0", - "once": "^1.4.0" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@octokit/rest": { - "version": "19.0.11", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.11.tgz", - "integrity": "sha512-m2a9VhaP5/tUw8FwfnW2ICXlXpLPIqxtg3XcAiGMLj/Xhw3RSBfZ8le/466ktO1Gcjr8oXudGnHhxV1TXJgFxw==", - "dependencies": { - "@octokit/core": "^4.2.1", - "@octokit/plugin-paginate-rest": "^6.1.2", - "@octokit/plugin-request-log": "^1.0.4", - "@octokit/plugin-rest-endpoint-methods": "^7.1.2" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@octokit/tsconfig": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@octokit/tsconfig/-/tsconfig-1.0.2.tgz", - "integrity": "sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA==" - }, - "node_modules/@octokit/types": { - "version": "9.2.3", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.2.3.tgz", - "integrity": "sha512-MMeLdHyFIALioycq+LFcA71v0S2xpQUX2cw6pPbHQjaibcHYwLnmK/kMZaWuGfGfjBJZ3wRUq+dOaWsvrPJVvA==", - "dependencies": { - "@octokit/openapi-types": "^17.2.0" - } - }, - "node_modules/@phc/format": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@phc/format/-/format-1.0.0.tgz", - "integrity": "sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/@posthog/plugin-scaffold": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@posthog/plugin-scaffold/-/plugin-scaffold-1.4.2.tgz", - "integrity": "sha512-/VsRg3CfhQvYhxM2O9+gBOzj4K1QJZClY+yple0npL1Jd2nRn2nT4z7dlPSidTPZvdpFs0+hrnF+m4Kxf1NFvQ==", - "dev": true, - "dependencies": { - "@maxmind/geoip2-node": "^3.4.0" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" - }, - "node_modules/@sentry-internal/tracing": { - "version": "7.53.1", - "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.53.1.tgz", - "integrity": "sha512-a4H4rvVdz0XDGgNfRqc7zg6rMt2P1P05xBmgfIfztYy94Vciw1QMdboNiT7einr8ra8wogdEaK4Pe2AzYAPBJQ==", - "dependencies": { - "@sentry/core": "7.53.1", - "@sentry/types": "7.53.1", - "@sentry/utils": "7.53.1", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry-internal/tracing/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@sentry/core": { - "version": "7.53.1", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.53.1.tgz", - "integrity": "sha512-DAH8IJNORJJ7kQLqsZuhMkN6cwJjXzFuuUoZor7IIDHIHjtl51W+2F3Stg3+I3ZoKDfJfUNKqhipk2WZjG0FBg==", - "dependencies": { - "@sentry/types": "7.53.1", - "@sentry/utils": "7.53.1", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/core/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@sentry/node": { - "version": "7.53.1", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.53.1.tgz", - "integrity": "sha512-B4ax8sRd54xj4ad+4eY2EOKNt0Mh1NjuLW1zUKS8HW3h0bmuaDFzGuhEVvEY5H4SaV6tZKj1c0dvnMnyUbYkhA==", - "dependencies": { - "@sentry-internal/tracing": "7.53.1", - "@sentry/core": "7.53.1", - "@sentry/types": "7.53.1", - "@sentry/utils": "7.53.1", - "cookie": "^0.4.1", - "https-proxy-agent": "^5.0.0", - "lru_map": "^0.3.3", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/node/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@sentry/tracing": { - "version": "7.53.1", - "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-7.53.1.tgz", - "integrity": "sha512-1lpys/e19ee2gDTkcgIXyFNJySEqxdIxlu3Q1Oj+V0ORXVBfA9kFap2fHPWASaDJvmy1zpgGKlbzCpr+IEyfYQ==", - "dependencies": { - "@sentry-internal/tracing": "7.53.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/types": { - "version": "7.53.1", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.53.1.tgz", - "integrity": "sha512-/ijchRIu+jz3+j/zY+7KRPfLSCY14fTx5xujjbOdmEKjmIHQmwPBdszcQm40uwofrR8taV4hbt5MFN+WnjCkCw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/utils": { - "version": "7.53.1", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.53.1.tgz", - "integrity": "sha512-DKJA1LSUOEv4KOR828MzVuLh+drjeAgzyKgN063OEKmnirgjgRgNNS8wUgwpG0Tn2k6ANZGCwrdfzPeSBxshKg==", - "dependencies": { - "@sentry/types": "7.53.1", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/utils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@sinclair/typebox": { - "version": "0.25.24", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", - "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", - "dev": true - }, - "node_modules/@sinonjs/commons": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", - "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.2.0.tgz", - "integrity": "sha512-OPwQlEdg40HAj5KNF8WW6q2KG4Z+cBCZb3m4ninfTZKaBmbIJodviQsDBoYMPHkOyJJMHnOJo5j2+LKDOhOACg==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^3.0.0" - } - }, - "node_modules/@smithy/protocol-http": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-1.0.1.tgz", - "integrity": "sha512-9OrEn0WfOVtBNYJUjUAn9AOiJ4lzERCJJ/JeZs8E6yajTGxBaFRxUnNBHiNqoDJVg076hY36UmEnPx7xXrvUSg==", - "dependencies": { - "@smithy/types": "^1.0.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/types": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-1.0.0.tgz", - "integrity": "sha512-kc1m5wPBHQCTixwuaOh9vnak/iJm21DrSf9UK6yDE5S3mQQ4u11pqAUiKWnlrZnYkeLfAI9UEHj9OaMT1v5Umg==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": 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 - }, - "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 - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true - }, - "node_modules/@types/babel__core": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.1.tgz", - "integrity": "sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.0.tgz", - "integrity": "sha512-TBOjqAGf0hmaqRwpii5LLkJLg7c6OMm4nHLmpsUxwk9bBHtoTC6dAHdVWdGv4TBxj2CZOZY8Xfq8WmfoVi7n4Q==", - "dev": true, - "dependencies": { - "@babel/types": "^7.20.7" - } - }, - "node_modules/@types/bcrypt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.0.tgz", - "integrity": "sha512-agtcFKaruL8TmcvqbndlqHPSJgsolhf/qPWchFlgnW1gECTN/nKbFcoFnvKAQRFfKbh+BO6A3SWdJu9t+xF3Lw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/bcryptjs": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.2.tgz", - "integrity": "sha512-LiMQ6EOPob/4yUL66SZzu6Yh77cbzJFYll+ZfaPiPPFswtIlA/Fs1MzdKYA7JApHU49zQTbJGX3PDmCpIdDBRQ==", - "dev": true - }, - "node_modules/@types/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", - "dev": true, - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/cookie-parser": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.3.tgz", - "integrity": "sha512-CqSKwFwefj4PzZ5n/iwad/bow2hTCh0FlNAeWLtQM3JA/NX/iYagIpWG2cf1bQKQ2c9gU2log5VUCrn7LDOs0w==", - "dev": true, - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@types/cookiejar": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.2.tgz", - "integrity": "sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==", - "dev": true - }, - "node_modules/@types/cors": { - "version": "2.8.13", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", - "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/crypto-js": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.1.1.tgz", - "integrity": "sha512-BG7fQKZ689HIoc5h+6D2Dgq1fABRa0RbBWKBd9SP/MVRVXROflpm5fhwyATX5duFmbStzyzyycPB8qUYKDH3NA==" - }, - "node_modules/@types/express": { - "version": "4.17.17", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", - "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", - "dev": true, - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.35", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz", - "integrity": "sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==", - "dev": true, - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", - "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", - "dev": true - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "29.5.1", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.1.tgz", - "integrity": "sha512-tEuVcHrpaixS36w7hpsfLBLpjtMRJUE09/MHXn923LOVojDwyC14cWcfc0rDs0VEfUyYmt/+iX1kxxp+gZMcaQ==", - "dev": true, - "dependencies": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", - "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", - "dev": true - }, - "node_modules/@types/jsonwebtoken": { - "version": "8.5.9", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.9.tgz", - "integrity": "sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/libsodium-wrappers": { - "version": "0.7.10", - "resolved": "https://registry.npmjs.org/@types/libsodium-wrappers/-/libsodium-wrappers-0.7.10.tgz", - "integrity": "sha512-BqI9B92u+cM3ccp8mpHf+HzJ8fBlRwdmyd6+fz3p99m3V6ifT5O3zmOMi612PGkpeFeG/G6loxUnzlDNhfjPSA==" - }, - "node_modules/@types/lodash": { - "version": "4.14.195", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.195.tgz", - "integrity": "sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg==", - "dev": true - }, - "node_modules/@types/long": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" - }, - "node_modules/@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", - "dev": true - }, - "node_modules/@types/node": { - "version": "18.16.16", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.16.tgz", - "integrity": "sha512-NpaM49IGQQAUlBhHMF82QH80J08os4ZmyF9MkpCzWAGuOHqE4gTEbhzd7L3l5LmWuZ6E0OiC1FweQ4tsiW35+g==" - }, - "node_modules/@types/nodemailer": { - "version": "6.4.8", - "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.8.tgz", - "integrity": "sha512-oVsJSCkqViCn8/pEu2hfjwVO+Gb3e+eTWjg3PcjeFKRItfKpKwHphQqbYmPQrlMk+op7pNNWPbsJIEthpFN/OQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/passport": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.12.tgz", - "integrity": "sha512-QFdJ2TiAEoXfEQSNDISJR1Tm51I78CymqcBa8imbjo6dNNu+l2huDxxbDEIoFIwOSKMkOfHEikyDuZ38WwWsmw==", - "dev": true, - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@types/prettier": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", - "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", - "dev": true - }, - "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", - "dev": true - }, - "node_modules/@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", - "dev": true - }, - "node_modules/@types/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", - "dev": true - }, - "node_modules/@types/send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", - "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==", - "dev": true, - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz", - "integrity": "sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==", - "dev": true, - "dependencies": { - "@types/mime": "*", - "@types/node": "*" - } - }, - "node_modules/@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", - "dev": true - }, - "node_modules/@types/superagent": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.18.tgz", - "integrity": "sha512-LOWgpacIV8GHhrsQU+QMZuomfqXiqzz3ILLkCtKx3Us6AmomFViuzKT9D693QTKgyut2oCytMG8/efOop+DB+w==", - "dev": true, - "dependencies": { - "@types/cookiejar": "*", - "@types/node": "*" - } - }, - "node_modules/@types/supertest": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-2.0.12.tgz", - "integrity": "sha512-X3HPWTwXRerBZS7Mo1k6vMVR1Z6zmJcDVn5O/31whe0tnjE4te6ZJSJGq1RiqHPjzPdMTfjCFogDJmwng9xHaQ==", - "dev": true, - "dependencies": { - "@types/superagent": "*" - } - }, - "node_modules/@types/swagger-jsdoc": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@types/swagger-jsdoc/-/swagger-jsdoc-6.0.1.tgz", - "integrity": "sha512-+MUpcbyxD528dECUBCEVm6abNuORdbuGjbrUdHDeAQ+rkPuo2a+L4N02WJHF3bonSSE6SJ3dUJwF2V6+cHnf0w==", - "dev": true - }, - "node_modules/@types/swagger-ui-express": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@types/swagger-ui-express/-/swagger-ui-express-4.1.3.tgz", - "integrity": "sha512-jqCjGU/tGEaqIplPy3WyQg+Nrp6y80DCFnDEAvVKWkJyv0VivSSDCChkppHRHAablvInZe6pijDFMnavtN0vqA==", - "dev": true, - "dependencies": { - "@types/express": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/triple-beam": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.2.tgz", - "integrity": "sha512-txGIh+0eDFzKGC25zORnswy+br1Ha7hj5cMVwKIU7+s0U2AxxJru/jZSMU6OC9MJWP6+pc/hc6ZjyZShpsyY2g==" - }, - "node_modules/@types/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog==" - }, - "node_modules/@types/whatwg-url": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz", - "integrity": "sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==", - "dependencies": { - "@types/node": "*", - "@types/webidl-conversions": "*" - } - }, - "node_modules/@types/yargs": { - "version": "17.0.24", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", - "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", - "dev": true - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.7.tgz", - "integrity": "sha512-BL+jYxUFIbuYwy+4fF86k5vdT9lT0CNJ6HtwrIvGh0PhH8s0yy5rjaKH2fDCrz5ITHy07WCzVGNvAmjJh4IJFA==", - "dev": true, - "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.7", - "@typescript-eslint/type-utils": "5.59.7", - "@typescript-eslint/utils": "5.59.7", - "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.7.tgz", - "integrity": "sha512-VhpsIEuq/8i5SF+mPg9jSdIwgMBBp0z9XqjiEay+81PYLJuroN+ET1hM5IhkiYMJd9MkTz8iJLt7aaGAgzWUbQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "5.59.7", - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/typescript-estree": "5.59.7", - "debug": "^4.3.4" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.7.tgz", - "integrity": "sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/visitor-keys": "5.59.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.7.tgz", - "integrity": "sha512-ozuz/GILuYG7osdY5O5yg0QxXUAEoI4Go3Do5xeu+ERH9PorHBPSdvD3Tjp2NN2bNLh1NJQSsQu2TPu/Ly+HaQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "5.59.7", - "@typescript-eslint/utils": "5.59.7", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz", - "integrity": "sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.7.tgz", - "integrity": "sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/visitor-keys": "5.59.7", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.7.tgz", - "integrity": "sha512-yCX9WpdQKaLufz5luG4aJbOpdXf/fjwGMcLFXZVPUz3QqLirG5QcwwnIHNf8cjLjxK4qtzTO8udUtMQSAToQnQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.7", - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/typescript-estree": "5.59.7", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz", - "integrity": "sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.7", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "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, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" - }, - "node_modules/are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "node_modules/argon2": { - "version": "0.30.3", - "resolved": "https://registry.npmjs.org/argon2/-/argon2-0.30.3.tgz", - "integrity": "sha512-DoH/kv8c9127ueJSBxAVJXinW9+EuPA3EMUxoV2sAY1qDE5H9BjTyVF/aD2XyHqbqUWabgBkIfcP3ZZuGhbJdg==", - "hasInstallScript": true, - "dependencies": { - "@mapbox/node-pre-gyp": "^1.0.10", - "@phc/format": "^1.0.0", - "node-addon-api": "^5.0.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "dev": true - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" - }, - "node_modules/async-exit-hook": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", - "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/await-to-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/await-to-js/-/await-to-js-3.0.0.tgz", - "integrity": "sha512-zJAaP9zxTcvTHRlejau3ZOY4V7SRpiByf3/dxx2uyKxxor19tpmpV2QRsTKikckwhaPmr2dVpxxMr7jOCYVp5g==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/aws-sdk": { - "version": "2.1386.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1386.0.tgz", - "integrity": "sha512-bmUvpNRR4x1YvTaAm7WK/2lSNVPrNuiYlleU47GA5Xskh8PKaWedGHvGinH2YwhC720hM0Qc4f4/snUPGJ0eYg==", - "dependencies": { - "buffer": "4.9.2", - "events": "1.1.1", - "ieee754": "1.1.13", - "jmespath": "0.16.0", - "querystring": "0.2.0", - "sax": "1.2.1", - "url": "0.10.3", - "util": "^0.12.4", - "uuid": "8.0.0", - "xml2js": "0.5.0" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/aws-sdk/node_modules/uuid": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", - "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/axios": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", - "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", - "dependencies": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/axios-retry": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.5.0.tgz", - "integrity": "sha512-g48qNrLX30VU6ECWltpFCPegKK6dWzMDYv2o83W2zUL/Zh/SLXbT6ksGoKqYZHtghzqeeXhZBcSXJkO1fPbCcw==", - "dependencies": { - "@babel/runtime": "^7.15.4", - "is-retry-allowed": "^2.2.0" - } - }, - "node_modules/babel-jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.5.0.tgz", - "integrity": "sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q==", - "dev": true, - "dependencies": { - "@jest/transform": "^29.5.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.5.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz", - "integrity": "sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==", - "dev": true, - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz", - "integrity": "sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==", - "dev": true, - "dependencies": { - "babel-plugin-jest-hoist": "^29.5.0", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "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/base64url": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", - "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/bcrypt": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.0.tgz", - "integrity": "sha512-RHBS7HI5N5tEnGTmtR/pppX0mmDSBpQ4aCBsj7CEQfYXDcO74A8sIBYcJMuCsis2E81zDxeENYhv66oZwLiA+Q==", - "hasInstallScript": true, - "dependencies": { - "@mapbox/node-pre-gyp": "^1.0.10", - "node-addon-api": "^5.0.0" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/before-after-hook": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", - "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==" - }, - "node_modules/bigint-conversion": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/bigint-conversion/-/bigint-conversion-2.4.1.tgz", - "integrity": "sha512-/DTRevseMZoqN4KLkN5BryOiom0KbwYajiXG5Vo+ZcEPAO0WBZyZoYyDZSgfeq/v/oegLo9bjdndDBlExvAhBQ==", - "dependencies": { - "@juanelas/base64": "^1.1.2" - } - }, - "node_modules/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, - "engines": { - "node": ">=8" - } - }, - "node_modules/bl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", - "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", - "dependencies": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/bl/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/bl/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/bl/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/bowser": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", - "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.21.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.6.tgz", - "integrity": "sha512-PF07dKGXKR+/bljJzCB6rAYtHEu21TthLxmJagtQizx+rwiqdRDBO5971Xu1N7MgcMLi4+mr4Cnl76x7O3DHtA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001489", - "electron-to-chromium": "^1.4.411", - "node-releases": "^2.0.12", - "update-browserslist-db": "^1.0.11" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "dependencies": { - "fast-json-stable-stringify": "2.x" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/bson": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/bson/-/bson-4.7.2.tgz", - "integrity": "sha512-Ry9wCtIZ5kGqkJoi6aD8KjxFZEx78guTQDnpXWiNthsxzrxAK/i8E6pCHAIZTbaEFWcOCvbecMukfK7XUvyLpQ==", - "dependencies": { - "buffer": "^5.6.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/bson/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/btoa": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz", - "integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==", - "bin": { - "btoa": "bin/btoa.js" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "node_modules/buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/builder-pattern": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/builder-pattern/-/builder-pattern-2.2.0.tgz", - "integrity": "sha512-cES3qdeBzA4QyJi7rV/l/kAhIFX6AKo3vK66ZPXLNpjcQWCS8sjLKscly8imlfW2YPTo/hquMRMnaWpZ80Kj+g==" - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/camelcase-keys": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-7.0.2.tgz", - "integrity": "sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==", - "dev": true, - "dependencies": { - "camelcase": "^6.3.0", - "map-obj": "^4.1.0", - "quick-lru": "^5.1.1", - "type-fest": "^1.2.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001489", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001489.tgz", - "integrity": "sha512-x1mgZEXK8jHIfAxm+xgdpHpk50IN3z3q3zP261/WS+uvePxW8izXuCu6AHz0lkuYTlATDehiZ/tNyYBdSQsOUQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/ci-info": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", - "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", - "dev": true - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true, - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true - }, - "node_modules/color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", - "dependencies": { - "color-convert": "^1.9.3", - "color-string": "^1.6.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" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "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==" - }, - "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/color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "bin": { - "color-support": "bin.js" - } - }, - "node_modules/color/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/colorspace": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", - "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", - "dependencies": { - "color": "^3.1.3", - "text-hex": "1.0.x" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-parser": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz", - "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==", - "dependencies": { - "cookie": "0.4.1", - "cookie-signature": "1.0.6" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/cookie-parser/node_modules/cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "node_modules/cookiejar": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", - "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", - "dev": true - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "node_modules/cross-env": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", - "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "bin": { - "cross-env": "src/bin/cross-env.js", - "cross-env-shell": "src/bin/cross-env-shell.js" - }, - "engines": { - "node": ">=10.14", - "npm": ">=6", - "yarn": ">=1" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto-js": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", - "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==" - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" - }, - "node_modules/denque": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", - "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/deprecation": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "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/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/dezalgo": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", - "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", - "dev": true, - "dependencies": { - "asap": "^2.0.0", - "wrappy": "1" - } - }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/diff-sequences": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", - "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dotenv": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", - "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", - "engines": { - "node": ">=12" - } - }, - "node_modules/ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "node_modules/electron-to-chromium": { - "version": "1.4.411", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.411.tgz", - "integrity": "sha512-5VXLW4Qw89vM2WTICHua/y8v7fKGDRVa2VPOtBB9IpLvW316B+xd8yD1wTmLPY2ot/00P/qt87xdolj4aG/Lzg==", - "dev": true - }, - "node_modules/emittery": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", - "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/enabled": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.41.0.tgz", - "integrity": "sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.41.0", - "@humanwhocodes/config-array": "^0.11.8", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.5.2", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/espree": { - "version": "9.5.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", - "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", - "dev": true, - "dependencies": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expect": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.5.0.tgz", - "integrity": "sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg==", - "dev": true, - "dependencies": { - "@jest/expect-utils": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express-async-errors": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/express-async-errors/-/express-async-errors-3.1.1.tgz", - "integrity": "sha512-h6aK1da4tpqWSbyCa3FxB/V6Ehd4EEB15zyQq9qe75OZBp0krinNKuH4rAY+S/U/2I36vdLAUFSjQJ+TFmODng==", - "peerDependencies": { - "express": "^4.16.2" - } - }, - "node_modules/express-rate-limit": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-6.7.0.tgz", - "integrity": "sha512-vhwIdRoqcYB/72TK3tRZI+0ttS8Ytrk24GfmsxDXK9o9IhHNO5bXRiXQSExPQ4GbaE5tvIS7j1SGrxsuWs+sGA==", - "engines": { - "node": ">= 12.9.0" - }, - "peerDependencies": { - "express": "^4 || ^5" - } - }, - "node_modules/express-validator": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-6.15.0.tgz", - "integrity": "sha512-r05VYoBL3i2pswuehoFSy+uM8NBuVaY7avp5qrYjQBDzagx2Z5A77FZqPT8/gNLF3HopWkIzaTFaC4JysWXLqg==", - "dependencies": { - "lodash": "^4.17.21", - "validator": "^13.9.0" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/express/node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true, - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", - "dev": true - }, - "node_modules/fast-xml-parser": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.1.2.tgz", - "integrity": "sha512-CDYeykkle1LiA/uqQyNwYpFbyF6Axec6YapmpUP+/RHWIoR1zKjocdvNaTsxCxZzQ6v9MLXaSYm9Qq0thv0DHg==", - "dependencies": { - "strnum": "^1.0.5" - }, - "bin": { - "fxparser": "src/cli/cli.js" - }, - "funding": { - "type": "paypal", - "url": "https://paypal.me/naturalintelligence" - } - }, - "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dev": true, - "dependencies": { - "bser": "2.1.1" - } - }, - "node_modules/fecha": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", - "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/filter-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", - "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true - }, - "node_modules/fn.name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" - }, - "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/formidable": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz", - "integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==", - "dev": true, - "dependencies": { - "dezalgo": "^1.0.4", - "hexoid": "^1.0.0", - "once": "^1.4.0", - "qs": "^6.11.0" - }, - "funding": { - "url": "https://ko-fi.com/tunnckoCore/commissions" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fs-minipass/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/gauge": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", - "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.2", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.1", - "object-assign": "^4.1.1", - "signal-exit": "^3.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globals/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" - }, - "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" - }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/helmet": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/helmet/-/helmet-5.1.1.tgz", - "integrity": "sha512-/yX0oVZBggA9cLJh8aw3PPCfedBnbd7J2aowjzsaWwZh7/UFY0nccn/aHAggIgWUFfnykX8GKd3a1pSbrmlcVQ==", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/hexoid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", - "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" - }, - "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", - "dev": true - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/infisical-node": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/infisical-node/-/infisical-node-1.2.1.tgz", - "integrity": "sha512-zEB0w5+1O0mv9qc68bq4f9jDjrtwdbqjJebnwodgy8U1XZElDXeMDQgSMCtgYan7JRmVlH6s/LM8X7kUF+67ZA==", - "dependencies": { - "axios": "^1.3.3", - "dotenv": "^16.0.3", - "tweetnacl": "^1.0.3", - "tweetnacl-util": "^0.15.1" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/install": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/install/-/install-0.13.0.tgz", - "integrity": "sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/ip": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", - "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" - }, - "node_modules/ip6addr": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/ip6addr/-/ip6addr-0.2.5.tgz", - "integrity": "sha512-9RGGSB6Zc9Ox5DpDGFnJdIeF0AsqXzdH+FspCfPPaU/L/4tI6P+5lIoFUFm9JXs9IrJv1boqAaNCQmoDADTSKQ==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^2.0.2" - } - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", - "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-retry-allowed": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz", - "integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.5.0.tgz", - "integrity": "sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ==", - "dev": true, - "dependencies": { - "@jest/core": "^29.5.0", - "@jest/types": "^29.5.0", - "import-local": "^3.0.2", - "jest-cli": "^29.5.0" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-changed-files": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.5.0.tgz", - "integrity": "sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==", - "dev": true, - "dependencies": { - "execa": "^5.0.0", - "p-limit": "^3.1.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-circus": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.5.0.tgz", - "integrity": "sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/expect": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^29.5.0", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", - "p-limit": "^3.1.0", - "pretty-format": "^29.5.0", - "pure-rand": "^6.0.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-cli": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.5.0.tgz", - "integrity": "sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw==", - "dev": true, - "dependencies": { - "@jest/core": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "prompts": "^2.0.1", - "yargs": "^17.3.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-config": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.5.0.tgz", - "integrity": "sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA==", - "dev": true, - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.5.0", - "@jest/types": "^29.5.0", - "babel-jest": "^29.5.0", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-circus": "^29.5.0", - "jest-environment-node": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-runner": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^29.5.0", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@types/node": "*", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-diff": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", - "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.4.3", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-docblock": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.4.3.tgz", - "integrity": "sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==", - "dev": true, - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-each": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.5.0.tgz", - "integrity": "sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA==", - "dev": true, - "dependencies": { - "@jest/types": "^29.5.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.4.3", - "jest-util": "^29.5.0", - "pretty-format": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-environment-node": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.5.0.tgz", - "integrity": "sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/fake-timers": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "jest-mock": "^29.5.0", - "jest-util": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-get-type": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", - "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-haste-map": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.5.0.tgz", - "integrity": "sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==", - "dev": true, - "dependencies": { - "@jest/types": "^29.5.0", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", - "jest-worker": "^29.5.0", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "node_modules/jest-junit": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-15.0.0.tgz", - "integrity": "sha512-Z5sVX0Ag3HZdMUnD5DFlG+1gciIFSy7yIVPhOdGUi8YJaI9iLvvBb530gtQL2CHmv0JJeiwRZenr0VrSR7frvg==", - "dev": true, - "dependencies": { - "mkdirp": "^1.0.4", - "strip-ansi": "^6.0.1", - "uuid": "^8.3.2", - "xml": "^1.0.1" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/jest-leak-detector": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.5.0.tgz", - "integrity": "sha512-u9YdeeVnghBUtpN5mVxjID7KbkKE1QU4f6uUwuxiY0vYRi9BUCLKlPEZfDGR67ofdFmDz9oPAy2G92Ujrntmow==", - "dev": true, - "dependencies": { - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-matcher-utils": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", - "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-message-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", - "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.5.0", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-mock": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.5.0.tgz", - "integrity": "sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw==", - "dev": true, - "dependencies": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "jest-util": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "dev": true, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "node_modules/jest-regex-util": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", - "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-resolve": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.5.0.tgz", - "integrity": "sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "resolve": "^1.20.0", - "resolve.exports": "^2.0.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.5.0.tgz", - "integrity": "sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg==", - "dev": true, - "dependencies": { - "jest-regex-util": "^29.4.3", - "jest-snapshot": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-runner": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.5.0.tgz", - "integrity": "sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ==", - "dev": true, - "dependencies": { - "@jest/console": "^29.5.0", - "@jest/environment": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^29.4.3", - "jest-environment-node": "^29.5.0", - "jest-haste-map": "^29.5.0", - "jest-leak-detector": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-resolve": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-util": "^29.5.0", - "jest-watcher": "^29.5.0", - "jest-worker": "^29.5.0", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-runtime": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.5.0.tgz", - "integrity": "sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/fake-timers": "^29.5.0", - "@jest/globals": "^29.5.0", - "@jest/source-map": "^29.4.3", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-snapshot": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.5.0.tgz", - "integrity": "sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==", - "dev": true, - "dependencies": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/babel__traverse": "^7.0.6", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.5.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.5.0", - "semver": "^7.3.5" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", - "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", - "dev": true, - "dependencies": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-validate": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.5.0.tgz", - "integrity": "sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ==", - "dev": true, - "dependencies": { - "@jest/types": "^29.5.0", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.4.3", - "leven": "^3.1.0", - "pretty-format": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-watcher": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.5.0.tgz", - "integrity": "sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA==", - "dev": true, - "dependencies": { - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "jest-util": "^29.5.0", - "string-length": "^4.0.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", - "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", - "dev": true, - "dependencies": { - "@types/node": "*", - "jest-util": "^29.5.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/jmespath": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", - "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", - "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==" - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonwebtoken": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz", - "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==", - "dependencies": { - "jws": "^3.2.2", - "lodash": "^4.17.21", - "ms": "^2.1.1", - "semver": "^7.3.8" - }, - "engines": { - "node": ">=12", - "npm": ">=6" - } - }, - "node_modules/jsprim": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", - "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - } - }, - "node_modules/jsrp": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/jsrp/-/jsrp-0.2.4.tgz", - "integrity": "sha512-+CjGAhZaj3k2MMXEy+xWYv7xJGnise/SlL1IIvnRuJ1ZiLtNPJJln/dMDCgORQCq1ouXDnW1FBxW5bkBFhK/8g==", - "dependencies": { - "create-hash": "^1.0.0", - "jsbn": "^1.0.0", - "randombytes": "^2.0.0" - } - }, - "node_modules/jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "dependencies": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/kareem": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz", - "integrity": "sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/kuler": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/libsodium": { - "version": "0.7.11", - "resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.7.11.tgz", - "integrity": "sha512-WPfJ7sS53I2s4iM58QxY3Inb83/6mjlYgcmZs7DJsvDlnmVUwNinBCi5vBT43P6bHRy01O4zsMU2CoVR6xJ40A==" - }, - "node_modules/libsodium-wrappers": { - "version": "0.7.11", - "resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.11.tgz", - "integrity": "sha512-SrcLtXj7BM19vUKtQuyQKiQCRJPgbpauzl3s0rSwD+60wtHqSUuqcoawlMDheCJga85nKOQwxNYQxf/CKAvs6Q==", - "dependencies": { - "libsodium": "^0.7.11" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/logform": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.5.1.tgz", - "integrity": "sha512-9FyqAm9o9NKKfiAKfZoYo9bGXXuwMkxQiQttkT4YjjVtQVIQtK6LmVtlxmCaFswo6N4AfEkHqZTV0taDtPotNg==", - "dependencies": { - "@colors/colors": "1.5.0", - "@types/triple-beam": "^1.3.2", - "fecha": "^4.2.0", - "ms": "^2.1.1", - "safe-stable-stringify": "^2.3.1", - "triple-beam": "^1.3.0" - } - }, - "node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, - "node_modules/lru_map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", - "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==" - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "dependencies": { - "tmpl": "1.0.5" - } - }, - "node_modules/map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/maxmind": { - "version": "4.3.11", - "resolved": "https://registry.npmjs.org/maxmind/-/maxmind-4.3.11.tgz", - "integrity": "sha512-tJDrKbUzN6PSA88tWgg0L2R4Ln00XwecYQJPFI+RvlF2k1sx6VQYtuQ1SVxm8+bw5tF7GWV4xyb+3/KyzEpPUw==", - "dev": true, - "dependencies": { - "mmdb-lib": "2.0.2", - "tiny-lru": "11.0.1" - }, - "engines": { - "node": ">=12", - "npm": ">=6" - } - }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memory-pager": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", - "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", - "optional": true - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mmdb-lib": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/mmdb-lib/-/mmdb-lib-2.0.2.tgz", - "integrity": "sha512-shi1I+fCPQonhTi7qyb6hr7hi87R7YS69FlfJiMFuJ12+grx0JyL56gLNzGTYXPU7EhAPkMLliGeyHer0K+AVA==", - "dev": true, - "engines": { - "node": ">=10", - "npm": ">=6" - } - }, - "node_modules/mongodb": { - "version": "4.16.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.16.0.tgz", - "integrity": "sha512-0EB113Fsucaq1wsY0dOhi1fmZOwFtLOtteQkiqOXGklvWMnSH3g2QS53f0KTP+/6qOkuoXE2JksubSZNmxeI+g==", - "dependencies": { - "bson": "^4.7.2", - "mongodb-connection-string-url": "^2.5.4", - "socks": "^2.7.1" - }, - "engines": { - "node": ">=12.9.0" - }, - "optionalDependencies": { - "@aws-sdk/credential-providers": "^3.186.0", - "saslprep": "^1.0.3" - } - }, - "node_modules/mongodb-connection-string-url": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz", - "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==", - "dependencies": { - "@types/whatwg-url": "^8.2.1", - "whatwg-url": "^11.0.0" - } - }, - "node_modules/mongoose": { - "version": "6.11.1", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-6.11.1.tgz", - "integrity": "sha512-AvQ8C5ZGF6GcsQhoRg/i7pbNZpb96qLGU5ICBllckp7qMOxcfUF1nA6JstZw841BqRcE6myZ/mx9CluEESaw5Q==", - "dependencies": { - "bson": "^4.7.2", - "kareem": "2.5.1", - "mongodb": "4.16.0", - "mpath": "0.9.0", - "mquery": "4.0.3", - "ms": "2.1.3", - "sift": "16.0.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mongoose" - } - }, - "node_modules/mongoose/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/mpath": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", - "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/mquery": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/mquery/-/mquery-4.0.3.tgz", - "integrity": "sha512-J5heI+P08I6VJ2Ky3+33IpCdAvlYGTSUjwTPxkAr8i8EoduPMBX2OY/wa3IKZIQl7MU4SbFk8ndgSKyB/cl1zA==", - "dependencies": { - "debug": "4.x" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "node_modules/node-addon-api": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", - "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" - }, - "node_modules/node-cache": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-5.1.2.tgz", - "integrity": "sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==", - "dependencies": { - "clone": "2.x" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-fetch/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/node-fetch/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/node-fetch/node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true - }, - "node_modules/node-releases": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz", - "integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==", - "dev": true - }, - "node_modules/nodemailer": { - "version": "6.9.2", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.2.tgz", - "integrity": "sha512-4+TYaa/e1nIxQfyw/WzNPYTEZ5OvHIDEnmjs4LPmIfccPQN+2CYKmGHjWixn/chzD3bmUTu5FMfpltizMxqzdg==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/nodemon": { - "version": "2.0.22", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz", - "integrity": "sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==", - "dev": true, - "dependencies": { - "chokidar": "^3.5.2", - "debug": "^3.2.7", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.1.2", - "pstree.remy": "^1.1.8", - "semver": "^5.7.1", - "simple-update-notifier": "^1.0.7", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.5" - }, - "bin": { - "nodemon": "bin/nodemon.js" - }, - "engines": { - "node": ">=8.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nodemon" - } - }, - "node_modules/nodemon/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/nodemon/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/nodemon/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/nodemon/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm": { - "version": "8.19.4", - "resolved": "https://registry.npmjs.org/npm/-/npm-8.19.4.tgz", - "integrity": "sha512-3HANl8i9DKnUA89P4KEgVNN28EjSeDCmvEqbzOAuxCFDzdBZzjUl99zgnGpOUumvW5lvJo2HKcjrsc+tfyv1Hw==", - "bundleDependencies": [ - "@isaacs/string-locale-compare", - "@npmcli/arborist", - "@npmcli/ci-detect", - "@npmcli/config", - "@npmcli/fs", - "@npmcli/map-workspaces", - "@npmcli/package-json", - "@npmcli/run-script", - "abbrev", - "archy", - "cacache", - "chalk", - "chownr", - "cli-columns", - "cli-table3", - "columnify", - "fastest-levenshtein", - "fs-minipass", - "glob", - "graceful-fs", - "hosted-git-info", - "ini", - "init-package-json", - "is-cidr", - "json-parse-even-better-errors", - "libnpmaccess", - "libnpmdiff", - "libnpmexec", - "libnpmfund", - "libnpmhook", - "libnpmorg", - "libnpmpack", - "libnpmpublish", - "libnpmsearch", - "libnpmteam", - "libnpmversion", - "make-fetch-happen", - "minimatch", - "minipass", - "minipass-pipeline", - "mkdirp", - "mkdirp-infer-owner", - "ms", - "node-gyp", - "nopt", - "npm-audit-report", - "npm-install-checks", - "npm-package-arg", - "npm-pick-manifest", - "npm-profile", - "npm-registry-fetch", - "npm-user-validate", - "npmlog", - "opener", - "p-map", - "pacote", - "parse-conflict-json", - "proc-log", - "qrcode-terminal", - "read", - "read-package-json", - "read-package-json-fast", - "readdir-scoped-modules", - "rimraf", - "semver", - "ssri", - "tar", - "text-table", - "tiny-relative-date", - "treeverse", - "validate-npm-package-name", - "which", - "write-file-atomic" - ], - "dev": true, - "dependencies": { - "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^5.6.3", - "@npmcli/ci-detect": "^2.0.0", - "@npmcli/config": "^4.2.1", - "@npmcli/fs": "^2.1.0", - "@npmcli/map-workspaces": "^2.0.3", - "@npmcli/package-json": "^2.0.0", - "@npmcli/run-script": "^4.2.1", - "abbrev": "~1.1.1", - "archy": "~1.0.0", - "cacache": "^16.1.3", - "chalk": "^4.1.2", - "chownr": "^2.0.0", - "cli-columns": "^4.0.0", - "cli-table3": "^0.6.2", - "columnify": "^1.6.0", - "fastest-levenshtein": "^1.0.12", - "fs-minipass": "^2.1.0", - "glob": "^8.0.1", - "graceful-fs": "^4.2.10", - "hosted-git-info": "^5.2.1", - "ini": "^3.0.1", - "init-package-json": "^3.0.2", - "is-cidr": "^4.0.2", - "json-parse-even-better-errors": "^2.3.1", - "libnpmaccess": "^6.0.4", - "libnpmdiff": "^4.0.5", - "libnpmexec": "^4.0.14", - "libnpmfund": "^3.0.5", - "libnpmhook": "^8.0.4", - "libnpmorg": "^4.0.4", - "libnpmpack": "^4.1.3", - "libnpmpublish": "^6.0.5", - "libnpmsearch": "^5.0.4", - "libnpmteam": "^4.0.4", - "libnpmversion": "^3.0.7", - "make-fetch-happen": "^10.2.0", - "minimatch": "^5.1.0", - "minipass": "^3.1.6", - "minipass-pipeline": "^1.2.4", - "mkdirp": "^1.0.4", - "mkdirp-infer-owner": "^2.0.0", - "ms": "^2.1.2", - "node-gyp": "^9.1.0", - "nopt": "^6.0.0", - "npm-audit-report": "^3.0.0", - "npm-install-checks": "^5.0.0", - "npm-package-arg": "^9.1.0", - "npm-pick-manifest": "^7.0.2", - "npm-profile": "^6.2.0", - "npm-registry-fetch": "^13.3.1", - "npm-user-validate": "^1.0.1", - "npmlog": "^6.0.2", - "opener": "^1.5.2", - "p-map": "^4.0.0", - "pacote": "^13.6.2", - "parse-conflict-json": "^2.0.2", - "proc-log": "^2.0.1", - "qrcode-terminal": "^0.12.0", - "read": "~1.0.7", - "read-package-json": "^5.0.2", - "read-package-json-fast": "^2.0.3", - "readdir-scoped-modules": "^1.1.0", - "rimraf": "^3.0.2", - "semver": "^7.3.7", - "ssri": "^9.0.1", - "tar": "^6.1.11", - "text-table": "~0.2.0", - "tiny-relative-date": "^1.3.0", - "treeverse": "^2.0.0", - "validate-npm-package-name": "^4.0.0", - "which": "^2.0.2", - "write-file-atomic": "^4.0.1" - }, - "bin": { - "npm": "bin/npm-cli.js", - "npx": "bin/npx-cli.js" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/@colors/colors": { - "version": "1.5.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/npm/node_modules/@gar/promisify": { - "version": "1.1.3", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/@isaacs/string-locale-compare": { - "version": "1.1.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/@npmcli/arborist": { - "version": "5.6.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/installed-package-contents": "^1.0.7", - "@npmcli/map-workspaces": "^2.0.3", - "@npmcli/metavuln-calculator": "^3.0.1", - "@npmcli/move-file": "^2.0.0", - "@npmcli/name-from-folder": "^1.0.1", - "@npmcli/node-gyp": "^2.0.0", - "@npmcli/package-json": "^2.0.0", - "@npmcli/query": "^1.2.0", - "@npmcli/run-script": "^4.1.3", - "bin-links": "^3.0.3", - "cacache": "^16.1.3", - "common-ancestor-path": "^1.0.1", - "hosted-git-info": "^5.2.1", - "json-parse-even-better-errors": "^2.3.1", - "json-stringify-nice": "^1.1.4", - "minimatch": "^5.1.0", - "mkdirp": "^1.0.4", - "mkdirp-infer-owner": "^2.0.0", - "nopt": "^6.0.0", - "npm-install-checks": "^5.0.0", - "npm-package-arg": "^9.0.0", - "npm-pick-manifest": "^7.0.2", - "npm-registry-fetch": "^13.0.0", - "npmlog": "^6.0.2", - "pacote": "^13.6.1", - "parse-conflict-json": "^2.0.1", - "proc-log": "^2.0.0", - "promise-all-reject-late": "^1.0.0", - "promise-call-limit": "^1.0.1", - "read-package-json-fast": "^2.0.2", - "readdir-scoped-modules": "^1.1.0", - "rimraf": "^3.0.2", - "semver": "^7.3.7", - "ssri": "^9.0.0", - "treeverse": "^2.0.0", - "walk-up-path": "^1.0.0" - }, - "bin": { - "arborist": "bin/index.js" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/ci-detect": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" - } - }, - "node_modules/npm/node_modules/@npmcli/config": { - "version": "4.2.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/map-workspaces": "^2.0.2", - "ini": "^3.0.0", - "mkdirp-infer-owner": "^2.0.0", - "nopt": "^6.0.0", - "proc-log": "^2.0.0", - "read-package-json-fast": "^2.0.3", - "semver": "^7.3.5", - "walk-up-path": "^1.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/disparity-colors": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "ansi-styles": "^4.3.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/fs": { - "version": "2.1.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@gar/promisify": "^1.1.3", - "semver": "^7.3.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/git": { - "version": "3.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/promise-spawn": "^3.0.0", - "lru-cache": "^7.4.4", - "mkdirp": "^1.0.4", - "npm-pick-manifest": "^7.0.0", - "proc-log": "^2.0.0", - "promise-inflight": "^1.0.1", - "promise-retry": "^2.0.1", - "semver": "^7.3.5", - "which": "^2.0.2" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/installed-package-contents": { - "version": "1.0.7", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-bundled": "^1.1.1", - "npm-normalize-package-bin": "^1.0.1" - }, - "bin": { - "installed-package-contents": "index.js" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/npm/node_modules/@npmcli/installed-package-contents/node_modules/npm-bundled": { - "version": "1.1.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-normalize-package-bin": "^1.0.1" - } - }, - "node_modules/npm/node_modules/@npmcli/map-workspaces": { - "version": "2.0.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/name-from-folder": "^1.0.1", - "glob": "^8.0.1", - "minimatch": "^5.0.1", - "read-package-json-fast": "^2.0.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { - "version": "3.1.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "cacache": "^16.0.0", - "json-parse-even-better-errors": "^2.3.1", - "pacote": "^13.0.3", - "semver": "^7.3.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/move-file": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/name-from-folder": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/@npmcli/node-gyp": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/package-json": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "json-parse-even-better-errors": "^2.3.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/promise-spawn": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "infer-owner": "^1.0.4" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/query": { - "version": "1.2.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-package-arg": "^9.1.0", - "postcss-selector-parser": "^6.0.10", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/run-script": { - "version": "4.2.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/node-gyp": "^2.0.0", - "@npmcli/promise-spawn": "^3.0.0", - "node-gyp": "^9.0.0", - "read-package-json-fast": "^2.0.3", - "which": "^2.0.2" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/@tootallnate/once": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/npm/node_modules/abbrev": { - "version": "1.1.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/agent-base": { - "version": "6.0.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/npm/node_modules/agentkeepalive": { - "version": "4.2.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "debug": "^4.1.0", - "depd": "^1.1.2", - "humanize-ms": "^1.2.1" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/npm/node_modules/aggregate-error": { - "version": "3.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/npm/node_modules/aproba": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/archy": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/are-we-there-yet": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/asap": { - "version": "2.0.6", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/balanced-match": { - "version": "1.0.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/bin-links": { - "version": "3.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "cmd-shim": "^5.0.0", - "mkdirp-infer-owner": "^2.0.0", - "npm-normalize-package-bin": "^2.0.0", - "read-cmd-shim": "^3.0.0", - "rimraf": "^3.0.0", - "write-file-atomic": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/bin-links/node_modules/npm-normalize-package-bin": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/binary-extensions": { - "version": "2.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/brace-expansion": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/npm/node_modules/builtins": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "semver": "^7.0.0" - } - }, - "node_modules/npm/node_modules/cacache": { - "version": "16.1.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/fs": "^2.1.0", - "@npmcli/move-file": "^2.0.0", - "chownr": "^2.0.0", - "fs-minipass": "^2.1.0", - "glob": "^8.0.1", - "infer-owner": "^1.0.4", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "mkdirp": "^1.0.4", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^9.0.0", - "tar": "^6.1.11", - "unique-filename": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/chalk": { - "version": "4.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/npm/node_modules/chownr": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/cidr-regex": { - "version": "3.1.1", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "ip-regex": "^4.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/clean-stack": { - "version": "2.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/npm/node_modules/cli-columns": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/npm/node_modules/cli-table3": { - "version": "0.6.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "@colors/colors": "1.5.0" - } - }, - "node_modules/npm/node_modules/clone": { - "version": "1.0.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/npm/node_modules/cmd-shim": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "mkdirp-infer-owner": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/color-convert": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/npm/node_modules/color-name": { - "version": "1.1.4", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/color-support": { - "version": "1.1.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "bin": { - "color-support": "bin.js" - } - }, - "node_modules/npm/node_modules/columnify": { - "version": "1.6.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "strip-ansi": "^6.0.1", - "wcwidth": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/npm/node_modules/common-ancestor-path": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/concat-map": { - "version": "0.0.1", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/console-control-strings": { - "version": "1.1.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/cssesc": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm/node_modules/debug": { - "version": "4.3.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/npm/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/debuglog": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/npm/node_modules/defaults": { - "version": "1.0.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "clone": "^1.0.2" - } - }, - "node_modules/npm/node_modules/delegates": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/depd": { - "version": "1.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/npm/node_modules/dezalgo": { - "version": "1.0.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "asap": "^2.0.0", - "wrappy": "1" - } - }, - "node_modules/npm/node_modules/diff": { - "version": "5.1.0", - "dev": true, - "inBundle": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/npm/node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/encoding": { - "version": "0.1.13", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" - } - }, - "node_modules/npm/node_modules/env-paths": { - "version": "2.2.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/npm/node_modules/err-code": { - "version": "2.0.3", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/fastest-levenshtein": { - "version": "1.0.12", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/fs-minipass": { - "version": "2.1.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/fs.realpath": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/function-bind": { - "version": "1.1.1", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/gauge": { - "version": "4.0.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/glob": { - "version": "8.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/graceful-fs": { - "version": "4.2.10", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/has": { - "version": "1.0.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/npm/node_modules/has-flag": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/has-unicode": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/hosted-git-info": { - "version": "5.2.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^7.5.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/http-cache-semantics": { - "version": "4.1.1", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause" - }, - "node_modules/npm/node_modules/http-proxy-agent": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/npm/node_modules/https-proxy-agent": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/npm/node_modules/humanize-ms": { - "version": "1.2.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ms": "^2.0.0" - } - }, - "node_modules/npm/node_modules/iconv-lite": { - "version": "0.6.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm/node_modules/ignore-walk": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minimatch": "^5.0.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/imurmurhash": { - "version": "0.1.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/npm/node_modules/indent-string": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/infer-owner": { - "version": "1.0.4", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/inflight": { - "version": "1.0.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/npm/node_modules/inherits": { - "version": "2.0.4", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/ini": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/init-package-json": { - "version": "3.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-package-arg": "^9.0.1", - "promzard": "^0.3.0", - "read": "^1.0.7", - "read-package-json": "^5.0.0", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4", - "validate-npm-package-name": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/ip": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/ip-regex": { - "version": "4.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/is-cidr": { - "version": "4.0.2", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "cidr-regex": "^3.1.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/is-core-module": { - "version": "2.10.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/npm/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/is-lambda": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/isexe": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/json-stringify-nice": { - "version": "1.1.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/jsonparse": { - "version": "1.3.1", - "dev": true, - "engines": [ - "node >= 0.2.0" - ], - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/just-diff": { - "version": "5.1.1", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/just-diff-apply": { - "version": "5.4.1", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/libnpmaccess": { - "version": "6.0.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^2.0.0", - "minipass": "^3.1.1", - "npm-package-arg": "^9.0.1", - "npm-registry-fetch": "^13.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/libnpmdiff": { - "version": "4.0.5", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/disparity-colors": "^2.0.0", - "@npmcli/installed-package-contents": "^1.0.7", - "binary-extensions": "^2.2.0", - "diff": "^5.1.0", - "minimatch": "^5.0.1", - "npm-package-arg": "^9.0.1", - "pacote": "^13.6.1", - "tar": "^6.1.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/libnpmexec": { - "version": "4.0.14", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/arborist": "^5.6.3", - "@npmcli/ci-detect": "^2.0.0", - "@npmcli/fs": "^2.1.1", - "@npmcli/run-script": "^4.2.0", - "chalk": "^4.1.0", - "mkdirp-infer-owner": "^2.0.0", - "npm-package-arg": "^9.0.1", - "npmlog": "^6.0.2", - "pacote": "^13.6.1", - "proc-log": "^2.0.0", - "read": "^1.0.7", - "read-package-json-fast": "^2.0.2", - "semver": "^7.3.7", - "walk-up-path": "^1.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/libnpmfund": { - "version": "3.0.5", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/arborist": "^5.6.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/libnpmhook": { - "version": "8.0.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^13.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/libnpmorg": { - "version": "4.0.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^13.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/libnpmpack": { - "version": "4.1.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/run-script": "^4.1.3", - "npm-package-arg": "^9.0.1", - "pacote": "^13.6.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/libnpmpublish": { - "version": "6.0.5", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "normalize-package-data": "^4.0.0", - "npm-package-arg": "^9.0.1", - "npm-registry-fetch": "^13.0.0", - "semver": "^7.3.7", - "ssri": "^9.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/libnpmsearch": { - "version": "5.0.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-registry-fetch": "^13.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/libnpmteam": { - "version": "4.0.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^13.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/libnpmversion": { - "version": "3.0.7", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/git": "^3.0.0", - "@npmcli/run-script": "^4.1.3", - "json-parse-even-better-errors": "^2.3.1", - "proc-log": "^2.0.0", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/lru-cache": { - "version": "7.13.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/npm/node_modules/make-fetch-happen": { - "version": "10.2.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "agentkeepalive": "^4.2.1", - "cacache": "^16.1.0", - "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^2.0.3", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^7.0.0", - "ssri": "^9.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/minimatch": { - "version": "5.1.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/minipass": { - "version": "3.3.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-collect": { - "version": "1.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/minipass-fetch": { - "version": "2.1.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "minipass": "^3.1.6", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, - "node_modules/npm/node_modules/minipass-flush": { - "version": "1.0.5", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/minipass-json-stream": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "jsonparse": "^1.3.1", - "minipass": "^3.0.0" - } - }, - "node_modules/npm/node_modules/minipass-pipeline": { - "version": "1.2.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-sized": { - "version": "1.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minizlib": { - "version": "2.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/mkdirp": { - "version": "1.0.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/mkdirp-infer-owner": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "chownr": "^2.0.0", - "infer-owner": "^1.0.4", - "mkdirp": "^1.0.3" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/ms": { - "version": "2.1.3", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/mute-stream": { - "version": "0.0.8", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/negotiator": { - "version": "0.6.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/npm/node_modules/node-gyp": { - "version": "9.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "env-paths": "^2.2.0", - "glob": "^7.1.4", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^10.0.3", - "nopt": "^5.0.0", - "npmlog": "^6.0.0", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^2.0.2" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": "^12.22 || ^14.13 || >=16" - } - }, - "node_modules/npm/node_modules/node-gyp/node_modules/brace-expansion": { - "version": "1.1.11", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/npm/node_modules/node-gyp/node_modules/glob": { - "version": "7.2.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/node-gyp/node_modules/minimatch": { - "version": "3.1.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/npm/node_modules/node-gyp/node_modules/nopt": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/npm/node_modules/nopt": { - "version": "6.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "abbrev": "^1.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/normalize-package-data": { - "version": "4.0.1", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^5.0.0", - "is-core-module": "^2.8.1", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/npm-audit-report": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "chalk": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/npm-bundled": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-normalize-package-bin": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/npm-bundled/node_modules/npm-normalize-package-bin": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/npm-install-checks": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "semver": "^7.1.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/npm-normalize-package-bin": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/npm-package-arg": { - "version": "9.1.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "hosted-git-info": "^5.0.0", - "proc-log": "^2.0.1", - "semver": "^7.3.5", - "validate-npm-package-name": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/npm-packlist": { - "version": "5.1.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "glob": "^8.0.1", - "ignore-walk": "^5.0.1", - "npm-bundled": "^2.0.0", - "npm-normalize-package-bin": "^2.0.0" - }, - "bin": { - "npm-packlist": "bin/index.js" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/npm-packlist/node_modules/npm-normalize-package-bin": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/npm-pick-manifest": { - "version": "7.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-install-checks": "^5.0.0", - "npm-normalize-package-bin": "^2.0.0", - "npm-package-arg": "^9.0.0", - "semver": "^7.3.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/npm-pick-manifest/node_modules/npm-normalize-package-bin": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/npm-profile": { - "version": "6.2.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-registry-fetch": "^13.0.1", - "proc-log": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/npm-registry-fetch": { - "version": "13.3.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "make-fetch-happen": "^10.0.6", - "minipass": "^3.1.6", - "minipass-fetch": "^2.0.3", - "minipass-json-stream": "^1.0.1", - "minizlib": "^2.1.2", - "npm-package-arg": "^9.0.1", - "proc-log": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/npm-user-validate": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause" - }, - "node_modules/npm/node_modules/npmlog": { - "version": "6.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.3", - "set-blocking": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/once": { - "version": "1.4.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/npm/node_modules/opener": { - "version": "1.5.2", - "dev": true, - "inBundle": true, - "license": "(WTFPL OR MIT)", - "bin": { - "opener": "bin/opener-bin.js" - } - }, - "node_modules/npm/node_modules/p-map": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm/node_modules/pacote": { - "version": "13.6.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/git": "^3.0.0", - "@npmcli/installed-package-contents": "^1.0.7", - "@npmcli/promise-spawn": "^3.0.0", - "@npmcli/run-script": "^4.1.0", - "cacache": "^16.0.0", - "chownr": "^2.0.0", - "fs-minipass": "^2.1.0", - "infer-owner": "^1.0.4", - "minipass": "^3.1.6", - "mkdirp": "^1.0.4", - "npm-package-arg": "^9.0.0", - "npm-packlist": "^5.1.0", - "npm-pick-manifest": "^7.0.0", - "npm-registry-fetch": "^13.0.1", - "proc-log": "^2.0.0", - "promise-retry": "^2.0.1", - "read-package-json": "^5.0.0", - "read-package-json-fast": "^2.0.3", - "rimraf": "^3.0.2", - "ssri": "^9.0.0", - "tar": "^6.1.11" - }, - "bin": { - "pacote": "lib/bin.js" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/parse-conflict-json": { - "version": "2.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "json-parse-even-better-errors": "^2.3.1", - "just-diff": "^5.0.1", - "just-diff-apply": "^5.2.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/path-is-absolute": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm/node_modules/postcss-selector-parser": { - "version": "6.0.10", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm/node_modules/proc-log": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/promise-all-reject-late": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/promise-call-limit": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/promise-inflight": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/promise-retry": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/promzard": { - "version": "0.3.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "read": "1" - } - }, - "node_modules/npm/node_modules/qrcode-terminal": { - "version": "0.12.0", - "dev": true, - "inBundle": true, - "bin": { - "qrcode-terminal": "bin/qrcode-terminal.js" - } - }, - "node_modules/npm/node_modules/read": { - "version": "1.0.7", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "mute-stream": "~0.0.4" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/npm/node_modules/read-cmd-shim": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/read-package-json": { - "version": "5.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "glob": "^8.0.1", - "json-parse-even-better-errors": "^2.3.1", - "normalize-package-data": "^4.0.0", - "npm-normalize-package-bin": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/read-package-json-fast": { - "version": "2.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "json-parse-even-better-errors": "^2.3.0", - "npm-normalize-package-bin": "^1.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/read-package-json/node_modules/npm-normalize-package-bin": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/readable-stream": { - "version": "3.6.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/npm/node_modules/readdir-scoped-modules": { - "version": "1.1.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "debuglog": "^1.0.1", - "dezalgo": "^1.0.0", - "graceful-fs": "^4.1.2", - "once": "^1.3.0" - } - }, - "node_modules/npm/node_modules/retry": { - "version": "0.12.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/npm/node_modules/rimraf": { - "version": "3.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/rimraf/node_modules/brace-expansion": { - "version": "1.1.11", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/npm/node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/rimraf/node_modules/minimatch": { - "version": "3.1.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/npm/node_modules/safe-buffer": { - "version": "5.2.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/safer-buffer": { - "version": "2.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true - }, - "node_modules/npm/node_modules/semver": { - "version": "7.3.7", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/set-blocking": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/signal-exit": { - "version": "3.0.7", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/smart-buffer": { - "version": "4.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/npm/node_modules/socks": { - "version": "2.7.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ip": "^2.0.0", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.13.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/npm/node_modules/socks-proxy-agent": { - "version": "7.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "agent-base": "^6.0.2", - "debug": "^4.3.3", - "socks": "^2.6.2" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/npm/node_modules/spdx-correct": { - "version": "3.1.1", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/npm/node_modules/spdx-exceptions": { - "version": "2.3.0", - "dev": true, - "inBundle": true, - "license": "CC-BY-3.0" - }, - "node_modules/npm/node_modules/spdx-expression-parse": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/npm/node_modules/spdx-license-ids": { - "version": "3.0.11", - "dev": true, - "inBundle": true, - "license": "CC0-1.0" - }, - "node_modules/npm/node_modules/ssri": { - "version": "9.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.1.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/string_decoder": { - "version": "1.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/npm/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/supports-color": { - "version": "7.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/tar": { - "version": "6.1.11", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/npm/node_modules/text-table": { - "version": "0.2.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/tiny-relative-date": { - "version": "1.3.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/treeverse": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/unique-filename": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "unique-slug": "^3.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/unique-slug": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/util-deprecate": { - "version": "1.0.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/validate-npm-package-license": { - "version": "3.0.4", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/npm/node_modules/validate-npm-package-name": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "builtins": "^5.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/walk-up-path": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/wcwidth": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "defaults": "^1.0.3" - } - }, - "node_modules/npm/node_modules/which": { - "version": "2.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/wide-align": { - "version": "1.1.5", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "node_modules/npm/node_modules/wrappy": { - "version": "1.0.2", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/write-file-atomic": { - "version": "4.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npmlog": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", - "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", - "dependencies": { - "are-we-there-yet": "^2.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^3.0.0", - "set-blocking": "^2.0.0" - } - }, - "node_modules/oauth": { - "version": "0.9.15", - "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", - "integrity": "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==" - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/one-time": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", - "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", - "dependencies": { - "fn.name": "1.x.x" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optional-require": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.1.8.tgz", - "integrity": "sha512-jq83qaUb0wNg9Krv1c5OQ+58EK+vHde6aBPzLvPPqJm89UQWsvSuFy9X/OSNJnFeSOKo7btE0n8Nl2+nE+z5nA==", - "dependencies": { - "require-at": "^1.0.6" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/passport": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/passport/-/passport-0.6.0.tgz", - "integrity": "sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==", - "dependencies": { - "passport-strategy": "1.x.x", - "pause": "0.0.1", - "utils-merge": "^1.0.1" - }, - "engines": { - "node": ">= 0.4.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/jaredhanson" - } - }, - "node_modules/passport-google-oauth20": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/passport-google-oauth20/-/passport-google-oauth20-2.0.0.tgz", - "integrity": "sha512-KSk6IJ15RoxuGq7D1UKK/8qKhNfzbLeLrG3gkLZ7p4A6DBCcv7xpyQwuXtWdpyR0+E0mwkpjY1VfPOhxQrKzdQ==", - "dependencies": { - "passport-oauth2": "1.x.x" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/passport-oauth2": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.7.0.tgz", - "integrity": "sha512-j2gf34szdTF2Onw3+76alNnaAExlUmHvkc7cL+cmaS5NzHzDP/BvFHJruueQ9XAeNOdpI+CH+PWid8RA7KCwAQ==", - "dependencies": { - "base64url": "3.x.x", - "oauth": "0.9.x", - "passport-strategy": "1.x.x", - "uid2": "0.0.x", - "utils-merge": "1.x.x" - }, - "engines": { - "node": ">= 0.4.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/jaredhanson" - } - }, - "node_modules/passport-strategy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", - "integrity": "sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pause": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", - "integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==" - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/posthog-node": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/posthog-node/-/posthog-node-2.6.0.tgz", - "integrity": "sha512-/BiFw/jwdP0uJSRAIoYqLoBTjZ612xv74b1L/a3T/p1nJVL8e0OrHuxbJW56c6WVW/IKm9gBF/zhbqfaz0XgJQ==", - "dependencies": { - "axios": "^0.27.0" - }, - "engines": { - "node": ">=15.0.0" - } - }, - "node_modules/posthog-node/node_modules/axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", - "dependencies": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.4.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/protobufjs": { - "version": "6.11.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", - "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", - "hasInstallScript": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - }, - "bin": { - "pbjs": "bin/pbjs", - "pbts": "bin/pbts" - } - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "node_modules/pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "dev": true - }, - "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/pure-rand": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.2.tgz", - "integrity": "sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ] - }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/query-string": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz", - "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==", - "dependencies": { - "decode-uri-component": "^0.2.2", - "filter-obj": "^1.1.0", - "split-on-first": "^1.0.0", - "strict-uri-encode": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", - "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "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/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/rate-limit-mongo": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/rate-limit-mongo/-/rate-limit-mongo-2.3.2.tgz", - "integrity": "sha512-dLck0j5N/AX9ycVHn5lX9Ti2Wrrwi1LfbXitu/mMBZOo2nC26RgYKJVbcb2mYgb9VMaPI2IwJVzIa2hAQrMaDA==", - "dependencies": { - "mongodb": "^3.6.7", - "twostep": "0.4.2", - "underscore": "1.12.1" - } - }, - "node_modules/rate-limit-mongo/node_modules/bson": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", - "integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==", - "engines": { - "node": ">=0.6.19" - } - }, - "node_modules/rate-limit-mongo/node_modules/mongodb": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.7.3.tgz", - "integrity": "sha512-Psm+g3/wHXhjBEktkxXsFMZvd3nemI0r3IPsE0bU+4//PnvNWKkzhZcEsbPcYiWqe8XqXJJEg4Tgtr7Raw67Yw==", - "dependencies": { - "bl": "^2.2.1", - "bson": "^1.1.4", - "denque": "^1.4.1", - "optional-require": "^1.1.8", - "safe-buffer": "^5.1.2" - }, - "engines": { - "node": ">=4" - }, - "optionalDependencies": { - "saslprep": "^1.0.0" - }, - "peerDependenciesMeta": { - "aws4": { - "optional": true - }, - "bson-ext": { - "optional": true - }, - "kerberos": { - "optional": true - }, - "mongodb-client-encryption": { - "optional": true - }, - "mongodb-extjson": { - "optional": true - }, - "snappy": { - "optional": true - } - } - }, - "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" - }, - "node_modules/require-at": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/require-at/-/require-at-1.0.6.tgz", - "integrity": "sha512-7i1auJbMUrXEAZCOQ0VNJgmcT2VOKPRl2YGJwgpHpC9CE91Mv4/4UYIUm4chGJaI381ZDq1JUicFii64Hapd8g==", - "engines": { - "node": ">=4" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", - "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", - "dev": true, - "dependencies": { - "is-core-module": "^2.11.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve.exports": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", - "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "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/safe-stable-stringify": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", - "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", - "engines": { - "node": ">=10" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/saslprep": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", - "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", - "optional": true, - "dependencies": { - "sparse-bitfield": "^3.0.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/sax": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", - "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==" - }, - "node_modules/semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/sift": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.1.tgz", - "integrity": "sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ==" - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, - "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/simple-swizzle/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/simple-update-notifier": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", - "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", - "dev": true, - "dependencies": { - "semver": "~7.0.0" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/simple-update-notifier/node_modules/semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/snappy": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/snappy/-/snappy-7.1.1.tgz", - "integrity": "sha512-mL7GGPJ+WdsaFT5aR/uEqCq8cPg2VbhyifDEP7AeqIVDsAC8LBGYbZP1Qzoa2Ym84OW7JEQXqIpwqFp1EQw5BA==", - "optional": true, - "engines": { - "node": ">= 10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" - }, - "optionalDependencies": { - "@napi-rs/snappy-android-arm-eabi": "7.1.1", - "@napi-rs/snappy-android-arm64": "7.1.1", - "@napi-rs/snappy-darwin-arm64": "7.1.1", - "@napi-rs/snappy-darwin-x64": "7.1.1", - "@napi-rs/snappy-freebsd-x64": "7.1.1", - "@napi-rs/snappy-linux-arm-gnueabihf": "7.1.1", - "@napi-rs/snappy-linux-arm64-gnu": "7.1.1", - "@napi-rs/snappy-linux-arm64-musl": "7.1.1", - "@napi-rs/snappy-linux-x64-gnu": "7.1.1", - "@napi-rs/snappy-linux-x64-musl": "7.1.1", - "@napi-rs/snappy-win32-arm64-msvc": "7.1.1", - "@napi-rs/snappy-win32-ia32-msvc": "7.1.1", - "@napi-rs/snappy-win32-x64-msvc": "7.1.1" - } - }, - "node_modules/socks": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", - "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", - "dependencies": { - "ip": "^2.0.0", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.13.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/sparse-bitfield": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", - "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", - "optional": true, - "dependencies": { - "memory-pager": "^1.0.2" - } - }, - "node_modules/split-on-first": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", - "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "node_modules/stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", - "engines": { - "node": "*" - } - }, - "node_modules/stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "engines": { - "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", - "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/stripe": { - "version": "10.17.0", - "resolved": "https://registry.npmjs.org/stripe/-/stripe-10.17.0.tgz", - "integrity": "sha512-JHV2KoL+nMQRXu3m9ervCZZvi4DDCJfzHUE6CmtJxR9TmizyYfrVuhGvnsZLLnheby9Qrnf4Hq6iOEcejGwnGQ==", - "dependencies": { - "@types/node": ">=8.1.0", - "qs": "^6.11.0" - }, - "engines": { - "node": "^8.1 || >=10.*" - } - }, - "node_modules/strnum": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" - }, - "node_modules/superagent": { - "version": "8.0.9", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.0.9.tgz", - "integrity": "sha512-4C7Bh5pyHTvU33KpZgwrNKh/VQnvgtCSqPRfJAUdmrtSYePVzVg4E4OzsrbkhJj9O7SO6Bnv75K/F8XVZT8YHA==", - "dev": true, - "dependencies": { - "component-emitter": "^1.3.0", - "cookiejar": "^2.1.4", - "debug": "^4.3.4", - "fast-safe-stringify": "^2.1.1", - "form-data": "^4.0.0", - "formidable": "^2.1.2", - "methods": "^1.1.2", - "mime": "2.6.0", - "qs": "^6.11.0", - "semver": "^7.3.8" - }, - "engines": { - "node": ">=6.4.0 <13 || >=14" - } - }, - "node_modules/superagent/node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/supertest": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/supertest/-/supertest-6.3.3.tgz", - "integrity": "sha512-EMCG6G8gDu5qEqRQ3JjjPs6+FYT1a7Hv5ApHvtSghmOFJYtsU5S+pSb6Y2EUeCEY3CmEL3mmQ8YWlPOzQomabA==", - "dev": true, - "dependencies": { - "methods": "^1.1.2", - "superagent": "^8.0.5" - }, - "engines": { - "node": ">=6.4.0" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/swagger-autogen": { - "version": "2.23.1", - "resolved": "https://registry.npmjs.org/swagger-autogen/-/swagger-autogen-2.23.1.tgz", - "integrity": "sha512-tOAb5cOGNPduIHKoOxndCRy2Mrg7xV3O1RerrWExrDxeSTjXhA350pyJd7VUDY6ZO9gbZ34Bjlc5CXkleUgvAQ==", - "dependencies": { - "acorn": "^7.4.1", - "deepmerge": "^4.2.2", - "glob": "^7.1.7", - "json5": "^2.2.3" - } - }, - "node_modules/swagger-autogen/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/swagger-ui-dist": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.19.0.tgz", - "integrity": "sha512-9C9fJGI18gK5AhaU5YRyPY1lXJH4lmWh8h9zFMrJBkYzdRjCbAzYl1ayWPYgwFvag/Luqi3Co599OK/39IS2QQ==" - }, - "node_modules/swagger-ui-express": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-4.6.3.tgz", - "integrity": "sha512-CDje4PndhTD2HkgyKH3pab+LKspDeB/NhPN2OF1j+piYIamQqBYwAXWESOT1Yju2xFg51bRW9sUng2WxDjzArw==", - "dependencies": { - "swagger-ui-dist": ">=4.11.0" - }, - "engines": { - "node": ">= v0.10.32" - }, - "peerDependencies": { - "express": ">=4.0.0 || >=5.0.0-beta" - } - }, - "node_modules/tar": { - "version": "6.1.15", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", - "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tar/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-hex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/tiny-lru": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/tiny-lru/-/tiny-lru-11.0.1.tgz", - "integrity": "sha512-iNgFugVuQgBKrqeO/mpiTTgmBsTP0WL6yeuLfLs/Ctf0pI/ixGqIRm8sDCwMcXGe9WWvt2sGXI5mNqZbValmJg==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/touch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", - "dev": true, - "dependencies": { - "nopt": "~1.0.10" - }, - "bin": { - "nodetouch": "bin/nodetouch.js" - } - }, - "node_modules/touch/node_modules/nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", - "dev": true, - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tr46": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", - "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/triple-beam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", - "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" - }, - "node_modules/ts-jest": { - "version": "29.1.0", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.0.tgz", - "integrity": "sha512-ZhNr7Z4PcYa+JjMl62ir+zPiNJfXJN6E8hSLnaUKhOgqcn8vb3e537cpkd0FuAfRK3sR1LSqM1MOhliXNgOFPA==", - "dev": true, - "dependencies": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^29.0.0", - "json5": "^2.2.3", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "^21.0.1" - }, - "bin": { - "ts-jest": "cli.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": ">=7.0.0-beta.0 <8", - "@jest/types": "^29.0.0", - "babel-jest": "^29.0.0", - "jest": "^29.0.0", - "typescript": ">=4.3 <6" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "@jest/types": { - "optional": true - }, - "babel-jest": { - "optional": true - }, - "esbuild": { - "optional": true - } - } - }, - "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/tslib": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.2.tgz", - "integrity": "sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA==" - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, - "node_modules/tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" - }, - "node_modules/twostep": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/twostep/-/twostep-0.4.2.tgz", - "integrity": "sha512-O/wdPYk9ey04qcCiw8AQN74DbvLFZLAgnryrNTpV7T/sxB4lcGkCMHynx5xCcA6fCh739ZAqp3HcGhy770X1qA==" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/uglify-js": { - "version": "3.17.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", - "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/uid2": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.4.tgz", - "integrity": "sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==" - }, - "node_modules/undefsafe": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", - "dev": true - }, - "node_modules/underscore": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", - "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==" - }, - "node_modules/universal-user-agent": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", - "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", - "integrity": "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==", - "dependencies": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - }, - "node_modules/url/node_modules/punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" - }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/utility-types": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz", - "integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/v8-compile-cache-lib": { - "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 - }, - "node_modules/v8-to-istanbul": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", - "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/v8-to-istanbul/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "node_modules/validator": { - "version": "13.9.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.9.0.tgz", - "integrity": "sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "engines": { - "node": ">=12" - } - }, - "node_modules/whatwg-url": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", - "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", - "dependencies": { - "tr46": "^3.0.0", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "node_modules/winston": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.9.0.tgz", - "integrity": "sha512-jW51iW/X95BCW6MMtZWr2jKQBP4hV5bIDq9QrIjfDk6Q9QuxvTKEAlpUNAzP+HYHFFCeENhph16s0zEunu4uuQ==", - "dependencies": { - "@colors/colors": "1.5.0", - "@dabh/diagnostics": "^2.0.2", - "async": "^3.2.3", - "is-stream": "^2.0.0", - "logform": "^2.4.0", - "one-time": "^1.0.0", - "readable-stream": "^3.4.0", - "safe-stable-stringify": "^2.3.1", - "stack-trace": "0.0.x", - "triple-beam": "^1.3.0", - "winston-transport": "^4.5.0" - }, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/winston-loki": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/winston-loki/-/winston-loki-6.0.6.tgz", - "integrity": "sha512-cll+nv5T/b9uJXqca0N2WKL1JJNuJND9E6WOOAuSGkZ44L9VQ/QK9F+/5VKbv6LIP9p0nvPSOYxtACCDb/9iWw==", - "dependencies": { - "async-exit-hook": "2.0.1", - "btoa": "^1.2.1", - "protobufjs": "^6.8.8", - "winston-transport": "^4.3.0" - }, - "optionalDependencies": { - "snappy": "7.1.1" - } - }, - "node_modules/winston-transport": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.5.0.tgz", - "integrity": "sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==", - "dependencies": { - "logform": "^2.3.2", - "readable-stream": "^3.6.0", - "triple-beam": "^1.3.0" - }, - "engines": { - "node": ">= 6.4.0" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "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==" - }, - "node_modules/write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/xml": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", - "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==", - "dev": true - }, - "node_modules/xml2js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", - "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - }, "dependencies": { "@ampproject/remapping": { "version": "2.2.1", @@ -14475,8 +2028,7 @@ "@octokit/plugin-request-log": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", - "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", - "requires": {} + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==" }, "@octokit/plugin-rest-endpoint-methods": { "version": "7.1.2", @@ -15226,8 +2778,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} + "dev": true }, "acorn-walk": { "version": "8.2.0", @@ -16291,6 +3842,21 @@ } } }, + "eslint-plugin-unused-imports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-2.0.0.tgz", + "integrity": "sha512-3APeS/tQlTrFa167ThtP0Zm0vctjr4M44HMpeg1P4bK6wItarumq0Ma82xorMKdFsWpphQBlRPzw/pxiVELX1A==", + "dev": true, + "requires": { + "eslint-rule-composer": "^0.3.0" + } + }, + "eslint-rule-composer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz", + "integrity": "sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==", + "dev": true + }, "eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -16477,14 +4043,12 @@ "express-async-errors": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/express-async-errors/-/express-async-errors-3.1.1.tgz", - "integrity": "sha512-h6aK1da4tpqWSbyCa3FxB/V6Ehd4EEB15zyQq9qe75OZBp0krinNKuH4rAY+S/U/2I36vdLAUFSjQJ+TFmODng==", - "requires": {} + "integrity": "sha512-h6aK1da4tpqWSbyCa3FxB/V6Ehd4EEB15zyQq9qe75OZBp0krinNKuH4rAY+S/U/2I36vdLAUFSjQJ+TFmODng==" }, "express-rate-limit": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-6.7.0.tgz", - "integrity": "sha512-vhwIdRoqcYB/72TK3tRZI+0ttS8Ytrk24GfmsxDXK9o9IhHNO5bXRiXQSExPQ4GbaE5tvIS7j1SGrxsuWs+sGA==", - "requires": {} + "integrity": "sha512-vhwIdRoqcYB/72TK3tRZI+0ttS8Ytrk24GfmsxDXK9o9IhHNO5bXRiXQSExPQ4GbaE5tvIS7j1SGrxsuWs+sGA==" }, "express-validator": { "version": "6.15.0", @@ -17504,8 +5068,7 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "dev": true, - "requires": {} + "dev": true }, "jest-regex-util": { "version": "29.4.3", @@ -17903,11 +5466,6 @@ "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" }, - "lru_map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", - "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==" - }, "lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -17917,6 +5475,11 @@ "yallist": "^3.0.2" } }, + "lru_map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", + "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==" + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -19942,14 +7505,6 @@ "minipass": "^3.1.1" } }, - "string_decoder": { - "version": "1.3.0", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, "string-width": { "version": "4.2.3", "bundled": true, @@ -19960,6 +7515,14 @@ "strip-ansi": "^6.0.1" } }, + "string_decoder": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, "strip-ansi": { "version": "6.0.1", "bundled": true, @@ -20995,14 +8558,6 @@ "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==" }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, "string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -21023,6 +8578,14 @@ "strip-ansi": "^6.0.1" } }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", diff --git a/backend/package.json b/backend/package.json index 6d855001ed..b65fe13aa2 100644 --- a/backend/package.json +++ b/backend/package.json @@ -99,6 +99,7 @@ "@typescript-eslint/parser": "^5.40.1", "cross-env": "^7.0.3", "eslint": "^8.26.0", + "eslint-plugin-unused-imports": "^2.0.0", "install": "^0.13.0", "jest": "^29.3.1", "jest-junit": "^15.0.0", diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index 4613a05c91..62638859ac 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -1,93 +1,93 @@ -import InfisicalClient from 'infisical-node'; +import InfisicalClient from "infisical-node"; export const client = new InfisicalClient({ - token: process.env.INFISICAL_TOKEN! + token: process.env.INFISICAL_TOKEN!, }); -export const getPort = async () => (await client.getSecret('PORT')).secretValue || 4000; +export const getPort = async () => (await client.getSecret("PORT")).secretValue || 4000; export const getEncryptionKey = async () => { - const secretValue = (await client.getSecret('ENCRYPTION_KEY')).secretValue; - return secretValue === '' ? undefined : secretValue; + const secretValue = (await client.getSecret("ENCRYPTION_KEY")).secretValue; + return secretValue === "" ? undefined : secretValue; } export const getRootEncryptionKey = async () => { - const secretValue = (await client.getSecret('ROOT_ENCRYPTION_KEY')).secretValue; - return secretValue === '' ? undefined : secretValue; + const secretValue = (await client.getSecret("ROOT_ENCRYPTION_KEY")).secretValue; + return secretValue === "" ? undefined : secretValue; } -export const getInviteOnlySignup = async () => (await client.getSecret('INVITE_ONLY_SIGNUP')).secretValue === 'true' -export const getSaltRounds = async () => parseInt((await client.getSecret('SALT_ROUNDS')).secretValue) || 10; -export const getJwtAuthLifetime = async () => (await client.getSecret('JWT_AUTH_LIFETIME')).secretValue || '10d'; -export const getJwtAuthSecret = async () => (await client.getSecret('JWT_AUTH_SECRET')).secretValue; -export const getJwtMfaLifetime = async () => (await client.getSecret('JWT_MFA_LIFETIME')).secretValue || '5m'; -export const getJwtMfaSecret = async () => (await client.getSecret('JWT_MFA_LIFETIME')).secretValue || '5m'; -export const getJwtRefreshLifetime = async () => (await client.getSecret('JWT_REFRESH_LIFETIME')).secretValue || '90d'; -export const getJwtRefreshSecret = async () => (await client.getSecret('JWT_REFRESH_SECRET')).secretValue; -export const getJwtServiceSecret = async () => (await client.getSecret('JWT_SERVICE_SECRET')).secretValue; -export const getJwtSignupLifetime = async () => (await client.getSecret('JWT_SIGNUP_LIFETIME')).secretValue || '15m'; -export const getJwtProviderAuthSecret = async () => (await client.getSecret('JWT_PROVIDER_AUTH_SECRET')).secretValue; -export const getJwtProviderAuthLifetime = async () => (await client.getSecret('JWT_PROVIDER_AUTH_LIFETIME')).secretValue || '15m'; -export const getJwtSignupSecret = async () => (await client.getSecret('JWT_SIGNUP_SECRET')).secretValue; -export const getMongoURL = async () => (await client.getSecret('MONGO_URL')).secretValue; -export const getNodeEnv = async () => (await client.getSecret('NODE_ENV')).secretValue || 'production'; -export const getVerboseErrorOutput = async () => (await client.getSecret('VERBOSE_ERROR_OUTPUT')).secretValue === 'true' && true; -export const getLokiHost = async () => (await client.getSecret('LOKI_HOST')).secretValue; -export const getClientIdAzure = async () => (await client.getSecret('CLIENT_ID_AZURE')).secretValue; -export const getClientIdHeroku = async () => (await client.getSecret('CLIENT_ID_HEROKU')).secretValue; -export const getClientIdVercel = async () => (await client.getSecret('CLIENT_ID_VERCEL')).secretValue; -export const getClientIdNetlify = async () => (await client.getSecret('CLIENT_ID_NETLIFY')).secretValue; -export const getClientIdGitHub = async () => (await client.getSecret('CLIENT_ID_GITHUB')).secretValue; -export const getClientIdGitLab = async () => (await client.getSecret('CLIENT_ID_GITLAB')).secretValue; -export const getClientIdGoogle = async () => (await client.getSecret('CLIENT_ID_GOOGLE')).secretValue; -export const getClientSecretAzure = async () => (await client.getSecret('CLIENT_SECRET_AZURE')).secretValue; -export const getClientSecretHeroku = async () => (await client.getSecret('CLIENT_SECRET_HEROKU')).secretValue; -export const getClientSecretVercel = async () => (await client.getSecret('CLIENT_SECRET_VERCEL')).secretValue; -export const getClientSecretNetlify = async () => (await client.getSecret('CLIENT_SECRET_NETLIFY')).secretValue; -export const getClientSecretGitHub = async () => (await client.getSecret('CLIENT_SECRET_GITHUB')).secretValue; -export const getClientSecretGitLab = async () => (await client.getSecret('CLIENT_SECRET_GITLAB')).secretValue; -export const getClientSecretGoogle = async () => (await client.getSecret('CLIENT_SECRET_GOOGLE')).secretValue; -export const getClientSlugVercel = async () => (await client.getSecret('CLIENT_SLUG_VERCEL')).secretValue; -export const getPostHogHost = async () => (await client.getSecret('POSTHOG_HOST')).secretValue || 'https://app.posthog.com'; -export const getPostHogProjectApiKey = async () => (await client.getSecret('POSTHOG_PROJECT_API_KEY')).secretValue || 'phc_nSin8j5q2zdhpFDI1ETmFNUIuTG4DwKVyIigrY10XiE'; -export const getSentryDSN = async () => (await client.getSecret('SENTRY_DSN')).secretValue; -export const getSiteURL = async () => (await client.getSecret('SITE_URL')).secretValue; -export const getSmtpHost = async () => (await client.getSecret('SMTP_HOST')).secretValue; -export const getSmtpSecure = async () => (await client.getSecret('SMTP_SECURE')).secretValue === 'true' || false; -export const getSmtpPort = async () => parseInt((await client.getSecret('SMTP_PORT')).secretValue) || 587; -export const getSmtpUsername = async () => (await client.getSecret('SMTP_USERNAME')).secretValue; -export const getSmtpPassword = async () => (await client.getSecret('SMTP_PASSWORD')).secretValue; -export const getSmtpFromAddress = async () => (await client.getSecret('SMTP_FROM_ADDRESS')).secretValue; -export const getSmtpFromName = async () => (await client.getSecret('SMTP_FROM_NAME')).secretValue || 'Infisical'; +export const getInviteOnlySignup = async () => (await client.getSecret("INVITE_ONLY_SIGNUP")).secretValue === "true" +export const getSaltRounds = async () => parseInt((await client.getSecret("SALT_ROUNDS")).secretValue) || 10; +export const getJwtAuthLifetime = async () => (await client.getSecret("JWT_AUTH_LIFETIME")).secretValue || "10d"; +export const getJwtAuthSecret = async () => (await client.getSecret("JWT_AUTH_SECRET")).secretValue; +export const getJwtMfaLifetime = async () => (await client.getSecret("JWT_MFA_LIFETIME")).secretValue || "5m"; +export const getJwtMfaSecret = async () => (await client.getSecret("JWT_MFA_LIFETIME")).secretValue || "5m"; +export const getJwtRefreshLifetime = async () => (await client.getSecret("JWT_REFRESH_LIFETIME")).secretValue || "90d"; +export const getJwtRefreshSecret = async () => (await client.getSecret("JWT_REFRESH_SECRET")).secretValue; +export const getJwtServiceSecret = async () => (await client.getSecret("JWT_SERVICE_SECRET")).secretValue; +export const getJwtSignupLifetime = async () => (await client.getSecret("JWT_SIGNUP_LIFETIME")).secretValue || "15m"; +export const getJwtProviderAuthSecret = async () => (await client.getSecret("JWT_PROVIDER_AUTH_SECRET")).secretValue; +export const getJwtProviderAuthLifetime = async () => (await client.getSecret("JWT_PROVIDER_AUTH_LIFETIME")).secretValue || "15m"; +export const getJwtSignupSecret = async () => (await client.getSecret("JWT_SIGNUP_SECRET")).secretValue; +export const getMongoURL = async () => (await client.getSecret("MONGO_URL")).secretValue; +export const getNodeEnv = async () => (await client.getSecret("NODE_ENV")).secretValue || "production"; +export const getVerboseErrorOutput = async () => (await client.getSecret("VERBOSE_ERROR_OUTPUT")).secretValue === "true" && true; +export const getLokiHost = async () => (await client.getSecret("LOKI_HOST")).secretValue; +export const getClientIdAzure = async () => (await client.getSecret("CLIENT_ID_AZURE")).secretValue; +export const getClientIdHeroku = async () => (await client.getSecret("CLIENT_ID_HEROKU")).secretValue; +export const getClientIdVercel = async () => (await client.getSecret("CLIENT_ID_VERCEL")).secretValue; +export const getClientIdNetlify = async () => (await client.getSecret("CLIENT_ID_NETLIFY")).secretValue; +export const getClientIdGitHub = async () => (await client.getSecret("CLIENT_ID_GITHUB")).secretValue; +export const getClientIdGitLab = async () => (await client.getSecret("CLIENT_ID_GITLAB")).secretValue; +export const getClientIdGoogle = async () => (await client.getSecret("CLIENT_ID_GOOGLE")).secretValue; +export const getClientSecretAzure = async () => (await client.getSecret("CLIENT_SECRET_AZURE")).secretValue; +export const getClientSecretHeroku = async () => (await client.getSecret("CLIENT_SECRET_HEROKU")).secretValue; +export const getClientSecretVercel = async () => (await client.getSecret("CLIENT_SECRET_VERCEL")).secretValue; +export const getClientSecretNetlify = async () => (await client.getSecret("CLIENT_SECRET_NETLIFY")).secretValue; +export const getClientSecretGitHub = async () => (await client.getSecret("CLIENT_SECRET_GITHUB")).secretValue; +export const getClientSecretGitLab = async () => (await client.getSecret("CLIENT_SECRET_GITLAB")).secretValue; +export const getClientSecretGoogle = async () => (await client.getSecret("CLIENT_SECRET_GOOGLE")).secretValue; +export const getClientSlugVercel = async () => (await client.getSecret("CLIENT_SLUG_VERCEL")).secretValue; +export const getPostHogHost = async () => (await client.getSecret("POSTHOG_HOST")).secretValue || "https://app.posthog.com"; +export const getPostHogProjectApiKey = async () => (await client.getSecret("POSTHOG_PROJECT_API_KEY")).secretValue || "phc_nSin8j5q2zdhpFDI1ETmFNUIuTG4DwKVyIigrY10XiE"; +export const getSentryDSN = async () => (await client.getSecret("SENTRY_DSN")).secretValue; +export const getSiteURL = async () => (await client.getSecret("SITE_URL")).secretValue; +export const getSmtpHost = async () => (await client.getSecret("SMTP_HOST")).secretValue; +export const getSmtpSecure = async () => (await client.getSecret("SMTP_SECURE")).secretValue === "true" || false; +export const getSmtpPort = async () => parseInt((await client.getSecret("SMTP_PORT")).secretValue) || 587; +export const getSmtpUsername = async () => (await client.getSecret("SMTP_USERNAME")).secretValue; +export const getSmtpPassword = async () => (await client.getSecret("SMTP_PASSWORD")).secretValue; +export const getSmtpFromAddress = async () => (await client.getSecret("SMTP_FROM_ADDRESS")).secretValue; +export const getSmtpFromName = async () => (await client.getSecret("SMTP_FROM_NAME")).secretValue || "Infisical"; export const getLicenseKey = async () => { - const secretValue = (await client.getSecret('LICENSE_KEY')).secretValue; - return secretValue === '' ? undefined : secretValue; + const secretValue = (await client.getSecret("LICENSE_KEY")).secretValue; + return secretValue === "" ? undefined : secretValue; } export const getLicenseServerKey = async () => { - const secretValue = (await client.getSecret('LICENSE_SERVER_KEY')).secretValue; - return secretValue === '' ? undefined : secretValue; + const secretValue = (await client.getSecret("LICENSE_SERVER_KEY")).secretValue; + return secretValue === "" ? undefined : secretValue; } -export const getLicenseServerUrl = async () => (await client.getSecret('LICENSE_SERVER_URL')).secretValue || 'https://portal.infisical.com'; +export const getLicenseServerUrl = async () => (await client.getSecret("LICENSE_SERVER_URL")).secretValue || "https://portal.infisical.com"; // TODO: deprecate from here -export const getStripeProductStarter = async () => (await client.getSecret('STRIPE_PRODUCT_STARTER')).secretValue; -export const getStripeProductPro = async () => (await client.getSecret('STRIPE_PRODUCT_PRO')).secretValue; -export const getStripeProductTeam = async () => (await client.getSecret('STRIPE_PRODUCT_TEAM')).secretValue; -export const getStripePublishableKey = async () => (await client.getSecret('STRIPE_PUBLISHABLE_KEY')).secretValue; -export const getStripeSecretKey = async () => (await client.getSecret('STRIPE_SECRET_KEY')).secretValue; -export const getStripeWebhookSecret = async () => (await client.getSecret('STRIPE_WEBHOOK_SECRET')).secretValue; +export const getStripeProductStarter = async () => (await client.getSecret("STRIPE_PRODUCT_STARTER")).secretValue; +export const getStripeProductPro = async () => (await client.getSecret("STRIPE_PRODUCT_PRO")).secretValue; +export const getStripeProductTeam = async () => (await client.getSecret("STRIPE_PRODUCT_TEAM")).secretValue; +export const getStripePublishableKey = async () => (await client.getSecret("STRIPE_PUBLISHABLE_KEY")).secretValue; +export const getStripeSecretKey = async () => (await client.getSecret("STRIPE_SECRET_KEY")).secretValue; +export const getStripeWebhookSecret = async () => (await client.getSecret("STRIPE_WEBHOOK_SECRET")).secretValue; -export const getTelemetryEnabled = async () => (await client.getSecret('TELEMETRY_ENABLED')).secretValue !== 'false' && true; -export const getLoopsApiKey = async () => (await client.getSecret('LOOPS_API_KEY')).secretValue; -export const getSmtpConfigured = async () => (await client.getSecret('SMTP_HOST')).secretValue == '' || (await client.getSecret('SMTP_HOST')).secretValue == undefined ? false : true +export const getTelemetryEnabled = async () => (await client.getSecret("TELEMETRY_ENABLED")).secretValue !== "false" && true; +export const getLoopsApiKey = async () => (await client.getSecret("LOOPS_API_KEY")).secretValue; +export const getSmtpConfigured = async () => (await client.getSecret("SMTP_HOST")).secretValue == "" || (await client.getSecret("SMTP_HOST")).secretValue == undefined ? false : true export const getHttpsEnabled = async () => { if ((await getNodeEnv()) != "production") { // no https for anything other than prod return false } - if ((await client.getSecret('HTTPS_ENABLED')).secretValue == undefined || (await client.getSecret('HTTPS_ENABLED')).secretValue == "") { + if ((await client.getSecret("HTTPS_ENABLED")).secretValue == undefined || (await client.getSecret("HTTPS_ENABLED")).secretValue == "") { // default when no value present return true } - return (await client.getSecret('HTTPS_ENABLED')).secretValue === 'true' && true + return (await client.getSecret("HTTPS_ENABLED")).secretValue === "true" && true } \ No newline at end of file diff --git a/backend/src/config/request.ts b/backend/src/config/request.ts index e134696579..e69b1baff5 100644 --- a/backend/src/config/request.ts +++ b/backend/src/config/request.ts @@ -1,16 +1,16 @@ -import axios from 'axios'; -import axiosRetry from 'axios-retry'; +import axios from "axios"; +import axiosRetry from "axios-retry"; import { - getLicenseServerKeyAuthToken, - setLicenseServerKeyAuthToken, getLicenseKeyAuthToken, - setLicenseKeyAuthToken -} from './storage'; + getLicenseServerKeyAuthToken, + setLicenseKeyAuthToken, + setLicenseServerKeyAuthToken, +} from "./storage"; import { getLicenseKey, getLicenseServerKey, - getLicenseServerUrl -} from './index'; + getLicenseServerUrl, +} from "./index"; // should have JWT to interact with the license server export const licenseServerKeyRequest = axios.create(); @@ -35,8 +35,8 @@ export const refreshLicenseServerKeyToken = async () => { `${licenseServerUrl}/api/auth/v1/license-server-login`, {}, { headers: { - 'X-API-KEY': licenseServerKey - } + "X-API-KEY": licenseServerKey, + }, } ); @@ -53,8 +53,8 @@ export const refreshLicenseKeyToken = async () => { `${licenseServerUrl}/api/auth/v1/license-login`, {}, { headers: { - 'X-API-KEY': licenseKey - } + "X-API-KEY": licenseKey, + }, } ); @@ -86,7 +86,7 @@ licenseServerKeyRequest.interceptors.response.use((response) => { // refresh const token = await refreshLicenseServerKeyToken(); - axios.defaults.headers.common['Authorization'] = 'Bearer ' + token; + axios.defaults.headers.common["Authorization"] = "Bearer " + token; return licenseServerKeyRequest(originalRequest); } @@ -116,7 +116,7 @@ licenseKeyRequest.interceptors.response.use((response) => { // refresh const token = await refreshLicenseKeyToken(); - axios.defaults.headers.common['Authorization'] = 'Bearer ' + token; + axios.defaults.headers.common["Authorization"] = "Bearer " + token; return licenseKeyRequest(originalRequest); } diff --git a/backend/src/config/storage.ts b/backend/src/config/storage.ts index 5638561ac0..f3cf271967 100644 --- a/backend/src/config/storage.ts +++ b/backend/src/config/storage.ts @@ -5,7 +5,7 @@ const MemoryLicenseServerKeyTokenStorage = () => { setToken: (token: string) => { authToken = token; }, - getToken: () => authToken + getToken: () => authToken, }; }; @@ -16,7 +16,7 @@ const MemoryLicenseKeyTokenStorage = () => { setToken: (token: string) => { authToken = token; }, - getToken: () => authToken + getToken: () => authToken, }; }; diff --git a/backend/src/controllers/v1/authController.ts b/backend/src/controllers/v1/authController.ts index 8a70e016ed..311d9602d4 100644 --- a/backend/src/controllers/v1/authController.ts +++ b/backend/src/controllers/v1/authController.ts @@ -1,36 +1,36 @@ -import { Request, Response } from 'express'; -import fs from 'fs'; -import path from 'path'; -import jwt from 'jsonwebtoken'; -import * as bigintConversion from 'bigint-conversion'; +import { Request, Response } from "express"; +import fs from "fs"; +import path from "path"; +import jwt from "jsonwebtoken"; +import * as bigintConversion from "bigint-conversion"; // eslint-disable-next-line @typescript-eslint/no-var-requires -const jsrp = require('jsrp'); +const jsrp = require("jsrp"); import { - User, - LoginSRPDetail, - TokenVersion -} from '../../models'; -import { createToken, issueAuthTokens, clearTokens } from '../../helpers/auth'; -import { checkUserDevice } from '../../helpers/user'; + LoginSRPDetail, + TokenVersion, + User, +} from "../../models"; +import { clearTokens, createToken, issueAuthTokens } from "../../helpers/auth"; +import { checkUserDevice } from "../../helpers/user"; import { ACTION_LOGIN, ACTION_LOGOUT, - AUTH_MODE_JWT -} from '../../variables'; + AUTH_MODE_JWT, +} from "../../variables"; import { BadRequestError, - UnauthorizedRequestError -} from '../../utils/errors'; -import { EELogService } from '../../ee/services'; -import { getChannelFromUserAgent } from '../../utils/posthog'; + UnauthorizedRequestError, +} from "../../utils/errors"; +import { EELogService } from "../../ee/services"; +import { getChannelFromUserAgent } from "../../utils/posthog"; import { - getJwtRefreshSecret, + getHttpsEnabled, getJwtAuthLifetime, getJwtAuthSecret, - getHttpsEnabled -} from '../../config'; + getJwtRefreshSecret, +} from "../../config"; -declare module 'jsonwebtoken' { +declare module "jsonwebtoken" { export interface UserIDJwtPayload extends jwt.JwtPayload { userId: string; refreshVersion?: number; @@ -46,20 +46,20 @@ declare module 'jsonwebtoken' { export const login1 = async (req: Request, res: Response) => { const { email, - clientPublicKey + clientPublicKey, }: { email: string; clientPublicKey: string } = req.body; const user = await User.findOne({ - email - }).select('+salt +verifier'); + email, + }).select("+salt +verifier"); - if (!user) throw new Error('Failed to find user'); + if (!user) throw new Error("Failed to find user"); const server = new jsrp.server(); server.init( { salt: user.salt, - verifier: user.verifier + verifier: user.verifier, }, async () => { // generate server-side public key @@ -73,7 +73,7 @@ export const login1 = async (req: Request, res: Response) => { return res.status(200).send({ serverPublicKey, - salt: user.salt + salt: user.salt, }); } ); @@ -89,10 +89,10 @@ export const login1 = async (req: Request, res: Response) => { export const login2 = async (req: Request, res: Response) => { const { email, clientProof } = req.body; const user = await User.findOne({ - email - }).select('+salt +verifier +publicKey +encryptedPrivateKey +iv +tag'); + email, + }).select("+salt +verifier +publicKey +encryptedPrivateKey +iv +tag"); - if (!user) throw new Error('Failed to find user'); + if (!user) throw new Error("Failed to find user"); const loginSRPDetailFromDB = await LoginSRPDetail.findOneAndDelete({ email: email }) @@ -105,7 +105,7 @@ export const login2 = async (req: Request, res: Response) => { { salt: user.salt, verifier: user.verifier, - b: loginSRPDetailFromDB.serverBInt + b: loginSRPDetailFromDB.serverBInt, }, async () => { server.setClientPublicKey(loginSRPDetailFromDB.clientPublicKey); @@ -117,33 +117,33 @@ export const login2 = async (req: Request, res: Response) => { await checkUserDevice({ user, ip: req.realIP, - userAgent: req.headers['user-agent'] ?? '' + userAgent: req.headers["user-agent"] ?? "", }); const tokens = await issueAuthTokens({ userId: user._id, ip: req.realIP, - userAgent: req.headers['user-agent'] ?? '' + userAgent: req.headers["user-agent"] ?? "", }); // store (refresh) token in httpOnly cookie - res.cookie('jid', tokens.refreshToken, { + res.cookie("jid", tokens.refreshToken, { httpOnly: true, - path: '/', - sameSite: 'strict', - secure: await getHttpsEnabled() + path: "/", + sameSite: "strict", + secure: await getHttpsEnabled(), }); const loginAction = await EELogService.createAction({ name: ACTION_LOGIN, - userId: user._id + userId: user._id, }); loginAction && await EELogService.createLog({ userId: user._id, actions: [loginAction], - channel: getChannelFromUserAgent(req.headers['user-agent']), - ipAddress: req.realIP + channel: getChannelFromUserAgent(req.headers["user-agent"]), + ipAddress: req.realIP, }); // return (access) token in response @@ -152,12 +152,12 @@ export const login2 = async (req: Request, res: Response) => { publicKey: user.publicKey, encryptedPrivateKey: user.encryptedPrivateKey, iv: user.iv, - tag: user.tag + tag: user.tag, }); } return res.status(400).send({ - message: 'Failed to authenticate. Try again?' + message: "Failed to authenticate. Try again?", }); } ); @@ -175,51 +175,51 @@ export const logout = async (req: Request, res: Response) => { } // clear httpOnly cookie - res.cookie('jid', '', { + res.cookie("jid", "", { httpOnly: true, - path: '/', - sameSite: 'strict', - secure: (await getHttpsEnabled()) as boolean + path: "/", + sameSite: "strict", + secure: (await getHttpsEnabled()) as boolean, }); const logoutAction = await EELogService.createAction({ name: ACTION_LOGOUT, - userId: req.user._id + userId: req.user._id, }); logoutAction && await EELogService.createLog({ userId: req.user._id, actions: [logoutAction], - channel: getChannelFromUserAgent(req.headers['user-agent']), - ipAddress: req.realIP + channel: getChannelFromUserAgent(req.headers["user-agent"]), + ipAddress: req.realIP, }); return res.status(200).send({ - message: 'Successfully logged out.' + message: "Successfully logged out.", }); }; export const getCommonPasswords = async (req: Request, res: Response) => { const commonPasswords = fs.readFileSync( - path.resolve(__dirname, '../../data/' + 'common_passwords.txt'), - 'utf8' - ).split('\n'); + path.resolve(__dirname, "../../data/" + "common_passwords.txt"), + "utf8" + ).split("\n"); return res.status(200).send(commonPasswords); } export const revokeAllSessions = async (req: Request, res: Response) => { await TokenVersion.updateMany({ - user: req.user._id + user: req.user._id, }, { $inc: { refreshVersion: 1, - accessVersion: 1 - } + accessVersion: 1, + }, }); return res.status(200).send({ - message: 'Successfully revoked all sessions.' + message: "Successfully revoked all sessions.", }); } @@ -231,7 +231,7 @@ export const revokeAllSessions = async (req: Request, res: Response) => { */ export const checkAuth = async (req: Request, res: Response) => { return res.status(200).send({ - message: 'Authenticated' + message: "Authenticated", }); } @@ -245,7 +245,7 @@ export const getNewToken = async (req: Request, res: Response) => { const refreshToken = req.cookies.jid; if (!refreshToken) { - throw new Error('Failed to find refresh token in request cookies'); + throw new Error("Failed to find refresh token in request cookies"); } const decodedToken = ( @@ -253,35 +253,35 @@ export const getNewToken = async (req: Request, res: Response) => { ); const user = await User.findOne({ - _id: decodedToken.userId - }).select('+publicKey +refreshVersion +accessVersion'); + _id: decodedToken.userId, + }).select("+publicKey +refreshVersion +accessVersion"); - if (!user) throw new Error('Failed to authenticate unfound user'); + if (!user) throw new Error("Failed to authenticate unfound user"); if (!user?.publicKey) - throw new Error('Failed to authenticate not fully set up account'); + throw new Error("Failed to authenticate not fully set up account"); const tokenVersion = await TokenVersion.findById(decodedToken.tokenVersionId); if (!tokenVersion) throw UnauthorizedRequestError({ - message: 'Failed to validate refresh token' + message: "Failed to validate refresh token", }); if (decodedToken.refreshVersion !== tokenVersion.refreshVersion) throw BadRequestError({ - message: 'Failed to validate refresh token' + message: "Failed to validate refresh token", }); const token = createToken({ payload: { userId: decodedToken.userId, tokenVersionId: tokenVersion._id.toString(), - accessVersion: tokenVersion.refreshVersion + accessVersion: tokenVersion.refreshVersion, }, expiresIn: await getJwtAuthLifetime(), - secret: await getJwtAuthSecret() + secret: await getJwtAuthSecret(), }); return res.status(200).send({ - token + token, }); }; diff --git a/backend/src/controllers/v1/botController.ts b/backend/src/controllers/v1/botController.ts index f155f58a5e..b2e7575413 100644 --- a/backend/src/controllers/v1/botController.ts +++ b/backend/src/controllers/v1/botController.ts @@ -1,7 +1,7 @@ -import { Request, Response } from 'express'; -import { Types } from 'mongoose'; -import { Bot, BotKey } from '../../models'; -import { createBot } from '../../helpers/bot'; +import { Request, Response } from "express"; +import { Types } from "mongoose"; +import { Bot, BotKey } from "../../models"; +import { createBot } from "../../helpers/bot"; interface BotKey { encryptedKey: string; @@ -19,20 +19,20 @@ export const getBotByWorkspaceId = async (req: Request, res: Response) => { const { workspaceId } = req.params; let bot = await Bot.findOne({ - workspace: workspaceId + workspace: workspaceId, }); if (!bot) { // case: bot doesn't exist for workspace with id [workspaceId] // -> create a new bot and return it bot = await createBot({ - name: 'Infisical Bot', - workspaceId: new Types.ObjectId(workspaceId) + name: "Infisical Bot", + workspaceId: new Types.ObjectId(workspaceId), }); } return res.status(200).send({ - bot + bot, }); }; @@ -49,40 +49,40 @@ export const setBotActiveState = async (req: Request, res: Response) => { // bot state set to active -> share workspace key with bot if (!botKey?.encryptedKey || !botKey?.nonce) { return res.status(400).send({ - message: 'Failed to set bot state to active - missing bot key' + message: "Failed to set bot state to active - missing bot key", }); } await BotKey.findOneAndUpdate({ - workspace: req.bot.workspace + workspace: req.bot.workspace, }, { encryptedKey: botKey.encryptedKey, nonce: botKey.nonce, sender: req.user._id, bot: req.bot._id, - workspace: req.bot.workspace + workspace: req.bot.workspace, }, { upsert: true, - new: true + new: true, }); } else { // case: bot state set to inactive -> delete bot's workspace key await BotKey.deleteOne({ - bot: req.bot._id + bot: req.bot._id, }); } - let bot = await Bot.findOneAndUpdate({ - _id: req.bot._id + const bot = await Bot.findOneAndUpdate({ + _id: req.bot._id, }, { - isActive + isActive, }, { - new: true + new: true, }); - if (!bot) throw new Error('Failed to update bot active state'); + if (!bot) throw new Error("Failed to update bot active state"); return res.status(200).send({ - bot + bot, }); }; diff --git a/backend/src/controllers/v1/index.ts b/backend/src/controllers/v1/index.ts index 1da61835fc..5f25238951 100644 --- a/backend/src/controllers/v1/index.ts +++ b/backend/src/controllers/v1/index.ts @@ -1,19 +1,19 @@ -import * as authController from './authController'; -import * as botController from './botController'; -import * as integrationAuthController from './integrationAuthController'; -import * as integrationController from './integrationController'; -import * as keyController from './keyController'; -import * as membershipController from './membershipController'; -import * as membershipOrgController from './membershipOrgController'; -import * as organizationController from './organizationController'; -import * as passwordController from './passwordController'; -import * as secretController from './secretController'; -import * as serviceTokenController from './serviceTokenController'; -import * as signupController from './signupController'; -import * as stripeController from './stripeController'; -import * as userActionController from './userActionController'; -import * as userController from './userController'; -import * as workspaceController from './workspaceController'; +import * as authController from "./authController"; +import * as botController from "./botController"; +import * as integrationAuthController from "./integrationAuthController"; +import * as integrationController from "./integrationController"; +import * as keyController from "./keyController"; +import * as membershipController from "./membershipController"; +import * as membershipOrgController from "./membershipOrgController"; +import * as organizationController from "./organizationController"; +import * as passwordController from "./passwordController"; +import * as secretController from "./secretController"; +import * as serviceTokenController from "./serviceTokenController"; +import * as signupController from "./signupController"; +import * as stripeController from "./stripeController"; +import * as userActionController from "./userActionController"; +import * as userController from "./userController"; +import * as workspaceController from "./workspaceController"; export { authController, @@ -31,5 +31,5 @@ export { stripeController, userActionController, userController, - workspaceController + workspaceController, }; diff --git a/backend/src/controllers/v1/integrationAuthController.ts b/backend/src/controllers/v1/integrationAuthController.ts index 394c674464..f625f10a2d 100644 --- a/backend/src/controllers/v1/integrationAuthController.ts +++ b/backend/src/controllers/v1/integrationAuthController.ts @@ -1,21 +1,17 @@ -import { Request, Response } from 'express'; -import { Types } from 'mongoose'; +import { Request, Response } from "express"; +import { Types } from "mongoose"; +import { standardRequest } from "../../config/request"; +import { getApps, getTeams, revokeAccess } from "../../integrations"; +import { Bot, IntegrationAuth } from "../../models"; +import { IntegrationService } from "../../services"; import { - IntegrationAuth, - Bot -} from '../../models'; -import { ALGORITHM_AES_256_GCM, ENCODING_SCHEME_UTF8, INTEGRATION_SET, getIntegrationOptions as getIntegrationOptionsFunc } from '../../variables'; -import { IntegrationService } from '../../services'; -import { - getApps, - getTeams, - revokeAccess -} from '../../integrations'; -import { - INTEGRATION_VERCEL_API_URL, - INTEGRATION_RAILWAY_API_URL -} from '../../variables'; -import { standardRequest } from '../../config/request'; + ALGORITHM_AES_256_GCM, + ENCODING_SCHEME_UTF8, + INTEGRATION_RAILWAY_API_URL, + INTEGRATION_SET, + INTEGRATION_VERCEL_API_URL, + getIntegrationOptions as getIntegrationOptionsFunc +} from "../../variables"; /*** * Return integration authorization with id [integrationAuthId] @@ -23,22 +19,23 @@ import { standardRequest } from '../../config/request'; export const getIntegrationAuth = async (req: Request, res: Response) => { const { integrationAuthId } = req.params; const integrationAuth = await IntegrationAuth.findById(integrationAuthId); - - if (!integrationAuth) return res.status(400).send({ - message: 'Failed to find integration authorization' - }); - return res.status(200).send({ - integrationAuth - }); -} + if (!integrationAuth) + return res.status(400).send({ + message: "Failed to find integration authorization" + }); + + return res.status(200).send({ + integrationAuth + }); +}; export const getIntegrationOptions = async (req: Request, res: Response) => { - const INTEGRATION_OPTIONS = await getIntegrationOptionsFunc(); + const INTEGRATION_OPTIONS = await getIntegrationOptionsFunc(); - return res.status(200).send({ - integrationOptions: INTEGRATION_OPTIONS, - }); + return res.status(200).send({ + integrationOptions: INTEGRATION_OPTIONS + }); }; /** @@ -47,26 +44,22 @@ export const getIntegrationOptions = async (req: Request, res: Response) => { * @param res * @returns */ -export const oAuthExchange = async ( - req: Request, - res: Response -) => { +export const oAuthExchange = async (req: Request, res: Response) => { const { workspaceId, code, integration } = req.body; - if (!INTEGRATION_SET.has(integration)) - throw new Error('Failed to validate integration'); - + if (!INTEGRATION_SET.has(integration)) throw new Error("Failed to validate integration"); + const environments = req.membership.workspace?.environments || []; - if(environments.length === 0){ - throw new Error("Failed to get environments") + if (environments.length === 0) { + throw new Error("Failed to get environments"); } const integrationAuth = await IntegrationService.handleOAuthExchange({ workspaceId, integration, code, - environment: environments[0].slug, + environment: environments[0].slug }); - + return res.status(200).send({ integrationAuth }); @@ -75,69 +68,70 @@ export const oAuthExchange = async ( /** * Save integration access token and (optionally) access id as part of integration * [integration] for workspace with id [workspaceId] - * @param req - * @param res + * @param req + * @param res */ -export const saveIntegrationAccessToken = async ( - req: Request, - res: Response -) => { - // TODO: refactor - // TODO: check if access token is valid for each integration +export const saveIntegrationAccessToken = async (req: Request, res: Response) => { + // TODO: refactor + // TODO: check if access token is valid for each integration - let integrationAuth; - const { - workspaceId, - accessId, - accessToken, - url, - namespace, - integration - }: { - workspaceId: string; - accessId: string | null; - accessToken: string; - url: string; - namespace: string; - integration: string; - } = req.body; + let integrationAuth; + const { + workspaceId, + accessId, + accessToken, + url, + namespace, + integration + }: { + workspaceId: string; + accessId: string | null; + accessToken: string; + url: string; + namespace: string; + integration: string; + } = req.body; - const bot = await Bot.findOne({ - workspace: new Types.ObjectId(workspaceId), - isActive: true - }); - - if (!bot) throw new Error('Bot must be enabled to save integration access token'); + const bot = await Bot.findOne({ + workspace: new Types.ObjectId(workspaceId), + isActive: true + }); - integrationAuth = await IntegrationAuth.findOneAndUpdate({ - workspace: new Types.ObjectId(workspaceId), - integration - }, { - workspace: new Types.ObjectId(workspaceId), - integration, - url, - namespace, - algorithm: ALGORITHM_AES_256_GCM, - keyEncoding: ENCODING_SCHEME_UTF8 - }, { - new: true, - upsert: true - }); - - // encrypt and save integration access details - integrationAuth = await IntegrationService.setIntegrationAuthAccess({ - integrationAuthId: integrationAuth._id.toString(), - accessId, - accessToken, - accessExpiresAt: undefined - }); - - if (!integrationAuth) throw new Error('Failed to save integration access token'); - - return res.status(200).send({ - integrationAuth - }); -} + if (!bot) throw new Error("Bot must be enabled to save integration access token"); + + integrationAuth = await IntegrationAuth.findOneAndUpdate( + { + workspace: new Types.ObjectId(workspaceId), + integration + }, + { + workspace: new Types.ObjectId(workspaceId), + integration, + url, + namespace, + algorithm: ALGORITHM_AES_256_GCM, + keyEncoding: ENCODING_SCHEME_UTF8 + }, + { + new: true, + upsert: true + } + ); + + // encrypt and save integration access details + integrationAuth = await IntegrationService.setIntegrationAuthAccess({ + integrationAuthId: integrationAuth._id.toString(), + accessId, + accessToken, + accessExpiresAt: undefined + }); + + if (!integrationAuth) throw new Error("Failed to save integration access token"); + + return res.status(200).send({ + integrationAuth + }); +}; /** * Return list of applications allowed for integration with integration authorization id [integrationAuthId] @@ -147,108 +141,108 @@ export const saveIntegrationAccessToken = async ( */ export const getIntegrationAuthApps = async (req: Request, res: Response) => { const teamId = req.query.teamId as string; - + const apps = await getApps({ integrationAuth: req.integrationAuth, accessToken: req.accessToken, - accessId: req.accessId, - ...teamId && { teamId } + accessId: req.accessId, + ...(teamId && { teamId }) }); - return res.status(200).send({ - apps - }); + return res.status(200).send({ + apps + }); }; /** * Return list of teams allowed for integration with integration authorization id [integrationAuthId] - * @param req - * @param res - * @returns + * @param req + * @param res + * @returns */ export const getIntegrationAuthTeams = async (req: Request, res: Response) => { - const teams = await getTeams({ - integrationAuth: req.integrationAuth, - accessToken: req.accessToken - }); - - return res.status(200).send({ - teams - }); -} + const teams = await getTeams({ + integrationAuth: req.integrationAuth, + accessToken: req.accessToken + }); + + return res.status(200).send({ + teams + }); +}; /** * Return list of available Vercel (preview) branches for Vercel project with * id [appId] - * @param req - * @param res + * @param req + * @param res */ export const getIntegrationAuthVercelBranches = async (req: Request, res: Response) => { - const { integrationAuthId } = req.params; - const appId = req.query.appId as string; - - interface VercelBranch { - ref: string; - lastCommit: string; - isProtected: boolean; - } + const appId = req.query.appId as string; - const params = new URLSearchParams({ - projectId: appId, - ...(req.integrationAuth.teamId ? { - teamId: req.integrationAuth.teamId - } : {}) - }); + interface VercelBranch { + ref: string; + lastCommit: string; + isProtected: boolean; + } - let branches: string[] = []; - - if (appId && appId !== '') { - const { data }: { data: VercelBranch[] } = await standardRequest.get( - `${INTEGRATION_VERCEL_API_URL}/v1/integrations/git-branches`, - { - params, - headers: { - Authorization: `Bearer ${req.accessToken}`, - 'Accept-Encoding': 'application/json' - } - } - ); - - branches = data.map((b) => b.ref); - } + const params = new URLSearchParams({ + projectId: appId, + ...(req.integrationAuth.teamId + ? { + teamId: req.integrationAuth.teamId + } + : {}) + }); - return res.status(200).send({ - branches - }); -} + let branches: string[] = []; + + if (appId && appId !== "") { + const { data }: { data: VercelBranch[] } = await standardRequest.get( + `${INTEGRATION_VERCEL_API_URL}/v1/integrations/git-branches`, + { + params, + headers: { + Authorization: `Bearer ${req.accessToken}`, + "Accept-Encoding": "application/json" + } + } + ); + + branches = data.map((b) => b.ref); + } + + return res.status(200).send({ + branches + }); +}; /** * Return list of Railway environments for Railway project with * id [appId] - * @param req - * @param res + * @param req + * @param res */ export const getIntegrationAuthRailwayEnvironments = async (req: Request, res: Response) => { - const { integrationAuthId } = req.params; - const appId = req.query.appId as string; - - interface RailwayEnvironment { - node: { - id: string; - name: string; - isEphemeral: boolean; - } - } - - interface Environment { - environmentId: string; - name: string; - } - - let environments: Environment[] = []; + const appId = req.query.appId as string; - if (appId && appId !== '') { - const query = ` + interface RailwayEnvironment { + node: { + id: string; + name: string; + isEphemeral: boolean; + }; + } + + interface Environment { + environmentId: string; + name: string; + } + + let environments: Environment[] = []; + + if (appId && appId !== "") { + const query = ` query GetEnvironments($projectId: String!, $after: String, $before: String, $first: Int, $isEphemeral: Boolean, $last: Int) { environments(projectId: $projectId, after: $after, before: $before, first: $first, isEphemeral: $isEphemeral, last: $last) { edges { @@ -261,59 +255,68 @@ export const getIntegrationAuthRailwayEnvironments = async (req: Request, res: R } } `; - - const variables = { - projectId: appId - } - - const { data: { data: { environments: { edges } } } } = await standardRequest.post(INTEGRATION_RAILWAY_API_URL, { - query, - variables, - }, { - headers: { - 'Authorization': `Bearer ${req.accessToken}`, - 'Content-Type': 'application/json', - }, - }); - - environments = edges.map((e: RailwayEnvironment) => { - return ({ - name: e.node.name, - environmentId: e.node.id - }); - }); - } - - return res.status(200).send({ - environments - }); -} + + const variables = { + projectId: appId + }; + + const { + data: { + data: { + environments: { edges } + } + } + } = await standardRequest.post( + INTEGRATION_RAILWAY_API_URL, + { + query, + variables + }, + { + headers: { + Authorization: `Bearer ${req.accessToken}`, + "Content-Type": "application/json" + } + } + ); + + environments = edges.map((e: RailwayEnvironment) => { + return { + name: e.node.name, + environmentId: e.node.id + }; + }); + } + + return res.status(200).send({ + environments + }); +}; /** * Return list of Railway services for Railway project with id * [appId] - * @param req - * @param res + * @param req + * @param res */ export const getIntegrationAuthRailwayServices = async (req: Request, res: Response) => { - const { integrationAuthId } = req.params; - const appId = req.query.appId as string; - - interface RailwayService { - node: { - id: string; - name: string; - } - } - - interface Service { - name: string; - serviceId: string; - } - - let services: Service[] = []; - - const query = ` + const appId = req.query.appId as string; + + interface RailwayService { + node: { + id: string; + name: string; + }; + } + + interface Service { + name: string; + serviceId: string; + } + + let services: Service[] = []; + + const query = ` query project($id: String!) { project(id: $id) { createdAt @@ -341,31 +344,43 @@ export const getIntegrationAuthRailwayServices = async (req: Request, res: Respo } `; - if (appId && appId !== '') { - const variables = { - id: appId - } - - const { data: { data: { project: { services: { edges } } } } } = await standardRequest.post(INTEGRATION_RAILWAY_API_URL, { - query, - variables - }, { - headers: { - 'Authorization': `Bearer ${req.accessToken}`, - 'Content-Type': 'application/json', - }, - }); - - services = edges.map((e: RailwayService) => ({ - name: e.node.name, - serviceId: e.node.id - })); - } - - return res.status(200).send({ - services - }); -} + if (appId && appId !== "") { + const variables = { + id: appId + }; + + const { + data: { + data: { + project: { + services: { edges } + } + } + } + } = await standardRequest.post( + INTEGRATION_RAILWAY_API_URL, + { + query, + variables + }, + { + headers: { + Authorization: `Bearer ${req.accessToken}`, + "Content-Type": "application/json" + } + } + ); + + services = edges.map((e: RailwayService) => ({ + name: e.node.name, + serviceId: e.node.id + })); + } + + return res.status(200).send({ + services + }); +}; /** * Delete integration authorization with id [integrationAuthId] @@ -376,10 +391,10 @@ export const getIntegrationAuthRailwayServices = async (req: Request, res: Respo export const deleteIntegrationAuth = async (req: Request, res: Response) => { const integrationAuth = await revokeAccess({ integrationAuth: req.integrationAuth, - accessToken: req.accessToken, + accessToken: req.accessToken }); return res.status(200).send({ - integrationAuth, + integrationAuth }); }; diff --git a/backend/src/controllers/v1/keyController.ts b/backend/src/controllers/v1/keyController.ts index beb4d0d073..ed82dfdccd 100644 --- a/backend/src/controllers/v1/keyController.ts +++ b/backend/src/controllers/v1/keyController.ts @@ -1,6 +1,6 @@ -import { Request, Response } from 'express'; -import { Key } from '../../models'; -import { findMembership } from '../../helpers/membership'; +import { Request, Response } from "express"; +import { Key } from "../../models"; +import { findMembership } from "../../helpers/membership"; /** * Add (encrypted) copy of workspace key for workspace with id [workspaceId] for user with @@ -16,11 +16,11 @@ export const uploadKey = async (req: Request, res: Response) => { // validate membership of receiver const receiverMembership = await findMembership({ user: key.userId, - workspace: workspaceId + workspace: workspaceId, }); if (!receiverMembership) { - throw new Error('Failed receiver membership validation for workspace'); + throw new Error("Failed receiver membership validation for workspace"); } await new Key({ @@ -28,11 +28,11 @@ export const uploadKey = async (req: Request, res: Response) => { nonce: key.nonce, sender: req.user._id, receiver: key.userId, - workspace: workspaceId + workspace: workspaceId, }).save(); return res.status(200).send({ - message: 'Successfully uploaded key to workspace' + message: "Successfully uploaded key to workspace", }); }; @@ -48,16 +48,16 @@ export const getLatestKey = async (req: Request, res: Response) => { // get latest key const latestKey = await Key.find({ workspace: workspaceId, - receiver: req.user._id + receiver: req.user._id, }) .sort({ createdAt: -1 }) .limit(1) - .populate('sender', '+publicKey'); + .populate("sender", "+publicKey"); const resObj: any = {}; if (latestKey.length > 0) { - resObj['latestKey'] = latestKey[0]; + resObj["latestKey"] = latestKey[0]; } return res.status(200).send(resObj); diff --git a/backend/src/controllers/v1/membershipController.ts b/backend/src/controllers/v1/membershipController.ts index d7e512adbd..d795bcb607 100644 --- a/backend/src/controllers/v1/membershipController.ts +++ b/backend/src/controllers/v1/membershipController.ts @@ -1,12 +1,9 @@ -import { Request, Response } from 'express'; -import { Membership, MembershipOrg, User, Key } from '../../models'; -import { - findMembership, - deleteMembership as deleteMember -} from '../../helpers/membership'; -import { sendMail } from '../../helpers/nodemailer'; -import { ADMIN, MEMBER, ACCEPTED } from '../../variables'; -import { getSiteURL } from '../../config'; +import { Request, Response } from "express"; +import { Key, Membership, MembershipOrg, User } from "../../models"; +import { deleteMembership as deleteMember, findMembership } from "../../helpers/membership"; +import { sendMail } from "../../helpers/nodemailer"; +import { ACCEPTED, ADMIN, MEMBER } from "../../variables"; +import { getSiteURL } from "../../config"; /** * Check that user is a member of workspace with id [workspaceId] @@ -23,12 +20,12 @@ export const validateMembership = async (req: Request, res: Response) => { }); if (!membership) { - throw new Error('Failed to validate membership'); + throw new Error("Failed to validate membership"); } - return res.status(200).send({ - message: 'Workspace membership confirmed' - }); + return res.status(200).send({ + message: "Workspace membership confirmed" + }); }; /** @@ -43,12 +40,10 @@ export const deleteMembership = async (req: Request, res: Response) => { // check if membership to delete exists const membershipToDelete = await Membership.findOne({ _id: membershipId - }).populate('user'); + }).populate("user"); if (!membershipToDelete) { - throw new Error( - "Failed to delete workspace membership that doesn't exist" - ); + throw new Error("Failed to delete workspace membership that doesn't exist"); } // check if user is a member and admin of the workspace @@ -59,12 +54,12 @@ export const deleteMembership = async (req: Request, res: Response) => { }); if (!membership) { - throw new Error('Failed to validate workspace membership'); + throw new Error("Failed to validate workspace membership"); } if (membership.role !== ADMIN) { // user is not an admin member of the workspace - throw new Error('Insufficient role for deleting workspace membership'); + throw new Error("Insufficient role for deleting workspace membership"); } // delete workspace membership @@ -72,9 +67,9 @@ export const deleteMembership = async (req: Request, res: Response) => { membershipId: membershipToDelete._id.toString() }); - return res.status(200).send({ - deletedMembership - }); + return res.status(200).send({ + deletedMembership + }); }; /** @@ -88,7 +83,7 @@ export const changeMembershipRole = async (req: Request, res: Response) => { const { role } = req.body; if (![ADMIN, MEMBER].includes(role)) { - throw new Error('Failed to validate role'); + throw new Error("Failed to validate role"); } // validate target membership @@ -97,7 +92,7 @@ export const changeMembershipRole = async (req: Request, res: Response) => { }); if (!membershipToChangeRole) { - throw new Error('Failed to find membership to change role'); + throw new Error("Failed to find membership to change role"); } // check if user is a member and admin of target membership's @@ -108,20 +103,20 @@ export const changeMembershipRole = async (req: Request, res: Response) => { }); if (!membership) { - throw new Error('Failed to validate membership'); + throw new Error("Failed to validate membership"); } if (membership.role !== ADMIN) { // user is not an admin member of the workspace - throw new Error('Insufficient role for changing member roles'); + throw new Error("Insufficient role for changing member roles"); } membershipToChangeRole.role = role; await membershipToChangeRole.save(); - return res.status(200).send({ - membership: membershipToChangeRole - }); + return res.status(200).send({ + membership: membershipToChangeRole + }); }; /** @@ -136,10 +131,9 @@ export const inviteUserToWorkspace = async (req: Request, res: Response) => { const invitee = await User.findOne({ email - }).select('+publicKey'); + }).select("+publicKey"); - if (!invitee || !invitee?.publicKey) - throw new Error('Failed to validate invitee'); + if (!invitee || !invitee?.publicKey) throw new Error("Failed to validate invitee"); // validate invitee's workspace membership - ensure member isn't // already a member of the workspace @@ -148,8 +142,7 @@ export const inviteUserToWorkspace = async (req: Request, res: Response) => { workspace: workspaceId }); - if (inviteeMembership) - throw new Error('Failed to add existing member of workspace'); + if (inviteeMembership) throw new Error("Failed to add existing member of workspace"); // validate invitee's organization membership - ensure that only // (accepted) organization members can be added to the workspace @@ -159,8 +152,7 @@ export const inviteUserToWorkspace = async (req: Request, res: Response) => { status: ACCEPTED }); - if (!membershipOrg) - throw new Error("Failed to validate invitee's organization membership"); + if (!membershipOrg) throw new Error("Failed to validate invitee's organization membership"); // get latest key const latestKey = await Key.findOne({ @@ -168,29 +160,29 @@ export const inviteUserToWorkspace = async (req: Request, res: Response) => { receiver: req.user._id }) .sort({ createdAt: -1 }) - .populate('sender', '+publicKey'); + .populate("sender", "+publicKey"); // create new workspace membership - const m = await new Membership({ + await new Membership({ user: invitee._id, workspace: workspaceId, role: MEMBER }).save(); await sendMail({ - template: 'workspaceInvitation.handlebars', - subjectLine: 'Infisical workspace invitation', + template: "workspaceInvitation.handlebars", + subjectLine: "Infisical workspace invitation", recipients: [invitee.email], substitutions: { inviterFirstName: req.user.firstName, inviterEmail: req.user.email, workspaceName: req.membership.workspace.name, - callback_url: (await getSiteURL()) + '/login' + callback_url: (await getSiteURL()) + "/login" } }); - return res.status(200).send({ - invitee, - latestKey - }); + return res.status(200).send({ + invitee, + latestKey + }); }; diff --git a/backend/src/controllers/v1/membershipOrgController.ts b/backend/src/controllers/v1/membershipOrgController.ts index 0d4c1436d7..b5669a6715 100644 --- a/backend/src/controllers/v1/membershipOrgController.ts +++ b/backend/src/controllers/v1/membershipOrgController.ts @@ -1,15 +1,27 @@ -import { Types } from 'mongoose'; -import { Request, Response } from 'express'; -import { MembershipOrg, Organization, User } from '../../models'; -import { deleteMembershipOrg as deleteMemberFromOrg } from '../../helpers/membershipOrg'; -import { createToken } from '../../helpers/auth'; -import { updateSubscriptionOrgQuantity } from '../../helpers/organization'; -import { sendMail } from '../../helpers/nodemailer'; -import { TokenService } from '../../services'; -import { EELicenseService } from '../../ee/services'; -import { OWNER, ADMIN, MEMBER, ACCEPTED, INVITED, TOKEN_EMAIL_ORG_INVITATION } from '../../variables'; -import { getSiteURL, getJwtSignupLifetime, getJwtSignupSecret, getSmtpConfigured } from '../../config'; -import { validateUserEmail } from '../../validation'; +import { Types } from "mongoose"; +import { Request, Response } from "express"; +import { MembershipOrg, Organization, User } from "../../models"; +import { deleteMembershipOrg as deleteMemberFromOrg } from "../../helpers/membershipOrg"; +import { createToken } from "../../helpers/auth"; +import { updateSubscriptionOrgQuantity } from "../../helpers/organization"; +import { sendMail } from "../../helpers/nodemailer"; +import { TokenService } from "../../services"; +import { EELicenseService } from "../../ee/services"; +import { + ACCEPTED, + ADMIN, + INVITED, + MEMBER, + OWNER, + TOKEN_EMAIL_ORG_INVITATION +} from "../../variables"; +import { + getJwtSignupLifetime, + getJwtSignupSecret, + getSiteURL, + getSmtpConfigured +} from "../../config"; +import { validateUserEmail } from "../../validation"; /** * Delete organization membership with id [membershipOrgId] from organization @@ -17,18 +29,16 @@ import { validateUserEmail } from '../../validation'; * @param res * @returns */ -export const deleteMembershipOrg = async (req: Request, res: Response) => { +export const deleteMembershipOrg = async (req: Request, _res: Response) => { const { membershipOrgId } = req.params; // check if organization membership to delete exists const membershipOrgToDelete = await MembershipOrg.findOne({ _id: membershipOrgId - }).populate('user'); + }).populate("user"); if (!membershipOrgToDelete) { - throw new Error( - "Failed to delete organization membership that doesn't exist" - ); + throw new Error("Failed to delete organization membership that doesn't exist"); } // check if user is a member and admin of the organization @@ -39,16 +49,16 @@ export const deleteMembershipOrg = async (req: Request, res: Response) => { }); if (!membershipOrg) { - throw new Error('Failed to validate organization membership'); + throw new Error("Failed to validate organization membership"); } if (membershipOrg.role !== OWNER && membershipOrg.role !== ADMIN) { // user is not an admin member of the organization - throw new Error('Insufficient role for deleting organization membership'); + throw new Error("Insufficient role for deleting organization membership"); } // delete organization membership - const deletedMembershipOrg = await deleteMemberFromOrg({ + await deleteMemberFromOrg({ membershipOrgId: membershipOrgToDelete._id.toString() }); @@ -56,7 +66,7 @@ export const deleteMembershipOrg = async (req: Request, res: Response) => { organizationId: membershipOrg.organization.toString() }); - return membershipOrgToDelete; + return membershipOrgToDelete; }; /** @@ -66,14 +76,14 @@ export const deleteMembershipOrg = async (req: Request, res: Response) => { * @returns */ export const changeMembershipOrgRole = async (req: Request, res: Response) => { - // change role for (target) organization membership with id - // [membershipOrgId] + // change role for (target) organization membership with id + // [membershipOrgId] - let membershipToChangeRole; + let membershipToChangeRole; - return res.status(200).send({ - membershipOrg: membershipToChangeRole - }); + return res.status(200).send({ + membershipOrg: membershipToChangeRole + }); }; /** @@ -84,7 +94,7 @@ export const changeMembershipOrgRole = async (req: Request, res: Response) => { * @returns */ export const inviteUserToOrganization = async (req: Request, res: Response) => { - let invitee, inviteeMembershipOrg, completeInviteLink; + let inviteeMembershipOrg, completeInviteLink; const { organizationId, inviteeEmail } = req.body; const host = req.headers.host; const siteUrl = `${req.protocol}://${host}`; @@ -96,25 +106,26 @@ export const inviteUserToOrganization = async (req: Request, res: Response) => { }); if (!membershipOrg) { - throw new Error('Failed to validate organization membership'); + throw new Error("Failed to validate organization membership"); } - + const plan = await EELicenseService.getPlan(organizationId); - + if (plan.memberLimit !== null) { // case: limit imposed on number of members allowed - + if (plan.membersUsed >= plan.memberLimit) { // case: number of members used exceeds the number of members allowed return res.status(400).send({ - message: 'Failed to invite member due to member limit reached. Upgrade plan to invite more members.' + message: + "Failed to invite member due to member limit reached. Upgrade plan to invite more members." }); } } - invitee = await User.findOne({ + const invitee = await User.findOne({ email: inviteeEmail - }).select('+publicKey'); + }).select("+publicKey"); if (invitee) { // case: invitee is an existing user @@ -125,13 +136,10 @@ export const inviteUserToOrganization = async (req: Request, res: Response) => { }); if (inviteeMembershipOrg && inviteeMembershipOrg.status === ACCEPTED) { - throw new Error( - 'Failed to invite an existing member of the organization' - ); + throw new Error("Failed to invite an existing member of the organization"); } if (!inviteeMembershipOrg) { - await new MembershipOrg({ user: invitee, inviteEmail: inviteeEmail, @@ -149,7 +157,7 @@ export const inviteUserToOrganization = async (req: Request, res: Response) => { if (!inviteeMembershipOrg) { // case: invitee has never been invited before - + // validate that email is not disposable validateUserEmail(inviteeEmail); @@ -165,7 +173,6 @@ export const inviteUserToOrganization = async (req: Request, res: Response) => { const organization = await Organization.findOne({ _id: organizationId }); if (organization) { - const token = await TokenService.createToken({ type: TOKEN_EMAIL_ORG_INVITATION, email: inviteeEmail, @@ -173,8 +180,8 @@ export const inviteUserToOrganization = async (req: Request, res: Response) => { }); await sendMail({ - template: 'organizationInvitation.handlebars', - subjectLine: 'Infisical organization invitation', + template: "organizationInvitation.handlebars", + subjectLine: "Infisical organization invitation", recipients: [inviteeEmail], substitutions: { inviterFirstName: req.user.firstName, @@ -183,21 +190,23 @@ export const inviteUserToOrganization = async (req: Request, res: Response) => { email: inviteeEmail, organizationId: organization._id.toString(), token, - callback_url: (await getSiteURL()) + '/signupinvite' + callback_url: (await getSiteURL()) + "/signupinvite" } }); if (!(await getSmtpConfigured())) { - completeInviteLink = `${siteUrl + '/signupinvite'}?token=${token}&to=${inviteeEmail}&organization_id=${organization._id}` + completeInviteLink = `${ + siteUrl + "/signupinvite" + }?token=${token}&to=${inviteeEmail}&organization_id=${organization._id}`; } } await updateSubscriptionOrgQuantity({ organizationId }); - return res.status(200).send({ - message: `Sent an invite link to ${req.body.inviteeEmail}`, - completeInviteLink - }); + return res.status(200).send({ + message: `Sent an invite link to ${req.body.inviteeEmail}`, + completeInviteLink + }); }; /** @@ -208,14 +217,10 @@ export const inviteUserToOrganization = async (req: Request, res: Response) => { * @returns */ export const verifyUserToOrganization = async (req: Request, res: Response) => { - let user; - const { - email, - organizationId, - code - } = req.body; + let user; + const { email, organizationId, code } = req.body; - user = await User.findOne({ email }).select('+publicKey'); + user = await User.findOne({ email }).select("+publicKey"); const membershipOrg = await MembershipOrg.findOne({ inviteEmail: email, @@ -223,8 +228,7 @@ export const verifyUserToOrganization = async (req: Request, res: Response) => { organization: new Types.ObjectId(organizationId) }); - if (!membershipOrg) - throw new Error('Failed to find any invitations for email'); + if (!membershipOrg) throw new Error("Failed to find any invitations for email"); await TokenService.validateToken({ type: TOKEN_EMAIL_ORG_INVITATION, @@ -238,14 +242,14 @@ export const verifyUserToOrganization = async (req: Request, res: Response) => { // membership can be approved and redirected to login/dashboard membershipOrg.status = ACCEPTED; await membershipOrg.save(); - + await updateSubscriptionOrgQuantity({ organizationId }); return res.status(200).send({ - message: 'Successfully verified email', - user, + message: "Successfully verified email", + user }); } @@ -265,9 +269,9 @@ export const verifyUserToOrganization = async (req: Request, res: Response) => { secret: await getJwtSignupSecret() }); - return res.status(200).send({ - message: 'Successfully verified email', - user, - token - }); + return res.status(200).send({ + message: "Successfully verified email", + user, + token + }); }; diff --git a/backend/src/controllers/v1/organizationController.ts b/backend/src/controllers/v1/organizationController.ts index f0c73d75c6..304df8b432 100644 --- a/backend/src/controllers/v1/organizationController.ts +++ b/backend/src/controllers/v1/organizationController.ts @@ -1,28 +1,27 @@ -import { Request, Response } from 'express'; -import Stripe from 'stripe'; +import { Request, Response } from "express"; +import Stripe from "stripe"; import { + IncidentContactOrg, Membership, MembershipOrg, Organization, Workspace, - IncidentContactOrg -} from '../../models'; -import { createOrganization as create } from '../../helpers/organization'; -import { addMembershipsOrg } from '../../helpers/membershipOrg'; -import { OWNER, ACCEPTED } from '../../variables'; -import _ from 'lodash'; -import { getStripeSecretKey, getSiteURL } from '../../config'; +} from "../../models"; +import { createOrganization as create } from "../../helpers/organization"; +import { addMembershipsOrg } from "../../helpers/membershipOrg"; +import { ACCEPTED, OWNER } from "../../variables"; +import { getSiteURL, getStripeSecretKey } from "../../config"; export const getOrganizations = async (req: Request, res: Response) => { const organizations = ( await MembershipOrg.find({ user: req.user._id, - status: ACCEPTED - }).populate('organization') + status: ACCEPTED, + }).populate("organization") ).map((m) => m.organization); return res.status(200).send({ - organizations + organizations, }); }; @@ -37,24 +36,24 @@ export const createOrganization = async (req: Request, res: Response) => { const { organizationName } = req.body; if (organizationName.length < 1) { - throw new Error('Organization names must be at least 1-character long'); + throw new Error("Organization names must be at least 1-character long"); } // create organization and add user as member const organization = await create({ email: req.user.email, - name: organizationName + name: organizationName, }); await addMembershipsOrg({ userIds: [req.user._id.toString()], organizationId: organization._id.toString(), roles: [OWNER], - statuses: [ACCEPTED] + statuses: [ACCEPTED], }); return res.status(200).send({ - organization + organization, }); }; @@ -67,7 +66,7 @@ export const createOrganization = async (req: Request, res: Response) => { export const getOrganization = async (req: Request, res: Response) => { const organization = req.organization return res.status(200).send({ - organization + organization, }); }; @@ -81,11 +80,11 @@ export const getOrganizationMembers = async (req: Request, res: Response) => { const { organizationId } = req.params; const users = await MembershipOrg.find({ - organization: organizationId - }).populate('user', '+publicKey'); + organization: organizationId, + }).populate("user", "+publicKey"); return res.status(200).send({ - users + users, }); }; @@ -105,23 +104,23 @@ export const getOrganizationWorkspaces = async ( ( await Workspace.find( { - organization: organizationId + organization: organizationId, }, - '_id' + "_id" ) ).map((w) => w._id.toString()) ); const workspaces = ( await Membership.find({ - user: req.user._id - }).populate('workspace') + user: req.user._id, + }).populate("workspace") ) .filter((m) => workspacesSet.has(m.workspace._id.toString())) .map((m) => m.workspace); return res.status(200).send({ - workspaces + workspaces, }); }; @@ -137,19 +136,19 @@ export const changeOrganizationName = async (req: Request, res: Response) => { const organization = await Organization.findOneAndUpdate( { - _id: organizationId + _id: organizationId, }, { - name + name, }, { - new: true + new: true, } ); return res.status(200).send({ - message: 'Successfully changed organization name', - organization + message: "Successfully changed organization name", + organization, }); }; @@ -166,11 +165,11 @@ export const getOrganizationIncidentContacts = async ( const { organizationId } = req.params; const incidentContactsOrg = await IncidentContactOrg.find({ - organization: organizationId + organization: organizationId, }); return res.status(200).send({ - incidentContactsOrg + incidentContactsOrg, }); }; @@ -194,7 +193,7 @@ export const addOrganizationIncidentContact = async ( ); return res.status(200).send({ - incidentContactOrg + incidentContactOrg, }); }; @@ -213,12 +212,12 @@ export const deleteOrganizationIncidentContact = async ( const incidentContactOrg = await IncidentContactOrg.findOneAndDelete({ email, - organization: organizationId + organization: organizationId, }); return res.status(200).send({ - message: 'Successfully deleted organization incident contact', - incidentContactOrg + message: "Successfully deleted organization incident contact", + incidentContactOrg, }); }; @@ -235,28 +234,28 @@ export const createOrganizationPortalSession = async ( ) => { let session; const stripe = new Stripe(await getStripeSecretKey(), { - apiVersion: '2022-08-01' + apiVersion: "2022-08-01", }); // check if there is a payment method on file const paymentMethods = await stripe.paymentMethods.list({ customer: req.organization.customerId, - type: 'card' + type: "card", }); if (paymentMethods.data.length < 1) { // case: no payment method on file session = await stripe.checkout.sessions.create({ customer: req.organization.customerId, - mode: 'setup', - payment_method_types: ['card'], - success_url: (await getSiteURL()) + '/dashboard', - cancel_url: (await getSiteURL()) + '/dashboard' + mode: "setup", + payment_method_types: ["card"], + success_url: (await getSiteURL()) + "/dashboard", + cancel_url: (await getSiteURL()) + "/dashboard", }); } else { session = await stripe.billingPortal.sessions.create({ customer: req.organization.customerId, - return_url: (await getSiteURL()) + '/dashboard' + return_url: (await getSiteURL()) + "/dashboard", }); } @@ -274,15 +273,15 @@ export const getOrganizationSubscriptions = async ( res: Response ) => { const stripe = new Stripe(await getStripeSecretKey(), { - apiVersion: '2022-08-01' + apiVersion: "2022-08-01", }); const subscriptions = await stripe.subscriptions.list({ - customer: req.organization.customerId + customer: req.organization.customerId, }); return res.status(200).send({ - subscriptions + subscriptions, }); }; @@ -302,16 +301,16 @@ export const getOrganizationMembersAndTheirWorkspaces = async ( const workspacesSet = ( await Workspace.find( { - organization: organizationId + organization: organizationId, }, - '_id' + "_id" ) ).map((w) => w._id.toString()); const memberships = ( await Membership.find({ - workspace: { $in: workspacesSet } - }).populate('workspace') + workspace: { $in: workspacesSet }, + }).populate("workspace") ); const userToWorkspaceIds: any = {}; diff --git a/backend/src/controllers/v1/passwordController.ts b/backend/src/controllers/v1/passwordController.ts index da1903ebaa..5a26992255 100644 --- a/backend/src/controllers/v1/passwordController.ts +++ b/backend/src/controllers/v1/passwordController.ts @@ -1,85 +1,77 @@ -import { Request, Response } from 'express'; +import { Request, Response } from "express"; // eslint-disable-next-line @typescript-eslint/no-var-requires -const jsrp = require('jsrp'); -import * as bigintConversion from 'bigint-conversion'; -import { User, BackupPrivateKey, LoginSRPDetail } from '../../models'; +const jsrp = require("jsrp"); +import * as bigintConversion from "bigint-conversion"; +import { BackupPrivateKey, LoginSRPDetail, User } from "../../models"; +import { clearTokens, createToken, sendMail } from "../../helpers"; +import { TokenService } from "../../services"; +import { AUTH_MODE_JWT, TOKEN_EMAIL_PASSWORD_RESET } from "../../variables"; +import { BadRequestError } from "../../utils/errors"; import { - createToken, - sendMail, - clearTokens -} from '../../helpers'; -import { TokenService } from '../../services'; -import { - TOKEN_EMAIL_PASSWORD_RESET, - AUTH_MODE_JWT -} from '../../variables'; -import { BadRequestError } from '../../utils/errors'; -import { - getSiteURL, - getJwtSignupLifetime, - getJwtSignupSecret, - getHttpsEnabled -} from '../../config'; + getHttpsEnabled, + getJwtSignupLifetime, + getJwtSignupSecret, + getSiteURL +} from "../../config"; /** - * Password reset step 1: Send email verification link to email [email] + * Password reset step 1: Send email verification link to email [email] * for account recovery. * @param req * @param res * @returns */ export const emailPasswordReset = async (req: Request, res: Response) => { - let email: string; - email = req.body.email; + const email: string = req.body.email; - const user = await User.findOne({ email }).select('+publicKey'); + const user = await User.findOne({ email }).select("+publicKey"); if (!user || !user?.publicKey) { // case: user has already completed account return res.status(200).send({ - message:"If an account exists with this email, a password reset link has been sent" + message: "If an account exists with this email, a password reset link has been sent" }); } - + const token = await TokenService.createToken({ type: TOKEN_EMAIL_PASSWORD_RESET, email }); - + await sendMail({ - template: 'passwordReset.handlebars', - subjectLine: 'Infisical password reset', + template: "passwordReset.handlebars", + subjectLine: "Infisical password reset", recipients: [email], substitutions: { email, token, - callback_url: (await getSiteURL()) + '/password-reset' + callback_url: (await getSiteURL()) + "/password-reset" } }); - return res.status(200).send({ - message:"If an account exists with this email, a password reset link has been sent" - }); -} + return res.status(200).send({ + message: "If an account exists with this email, a password reset link has been sent" + }); +}; /** * Password reset step 2: Verify email verification link sent to email [email] - * @param req - * @param res - * @returns + * @param req + * @param res + * @returns */ export const emailPasswordResetVerify = async (req: Request, res: Response) => { const { email, code } = req.body; - const user = await User.findOne({ email }).select('+publicKey'); + const user = await User.findOne({ email }).select("+publicKey"); if (!user || !user?.publicKey) { - // case: user doesn't exist with email [email] or + // case: user doesn't exist with email [email] or // hasn't even completed their account return res.status(403).send({ - error: 'Failed email verification for password reset' + error: "Failed email verification for password reset" }); } - + await TokenService.validateToken({ type: TOKEN_EMAIL_PASSWORD_RESET, email, @@ -95,12 +87,12 @@ export const emailPasswordResetVerify = async (req: Request, res: Response) => { secret: await getJwtSignupSecret() }); - return res.status(200).send({ - message: 'Successfully verified email', - user, - token - }); -} + return res.status(200).send({ + message: "Successfully verified email", + user, + token + }); +}; /** * Return [salt] and [serverPublicKey] as part of step 1 of SRP protocol @@ -109,14 +101,14 @@ export const emailPasswordResetVerify = async (req: Request, res: Response) => { * @returns */ export const srp1 = async (req: Request, res: Response) => { - // return salt, serverPublicKey as part of first step of SRP protocol - + // return salt, serverPublicKey as part of first step of SRP protocol + const { clientPublicKey } = req.body; const user = await User.findOne({ email: req.user.email - }).select('+salt +verifier'); + }).select("+salt +verifier"); - if (!user) throw new Error('Failed to find user'); + if (!user) throw new Error("Failed to find user"); const server = new jsrp.server(); server.init( @@ -128,11 +120,15 @@ export const srp1 = async (req: Request, res: Response) => { // generate server-side public key const serverPublicKey = server.getPublicKey(); - await LoginSRPDetail.findOneAndReplace({ email: req.user.email }, { - email: req.user.email, - clientPublicKey: clientPublicKey, - serverBInt: bigintConversion.bigintToBuf(server.bInt), - }, { upsert: true, returnNewDocument: false }) + await LoginSRPDetail.findOneAndReplace( + { email: req.user.email }, + { + email: req.user.email, + clientPublicKey: clientPublicKey, + serverBInt: bigintConversion.bigintToBuf(server.bInt) + }, + { upsert: true, returnNewDocument: false } + ); return res.status(200).send({ serverPublicKey, @@ -140,8 +136,7 @@ export const srp1 = async (req: Request, res: Response) => { }); } ); -} - +}; /** * Change account SRP authentication information for user @@ -152,8 +147,8 @@ export const srp1 = async (req: Request, res: Response) => { * @returns */ export const changePassword = async (req: Request, res: Response) => { - const { - clientProof, + const { + clientProof, protectedKey, protectedKeyIV, protectedKeyTag, @@ -166,14 +161,18 @@ export const changePassword = async (req: Request, res: Response) => { const user = await User.findOne({ email: req.user.email - }).select('+salt +verifier'); + }).select("+salt +verifier"); - if (!user) throw new Error('Failed to find user'); + if (!user) throw new Error("Failed to find user"); - const loginSRPDetailFromDB = await LoginSRPDetail.findOneAndDelete({ email: req.user.email }) + const loginSRPDetailFromDB = await LoginSRPDetail.findOneAndDelete({ email: req.user.email }); if (!loginSRPDetailFromDB) { - return BadRequestError(Error("It looks like some details from the first login are not found. Please try login one again")) + return BadRequestError( + Error( + "It looks like some details from the first login are not found. Please try login one again" + ) + ); } const server = new jsrp.server(); @@ -207,27 +206,31 @@ export const changePassword = async (req: Request, res: Response) => { new: true } ); - - if (req.authData.authMode === AUTH_MODE_JWT && req.authData.authPayload instanceof User && req.authData.tokenVersionId) { - await clearTokens(req.authData.tokenVersionId) + + if ( + req.authData.authMode === AUTH_MODE_JWT && + req.authData.authPayload instanceof User && + req.authData.tokenVersionId + ) { + await clearTokens(req.authData.tokenVersionId); } // clear httpOnly cookie - - res.cookie('jid', '', { + + res.cookie("jid", "", { httpOnly: true, - path: '/', - sameSite: 'strict', + path: "/", + sameSite: "strict", secure: (await getHttpsEnabled()) as boolean }); return res.status(200).send({ - message: 'Successfully changed password' + message: "Successfully changed password" }); } return res.status(400).send({ - error: 'Failed to change password. Try again?' + error: "Failed to change password. Try again?" }); } ); @@ -240,22 +243,25 @@ export const changePassword = async (req: Request, res: Response) => { * @returns */ export const createBackupPrivateKey = async (req: Request, res: Response) => { - // create/change backup private key - // requires verifying [clientProof] as part of second step of SRP protocol - // as initiated in /srp1 + // create/change backup private key + // requires verifying [clientProof] as part of second step of SRP protocol + // as initiated in /srp1 - const { clientProof, encryptedPrivateKey, iv, tag, salt, verifier } = - req.body; + const { clientProof, encryptedPrivateKey, iv, tag, salt, verifier } = req.body; const user = await User.findOne({ email: req.user.email - }).select('+salt +verifier'); + }).select("+salt +verifier"); - if (!user) throw new Error('Failed to find user'); + if (!user) throw new Error("Failed to find user"); - const loginSRPDetailFromDB = await LoginSRPDetail.findOneAndDelete({ email: req.user.email }) + const loginSRPDetailFromDB = await LoginSRPDetail.findOneAndDelete({ email: req.user.email }); if (!loginSRPDetailFromDB) { - return BadRequestError(Error("It looks like some details from the first login are not found. Please try login one again")) + return BadRequestError( + Error( + "It looks like some details from the first login are not found. Please try login one again" + ) + ); } const server = new jsrp.server(); @@ -266,9 +272,7 @@ export const createBackupPrivateKey = async (req: Request, res: Response) => { b: loginSRPDetailFromDB.serverBInt }, async () => { - server.setClientPublicKey( - loginSRPDetailFromDB.clientPublicKey - ); + server.setClientPublicKey(loginSRPDetailFromDB.clientPublicKey); // compare server and client shared keys if (server.checkClientProof(clientProof)) { @@ -285,17 +289,17 @@ export const createBackupPrivateKey = async (req: Request, res: Response) => { verifier }, { upsert: true, new: true } - ).select('+user, encryptedPrivateKey'); + ).select("+user, encryptedPrivateKey"); // issue tokens return res.status(200).send({ - message: 'Successfully updated backup private key', + message: "Successfully updated backup private key", backupPrivateKey }); } return res.status(400).send({ - message: 'Failed to update backup private key' + message: "Failed to update backup private key" }); } ); @@ -303,21 +307,21 @@ export const createBackupPrivateKey = async (req: Request, res: Response) => { /** * Return backup private key for user - * @param req - * @param res - * @returns + * @param req + * @param res + * @returns */ export const getBackupPrivateKey = async (req: Request, res: Response) => { const backupPrivateKey = await BackupPrivateKey.findOne({ user: req.user._id - }).select('+encryptedPrivateKey +iv +tag'); + }).select("+encryptedPrivateKey +iv +tag"); - if (!backupPrivateKey) throw new Error('Failed to find backup private key'); + if (!backupPrivateKey) throw new Error("Failed to find backup private key"); - return res.status(200).send({ - backupPrivateKey - }); -} + return res.status(200).send({ + backupPrivateKey + }); +}; export const resetPassword = async (req: Request, res: Response) => { const { @@ -328,7 +332,7 @@ export const resetPassword = async (req: Request, res: Response) => { encryptedPrivateKeyIV, encryptedPrivateKeyTag, salt, - verifier, + verifier } = req.body; await User.findByIdAndUpdate( @@ -337,7 +341,7 @@ export const resetPassword = async (req: Request, res: Response) => { encryptionVersion: 2, protectedKey, protectedKeyIV, - protectedKeyTag, + protectedKeyTag, encryptedPrivateKey, iv: encryptedPrivateKeyIV, tag: encryptedPrivateKeyTag, @@ -349,7 +353,7 @@ export const resetPassword = async (req: Request, res: Response) => { } ); - return res.status(200).send({ - message: 'Successfully reset password' - }); -} + return res.status(200).send({ + message: "Successfully reset password" + }); +}; diff --git a/backend/src/controllers/v1/secretController.ts b/backend/src/controllers/v1/secretController.ts index 074e294548..bcb00d2096 100644 --- a/backend/src/controllers/v1/secretController.ts +++ b/backend/src/controllers/v1/secretController.ts @@ -1,30 +1,30 @@ -import { Request, Response } from 'express'; -import { Types } from 'mongoose'; -import { Key, Secret } from '../../models'; +import { Request, Response } from "express"; +import { Types } from "mongoose"; +import { Key } from "../../models"; import { - v1PushSecrets as push, - pullSecrets as pull, - reformatPullSecrets -} from '../../helpers/secret'; -import { pushKeys } from '../../helpers/key'; -import { eventPushSecrets } from '../../events'; -import { EventService } from '../../services'; -import { TelemetryService } from '../../services'; + pullSecrets as pull, + v1PushSecrets as push, + reformatPullSecrets +} from "../../helpers/secret"; +import { pushKeys } from "../../helpers/key"; +import { eventPushSecrets } from "../../events"; +import { EventService } from "../../services"; +import { TelemetryService } from "../../services"; interface PushSecret { - ciphertextKey: string; - ivKey: string; - tagKey: string; - hashKey: string; - ciphertextValue: string; - ivValue: string; - tagValue: string; - hashValue: string; - ciphertextComment: string; - ivComment: string; - tagComment: string; - hashComment: string; - type: 'shared' | 'personal'; + ciphertextKey: string; + ivKey: string; + tagKey: string; + hashKey: string; + ciphertextValue: string; + ivValue: string; + tagValue: string; + hashValue: string; + ciphertextComment: string; + ivComment: string; + tagComment: string; + hashComment: string; + type: "shared" | "personal"; } /** @@ -35,7 +35,7 @@ interface PushSecret { * @returns */ export const pushSecrets = async (req: Request, res: Response) => { - // upload (encrypted) secrets to workspace with id [workspaceId] + // upload (encrypted) secrets to workspace with id [workspaceId] const postHogClient = await TelemetryService.getPostHogClient(); let { secrets }: { secrets: PushSecret[] } = req.body; const { keys, environment, channel } = req.body; @@ -44,13 +44,11 @@ export const pushSecrets = async (req: Request, res: Response) => { // validate environment const workspaceEnvs = req.membership.workspace.environments; if (!workspaceEnvs.find(({ slug }: { slug: string }) => slug === environment)) { - throw new Error('Failed to validate environment'); + throw new Error("Failed to validate environment"); } // sanitize secrets - secrets = secrets.filter( - (s: PushSecret) => s.ciphertextKey !== '' && s.ciphertextValue !== '' - ); + secrets = secrets.filter((s: PushSecret) => s.ciphertextKey !== "" && s.ciphertextValue !== ""); await push({ userId: req.user._id, @@ -64,17 +62,16 @@ export const pushSecrets = async (req: Request, res: Response) => { workspaceId, keys }); - - + if (postHogClient) { postHogClient.capture({ - event: 'secrets pushed', + event: "secrets pushed", distinctId: req.user.email, properties: { numberOfSecrets: secrets.length, environment, workspaceId, - channel: channel ? channel : 'cli' + channel: channel ? channel : "cli" } }); } @@ -87,9 +84,9 @@ export const pushSecrets = async (req: Request, res: Response) => { }) }); - return res.status(200).send({ - message: 'Successfully uploaded workspace secrets' - }); + return res.status(200).send({ + message: "Successfully uploaded workspace secrets" + }); }; /** @@ -100,57 +97,56 @@ export const pushSecrets = async (req: Request, res: Response) => { * @returns */ export const pullSecrets = async (req: Request, res: Response) => { - let secrets; - let key; + let secrets; - const postHogClient = await TelemetryService.getPostHogClient(); - const environment: string = req.query.environment as string; - const channel: string = req.query.channel as string; - const { workspaceId } = req.params; + const postHogClient = await TelemetryService.getPostHogClient(); + const environment: string = req.query.environment as string; + const channel: string = req.query.channel as string; + const { workspaceId } = req.params; - // validate environment - const workspaceEnvs = req.membership.workspace.environments; - if (!workspaceEnvs.find(({ slug }: { slug: string }) => slug === environment)) { - throw new Error('Failed to validate environment'); - } + // validate environment + const workspaceEnvs = req.membership.workspace.environments; + if (!workspaceEnvs.find(({ slug }: { slug: string }) => slug === environment)) { + throw new Error("Failed to validate environment"); + } - secrets = await pull({ - userId: req.user._id.toString(), - workspaceId, - environment, - channel: channel ? channel : 'cli', - ipAddress: req.realIP - }); + secrets = await pull({ + userId: req.user._id.toString(), + workspaceId, + environment, + channel: channel ? channel : "cli", + ipAddress: req.realIP + }); - key = await Key.findOne({ - workspace: workspaceId, - receiver: req.user._id - }) - .sort({ createdAt: -1 }) - .populate('sender', '+publicKey'); - - if (channel !== 'cli') { - secrets = reformatPullSecrets({ secrets }); - } + const key = await Key.findOne({ + workspace: workspaceId, + receiver: req.user._id + }) + .sort({ createdAt: -1 }) + .populate("sender", "+publicKey"); - if (postHogClient) { - // capture secrets pushed event in production - postHogClient.capture({ - distinctId: req.user.email, - event: 'secrets pulled', - properties: { - numberOfSecrets: secrets.length, - environment, - workspaceId, - channel: channel ? channel : 'cli' - } - }); - } + if (channel !== "cli") { + secrets = reformatPullSecrets({ secrets }); + } - return res.status(200).send({ - secrets, - key - }); + if (postHogClient) { + // capture secrets pushed event in production + postHogClient.capture({ + distinctId: req.user.email, + event: "secrets pulled", + properties: { + numberOfSecrets: secrets.length, + environment, + workspaceId, + channel: channel ? channel : "cli" + } + }); + } + + return res.status(200).send({ + secrets, + key + }); }; /** @@ -162,54 +158,51 @@ export const pullSecrets = async (req: Request, res: Response) => { * @returns */ export const pullSecretsServiceToken = async (req: Request, res: Response) => { - let secrets; - let key; + const postHogClient = await TelemetryService.getPostHogClient(); + const environment: string = req.query.environment as string; + const channel: string = req.query.channel as string; + const { workspaceId } = req.params; - const postHogClient = await TelemetryService.getPostHogClient(); - const environment: string = req.query.environment as string; - const channel: string = req.query.channel as string; - const { workspaceId } = req.params; + // validate environment + const workspaceEnvs = req.membership.workspace.environments; + if (!workspaceEnvs.find(({ slug }: { slug: string }) => slug === environment)) { + throw new Error("Failed to validate environment"); + } - // validate environment - const workspaceEnvs = req.membership.workspace.environments; - if (!workspaceEnvs.find(({ slug }: { slug: string }) => slug === environment)) { - throw new Error('Failed to validate environment'); - } + const secrets = await pull({ + userId: req.serviceToken.user._id.toString(), + workspaceId, + environment, + channel: "cli", + ipAddress: req.realIP + }); - secrets = await pull({ - userId: req.serviceToken.user._id.toString(), - workspaceId, - environment, - channel: 'cli', - ipAddress: req.realIP - }); + const key = { + encryptedKey: req.serviceToken.encryptedKey, + nonce: req.serviceToken.nonce, + sender: { + publicKey: req.serviceToken.publicKey + }, + receiver: req.serviceToken.user, + workspace: req.serviceToken.workspace + }; - key = { - encryptedKey: req.serviceToken.encryptedKey, - nonce: req.serviceToken.nonce, - sender: { - publicKey: req.serviceToken.publicKey - }, - receiver: req.serviceToken.user, - workspace: req.serviceToken.workspace - }; + if (postHogClient) { + // capture secrets pulled event in production + postHogClient.capture({ + distinctId: req.serviceToken.user.email, + event: "secrets pulled", + properties: { + numberOfSecrets: secrets.length, + environment, + workspaceId, + channel: channel ? channel : "cli" + } + }); + } - if (postHogClient) { - // capture secrets pulled event in production - postHogClient.capture({ - distinctId: req.serviceToken.user.email, - event: 'secrets pulled', - properties: { - numberOfSecrets: secrets.length, - environment, - workspaceId, - channel: channel ? channel : 'cli' - } - }); - } - - return res.status(200).send({ - secrets: reformatPullSecrets({ secrets }), - key - }); + return res.status(200).send({ + secrets: reformatPullSecrets({ secrets }), + key + }); }; diff --git a/backend/src/controllers/v1/secretsFolderController.ts b/backend/src/controllers/v1/secretsFolderController.ts index c1ce7ffc44..6b31fd111b 100644 --- a/backend/src/controllers/v1/secretsFolderController.ts +++ b/backend/src/controllers/v1/secretsFolderController.ts @@ -5,13 +5,13 @@ import { BadRequestError } from "../../utils/errors"; import { appendFolder, deleteFolderById, - getAllFolderIds, - searchByFolderIdWithDir, - searchByFolderId, - validateFolderName, generateFolderId, - getParentFromFolderId, + getAllFolderIds, getFolderByPath, + getParentFromFolderId, + searchByFolderId, + searchByFolderIdWithDir, + validateFolderName, } from "../../services/FolderService"; import { ADMIN, MEMBER } from "../../variables"; import { validateMembership } from "../../helpers/membership"; diff --git a/backend/src/controllers/v1/serviceTokenController.ts b/backend/src/controllers/v1/serviceTokenController.ts index 86a87f372f..c1b753a906 100644 --- a/backend/src/controllers/v1/serviceTokenController.ts +++ b/backend/src/controllers/v1/serviceTokenController.ts @@ -1,7 +1,7 @@ -import { Request, Response } from 'express'; -import { ServiceToken } from '../../models'; -import { createToken } from '../../helpers/auth'; -import { getJwtServiceSecret } from '../../config'; +import { Request, Response } from "express"; +import { ServiceToken } from "../../models"; +import { createToken } from "../../helpers/auth"; +import { getJwtServiceSecret } from "../../config"; /** * Return service token on request @@ -11,7 +11,7 @@ import { getJwtServiceSecret } from '../../config'; */ export const getServiceToken = async (req: Request, res: Response) => { return res.status(200).send({ - serviceToken: req.serviceToken + serviceToken: req.serviceToken, }); }; @@ -31,13 +31,13 @@ export const createServiceToken = async (req: Request, res: Response) => { expiresIn, publicKey, encryptedKey, - nonce + nonce, } = req.body; // validate environment const workspaceEnvs = req.membership.workspace.environments; if (!workspaceEnvs.find(({ slug }: { slug: string }) => slug === environment)) { - throw new Error('Failed to validate environment'); + throw new Error("Failed to validate environment"); } // compute access token expiration date @@ -52,24 +52,24 @@ export const createServiceToken = async (req: Request, res: Response) => { expiresAt, publicKey, encryptedKey, - nonce + nonce, }).save(); token = createToken({ payload: { serviceTokenId: serviceToken._id.toString(), - workspaceId + workspaceId, }, expiresIn: expiresIn, - secret: await getJwtServiceSecret() + secret: await getJwtServiceSecret(), }); } catch (err) { return res.status(400).send({ - message: 'Failed to create service token' + message: "Failed to create service token", }); } return res.status(200).send({ - token + token, }); }; \ No newline at end of file diff --git a/backend/src/controllers/v1/signupController.ts b/backend/src/controllers/v1/signupController.ts index 19bf94e611..b545320a64 100644 --- a/backend/src/controllers/v1/signupController.ts +++ b/backend/src/controllers/v1/signupController.ts @@ -1,13 +1,15 @@ -import { Request, Response } from 'express'; -import { User } from '../../models'; +import { Request, Response } from "express"; +import { User } from "../../models"; +import { checkEmailVerification, sendEmailVerification } from "../../helpers/signup"; +import { createToken } from "../../helpers/auth"; +import { BadRequestError } from "../../utils/errors"; import { - sendEmailVerification, - checkEmailVerification, -} from '../../helpers/signup'; -import { createToken } from '../../helpers/auth'; -import { BadRequestError } from '../../utils/errors'; -import { getInviteOnlySignup, getJwtSignupLifetime, getJwtSignupSecret, getSmtpConfigured } from '../../config'; -import { validateUserEmail } from '../../validation'; + getInviteOnlySignup, + getJwtSignupLifetime, + getJwtSignupSecret, + getSmtpConfigured +} from "../../config"; +import { validateUserEmail } from "../../validation"; /** * Signup step 1: Initialize account for user under email [email] and send a verification code @@ -17,27 +19,26 @@ import { validateUserEmail } from '../../validation'; * @returns */ export const beginEmailSignup = async (req: Request, res: Response) => { - let email: string; - email = req.body.email; - + const email: string = req.body.email; + // validate that email is not disposable validateUserEmail(email); - const user = await User.findOne({ email }).select('+publicKey'); + const user = await User.findOne({ email }).select("+publicKey"); if (user && user?.publicKey) { // case: user has already completed account return res.status(403).send({ - error: 'Failed to send email verification code for complete account' + error: "Failed to send email verification code for complete account" }); } // send send verification email await sendEmailVerification({ email }); - return res.status(200).send({ - message: `Sent an email verification code to ${email}` - }); + return res.status(200).send({ + message: `Sent an email verification code to ${email}` + }); }; /** @@ -48,23 +49,25 @@ export const beginEmailSignup = async (req: Request, res: Response) => { * @returns */ export const verifyEmailSignup = async (req: Request, res: Response) => { - let user, token; + let user; const { email, code } = req.body; // initialize user account - user = await User.findOne({ email }).select('+publicKey'); + user = await User.findOne({ email }).select("+publicKey"); if (user && user?.publicKey) { // case: user has already completed account return res.status(403).send({ - error: 'Failed email verification for complete user' + error: "Failed email verification for complete user" }); } if (await getInviteOnlySignup()) { // Only one user can create an account without being invited. The rest need to be invited in order to make an account - const userCount = await User.countDocuments({}) + const userCount = await User.countDocuments({}); if (userCount != 0) { - throw BadRequestError({ message: "New user sign ups are not allowed at this time. You must be invited to sign up." }) + throw BadRequestError({ + message: "New user sign ups are not allowed at this time. You must be invited to sign up." + }); } } @@ -83,7 +86,7 @@ export const verifyEmailSignup = async (req: Request, res: Response) => { } // generate temporary signup token - token = createToken({ + const token = createToken({ payload: { userId: user._id.toString() }, @@ -91,9 +94,9 @@ export const verifyEmailSignup = async (req: Request, res: Response) => { secret: await getJwtSignupSecret() }); - return res.status(200).send({ - message: 'Successfuly verified email', - user, - token - }); + return res.status(200).send({ + message: "Successfuly verified email", + user, + token + }); }; diff --git a/backend/src/controllers/v1/stripeController.ts b/backend/src/controllers/v1/stripeController.ts index 4aa7adce98..2acb52abda 100644 --- a/backend/src/controllers/v1/stripeController.ts +++ b/backend/src/controllers/v1/stripeController.ts @@ -1,6 +1,6 @@ -import { Request, Response } from 'express'; -import Stripe from 'stripe'; -import { getStripeSecretKey, getStripeWebhookSecret } from '../../config'; +import { Request, Response } from "express"; +import Stripe from "stripe"; +import { getStripeSecretKey, getStripeWebhookSecret } from "../../config"; /** * Handle service provisioning/un-provisioning via Stripe @@ -11,10 +11,10 @@ import { getStripeSecretKey, getStripeWebhookSecret } from '../../config'; export const handleWebhook = async (req: Request, res: Response) => { // check request for valid stripe signature const stripe = new Stripe(await getStripeSecretKey(), { - apiVersion: '2022-08-01' + apiVersion: "2022-08-01", }); - const sig = req.headers['stripe-signature'] as string; + const sig = req.headers["stripe-signature"] as string; const event = stripe.webhooks.constructEvent( req.body, sig, @@ -22,7 +22,7 @@ export const handleWebhook = async (req: Request, res: Response) => { ); switch (event.type) { - case '': + case "": break; default: } diff --git a/backend/src/controllers/v1/userActionController.ts b/backend/src/controllers/v1/userActionController.ts index cba78c7b83..9e7354ce19 100644 --- a/backend/src/controllers/v1/userActionController.ts +++ b/backend/src/controllers/v1/userActionController.ts @@ -1,5 +1,5 @@ -import { Request, Response } from 'express'; -import { UserAction } from '../../models'; +import { Request, Response } from "express"; +import { UserAction } from "../../models"; /** * Add user action [action] @@ -15,18 +15,18 @@ export const addUserAction = async (req: Request, res: Response) => { const userAction = await UserAction.findOneAndUpdate( { user: req.user._id, - action + action, }, { user: req.user._id, action }, { new: true, - upsert: true + upsert: true, } ); return res.status(200).send({ - message: 'Successfully recorded user action', - userAction + message: "Successfully recorded user action", + userAction, }); }; @@ -42,10 +42,10 @@ export const getUserAction = async (req: Request, res: Response) => { const userAction = await UserAction.findOne({ user: req.user._id, - action + action, }); return res.status(200).send({ - userAction + userAction, }); }; diff --git a/backend/src/controllers/v1/userController.ts b/backend/src/controllers/v1/userController.ts index d194c62176..398b24f08f 100644 --- a/backend/src/controllers/v1/userController.ts +++ b/backend/src/controllers/v1/userController.ts @@ -1,4 +1,4 @@ -import { Request, Response } from 'express'; +import { Request, Response } from "express"; /** * Return user on request @@ -8,6 +8,6 @@ import { Request, Response } from 'express'; */ export const getUser = async (req: Request, res: Response) => { return res.status(200).send({ - user: req.user + user: req.user, }); }; diff --git a/backend/src/controllers/v1/workspaceController.ts b/backend/src/controllers/v1/workspaceController.ts index 2faac0d686..f26078acea 100644 --- a/backend/src/controllers/v1/workspaceController.ts +++ b/backend/src/controllers/v1/workspaceController.ts @@ -1,19 +1,18 @@ import { Request, Response } from "express"; import { - Workspace, - Membership, - MembershipOrg, + IUser, Integration, IntegrationAuth, - IUser, + Membership, + MembershipOrg, ServiceToken, - ServiceTokenData, + Workspace, } from "../../models"; import { createWorkspace as create, deleteWorkspace as deleteWork, } from "../../helpers/workspace"; -import { EELicenseService } from '../../ee/services'; +import { EELicenseService } from "../../ee/services"; import { addMemberships } from "../../helpers/membership"; import { ADMIN } from "../../variables"; @@ -123,7 +122,7 @@ export const createWorkspace = async (req: Request, res: Response) => { if (plan.workspacesUsed >= plan.workspaceLimit) { // case: number of workspaces used exceeds the number of workspaces allowed return res.status(400).send({ - message: 'Failed to create workspace due to plan limit reached. Upgrade plan to add more workspaces.' + message: "Failed to create workspace due to plan limit reached. Upgrade plan to add more workspaces.", }); } } diff --git a/backend/src/controllers/v2/apiKeyDataController.ts b/backend/src/controllers/v2/apiKeyDataController.ts index 73fd1afbff..ee19b0e4ce 100644 --- a/backend/src/controllers/v2/apiKeyDataController.ts +++ b/backend/src/controllers/v2/apiKeyDataController.ts @@ -1,74 +1,72 @@ -import { Request, Response } from 'express'; -import crypto from 'crypto'; -import bcrypt from 'bcrypt'; -import { - APIKeyData -} from '../../models'; -import { getSaltRounds } from '../../config'; +import { Request, Response } from "express"; +import crypto from "crypto"; +import bcrypt from "bcrypt"; +import { APIKeyData } from "../../models"; +import { getSaltRounds } from "../../config"; /** * Return API key data for user with id [req.user_id] * @param req - * @param res - * @returns + * @param res + * @returns */ export const getAPIKeyData = async (req: Request, res: Response) => { - const apiKeyData = await APIKeyData.find({ - user: req.user._id - }); - - return res.status(200).send({ - apiKeyData - }); -} + const apiKeyData = await APIKeyData.find({ + user: req.user._id, + }); + + return res.status(200).send({ + apiKeyData, + }); +}; /** * Create new API key data for user with id [req.user._id] - * @param req - * @param res + * @param req + * @param res */ export const createAPIKeyData = async (req: Request, res: Response) => { - const { name, expiresIn } = req.body; - - const secret = crypto.randomBytes(16).toString('hex'); - const secretHash = await bcrypt.hash(secret, await getSaltRounds()); - - const expiresAt = new Date(); - expiresAt.setSeconds(expiresAt.getSeconds() + expiresIn); - - let apiKeyData = await new APIKeyData({ - name, - lastUsed: new Date(), - expiresAt, - user: req.user._id, - secretHash - }).save(); - - // return api key data without sensitive data - // FIX: fix this any - apiKeyData = await APIKeyData.findById(apiKeyData._id) as any - - if (!apiKeyData) throw new Error('Failed to find API key data'); - - const apiKey = `ak.${apiKeyData._id.toString()}.${secret}`; - - return res.status(200).send({ - apiKey, - apiKeyData - }); -} + const { name, expiresIn } = req.body; + + const secret = crypto.randomBytes(16).toString("hex"); + const secretHash = await bcrypt.hash(secret, await getSaltRounds()); + + const expiresAt = new Date(); + expiresAt.setSeconds(expiresAt.getSeconds() + expiresIn); + + let apiKeyData = await new APIKeyData({ + name, + lastUsed: new Date(), + expiresAt, + user: req.user._id, + secretHash, + }).save(); + + // return api key data without sensitive data + // FIX: fix this any + apiKeyData = (await APIKeyData.findById(apiKeyData._id)) as any; + + if (!apiKeyData) throw new Error("Failed to find API key data"); + + const apiKey = `ak.${apiKeyData._id.toString()}.${secret}`; + + return res.status(200).send({ + apiKey, + apiKeyData, + }); +}; /** * Delete API key data with id [apiKeyDataId]. - * @param req - * @param res - * @returns + * @param req + * @param res + * @returns */ export const deleteAPIKeyData = async (req: Request, res: Response) => { - const { apiKeyDataId } = req.params; - const apiKeyData = await APIKeyData.findByIdAndDelete(apiKeyDataId); - - return res.status(200).send({ - apiKeyData - }); -} + const { apiKeyDataId } = req.params; + const apiKeyData = await APIKeyData.findByIdAndDelete(apiKeyDataId); + + return res.status(200).send({ + apiKeyData, + }); +}; diff --git a/backend/src/controllers/v2/authController.ts b/backend/src/controllers/v2/authController.ts index 0718ec8dc6..282c152886 100644 --- a/backend/src/controllers/v2/authController.ts +++ b/backend/src/controllers/v2/authController.ts @@ -1,27 +1,27 @@ /* eslint-disable @typescript-eslint/no-var-requires */ -import { Request, Response } from 'express'; -import jwt from 'jsonwebtoken'; -import * as bigintConversion from 'bigint-conversion'; -const jsrp = require('jsrp'); -import { User, LoginSRPDetail } from '../../models'; -import { issueAuthTokens, createToken } from '../../helpers/auth'; -import { checkUserDevice } from '../../helpers/user'; -import { sendMail } from '../../helpers/nodemailer'; -import { TokenService } from '../../services'; -import { EELogService } from '../../ee/services'; -import { BadRequestError, InternalServerError } from '../../utils/errors'; +import { Request, Response } from "express"; +import jwt from "jsonwebtoken"; +import * as bigintConversion from "bigint-conversion"; +const jsrp = require("jsrp"); +import { LoginSRPDetail, User } from "../../models"; +import { createToken, issueAuthTokens } from "../../helpers/auth"; +import { checkUserDevice } from "../../helpers/user"; +import { sendMail } from "../../helpers/nodemailer"; +import { TokenService } from "../../services"; +import { EELogService } from "../../ee/services"; +import { BadRequestError, InternalServerError } from "../../utils/errors"; import { + ACTION_LOGIN, TOKEN_EMAIL_MFA, - ACTION_LOGIN -} from '../../variables'; -import { getChannelFromUserAgent } from '../../utils/posthog'; // TODO: move this +} from "../../variables"; +import { getChannelFromUserAgent } from "../../utils/posthog"; // TODO: move this import { + getHttpsEnabled, getJwtMfaLifetime, getJwtMfaSecret, - getHttpsEnabled -} from '../../config'; +} from "../../config"; -declare module 'jsonwebtoken' { +declare module "jsonwebtoken" { export interface UserIDJwtPayload extends jwt.JwtPayload { userId: string; } @@ -36,20 +36,20 @@ declare module 'jsonwebtoken' { export const login1 = async (req: Request, res: Response) => { const { email, - clientPublicKey + clientPublicKey, }: { email: string; clientPublicKey: string } = req.body; const user = await User.findOne({ - email - }).select('+salt +verifier'); + email, + }).select("+salt +verifier"); - if (!user) throw new Error('Failed to find user'); + if (!user) throw new Error("Failed to find user"); const server = new jsrp.server(); server.init( { salt: user.salt, - verifier: user.verifier + verifier: user.verifier, }, async () => { // generate server-side public key @@ -63,7 +63,7 @@ export const login1 = async (req: Request, res: Response) => { return res.status(200).send({ serverPublicKey, - salt: user.salt + salt: user.salt, }); } ); @@ -78,14 +78,14 @@ export const login1 = async (req: Request, res: Response) => { * @returns */ export const login2 = async (req: Request, res: Response) => { - if (!req.headers['user-agent']) throw InternalServerError({ message: 'User-Agent header is required' }); + if (!req.headers["user-agent"]) throw InternalServerError({ message: "User-Agent header is required" }); const { email, clientProof } = req.body; const user = await User.findOne({ - email - }).select('+salt +verifier +encryptionVersion +protectedKey +protectedKeyIV +protectedKeyTag +publicKey +encryptedPrivateKey +iv +tag +devices'); + email, + }).select("+salt +verifier +encryptionVersion +protectedKey +protectedKeyIV +protectedKeyTag +publicKey +encryptedPrivateKey +iv +tag +devices"); - if (!user) throw new Error('Failed to find user'); + if (!user) throw new Error("Failed to find user"); const loginSRPDetail = await LoginSRPDetail.findOneAndDelete({ email: email }) @@ -98,7 +98,7 @@ export const login2 = async (req: Request, res: Response) => { { salt: user.salt, verifier: user.verifier, - b: loginSRPDetail.serverBInt + b: loginSRPDetail.serverBInt, }, async () => { server.setClientPublicKey(loginSRPDetail.clientPublicKey); @@ -111,52 +111,52 @@ export const login2 = async (req: Request, res: Response) => { // generate temporary MFA token const token = createToken({ payload: { - userId: user._id.toString() + userId: user._id.toString(), }, expiresIn: await getJwtMfaLifetime(), - secret: await getJwtMfaSecret() + secret: await getJwtMfaSecret(), }); const code = await TokenService.createToken({ type: TOKEN_EMAIL_MFA, - email + email, }); // send MFA code [code] to [email] await sendMail({ - template: 'emailMfa.handlebars', - subjectLine: 'Infisical MFA code', + template: "emailMfa.handlebars", + subjectLine: "Infisical MFA code", recipients: [email], substitutions: { - code - } + code, + }, }); return res.status(200).send({ mfaEnabled: true, - token + token, }); } await checkUserDevice({ user, ip: req.realIP, - userAgent: req.headers['user-agent'] ?? '' + userAgent: req.headers["user-agent"] ?? "", }); // issue tokens const tokens = await issueAuthTokens({ userId: user._id, ip: req.realIP, - userAgent: req.headers['user-agent'] ?? '' + userAgent: req.headers["user-agent"] ?? "", }); // store (refresh) token in httpOnly cookie - res.cookie('jid', tokens.refreshToken, { + res.cookie("jid", tokens.refreshToken, { httpOnly: true, - path: '/', - sameSite: 'strict', - secure: await getHttpsEnabled() + path: "/", + sameSite: "strict", + secure: await getHttpsEnabled(), }); // case: user does not have MFA enabled @@ -182,7 +182,7 @@ export const login2 = async (req: Request, res: Response) => { publicKey: user.publicKey, encryptedPrivateKey: user.encryptedPrivateKey, iv: user.iv, - tag: user.tag + tag: user.tag, } if ( @@ -197,21 +197,21 @@ export const login2 = async (req: Request, res: Response) => { const loginAction = await EELogService.createAction({ name: ACTION_LOGIN, - userId: user._id + userId: user._id, }); loginAction && await EELogService.createLog({ userId: user._id, actions: [loginAction], - channel: getChannelFromUserAgent(req.headers['user-agent']), - ipAddress: req.ip + channel: getChannelFromUserAgent(req.headers["user-agent"]), + ipAddress: req.ip, }); return res.status(200).send(response); } return res.status(400).send({ - message: 'Failed to authenticate. Try again?' + message: "Failed to authenticate. Try again?", }); } ); @@ -227,21 +227,21 @@ export const sendMfaToken = async (req: Request, res: Response) => { const code = await TokenService.createToken({ type: TOKEN_EMAIL_MFA, - email + email, }); // send MFA code [code] to [email] await sendMail({ - template: 'emailMfa.handlebars', - subjectLine: 'Infisical MFA code', + template: "emailMfa.handlebars", + subjectLine: "Infisical MFA code", recipients: [email], substitutions: { - code - } + code, + }, }); return res.status(200).send({ - message: 'Successfully sent new MFA code' + message: "Successfully sent new MFA code", }); } @@ -257,36 +257,36 @@ export const verifyMfaToken = async (req: Request, res: Response) => { await TokenService.validateToken({ type: TOKEN_EMAIL_MFA, email, - token: mfaToken + token: mfaToken, }); const user = await User.findOne({ - email - }).select('+salt +verifier +encryptionVersion +protectedKey +protectedKeyIV +protectedKeyTag +publicKey +encryptedPrivateKey +iv +tag +devices'); + email, + }).select("+salt +verifier +encryptionVersion +protectedKey +protectedKeyIV +protectedKeyTag +publicKey +encryptedPrivateKey +iv +tag +devices"); - if (!user) throw new Error('Failed to find user'); + if (!user) throw new Error("Failed to find user"); await LoginSRPDetail.deleteOne({ userId: user.id }) await checkUserDevice({ user, ip: req.realIP, - userAgent: req.headers['user-agent'] ?? '' + userAgent: req.headers["user-agent"] ?? "", }); // issue tokens const tokens = await issueAuthTokens({ userId: user._id, ip: req.realIP, - userAgent: req.headers['user-agent'] ?? '' + userAgent: req.headers["user-agent"] ?? "", }); // store (refresh) token in httpOnly cookie - res.cookie('jid', tokens.refreshToken, { + res.cookie("jid", tokens.refreshToken, { httpOnly: true, - path: '/', - sameSite: 'strict', - secure: await getHttpsEnabled() + path: "/", + sameSite: "strict", + secure: await getHttpsEnabled(), }); interface VerifyMfaTokenRes { @@ -319,7 +319,7 @@ export const verifyMfaToken = async (req: Request, res: Response) => { publicKey: user.publicKey as string, encryptedPrivateKey: user.encryptedPrivateKey as string, iv: user.iv as string, - tag: user.tag as string + tag: user.tag as string, } if (user?.protectedKey && user?.protectedKeyIV && user?.protectedKeyTag) { @@ -330,14 +330,14 @@ export const verifyMfaToken = async (req: Request, res: Response) => { const loginAction = await EELogService.createAction({ name: ACTION_LOGIN, - userId: user._id + userId: user._id, }); loginAction && await EELogService.createLog({ userId: user._id, actions: [loginAction], - channel: getChannelFromUserAgent(req.headers['user-agent']), - ipAddress: req.realIP + channel: getChannelFromUserAgent(req.headers["user-agent"]), + ipAddress: req.realIP, }); return res.status(200).send(resObj); diff --git a/backend/src/controllers/v2/environmentController.ts b/backend/src/controllers/v2/environmentController.ts index bf6d7d3c59..e1381db542 100644 --- a/backend/src/controllers/v2/environmentController.ts +++ b/backend/src/controllers/v2/environmentController.ts @@ -1,17 +1,17 @@ -import { Request, Response } from 'express'; +import { Request, Response } from "express"; import { + Integration, + Membership, Secret, ServiceToken, - Workspace, - Integration, ServiceTokenData, - Membership, -} from '../../models'; -import { SecretVersion } from '../../ee/models'; -import { EELicenseService } from '../../ee/services'; -import { BadRequestError, WorkspaceNotFoundError } from '../../utils/errors'; -import _ from 'lodash'; -import { PERMISSION_READ_SECRETS, PERMISSION_WRITE_SECRETS } from '../../variables'; + Workspace, +} from "../../models"; +import { SecretVersion } from "../../ee/models"; +import { EELicenseService } from "../../ee/services"; +import { BadRequestError, WorkspaceNotFoundError } from "../../utils/errors"; +import _ from "lodash"; +import { PERMISSION_READ_SECRETS, PERMISSION_WRITE_SECRETS } from "../../variables"; /** * Create new workspace environment named [environmentName] under workspace with id @@ -38,7 +38,7 @@ export const createWorkspaceEnvironment = async ( // case: number of environments used exceeds the number of environments allowed return res.status(400).send({ - message: 'Failed to create environment due to environment limit reached. Upgrade plan to create more environments.' + message: "Failed to create environment due to environment limit reached. Upgrade plan to create more environments.", }); } } @@ -49,7 +49,7 @@ export const createWorkspaceEnvironment = async ( ({ name, slug }) => slug === environmentSlug || environmentName === name ) ) { - throw new Error('Failed to create workspace environment'); + throw new Error("Failed to create workspace environment"); } workspace?.environments.push({ @@ -61,7 +61,7 @@ export const createWorkspaceEnvironment = async ( await EELicenseService.refreshPlan(workspace.organization.toString(), workspaceId); return res.status(200).send({ - message: 'Successfully created new environment', + message: "Successfully created new environment", workspace: workspaceId, environment: { name: environmentName, @@ -85,13 +85,13 @@ export const renameWorkspaceEnvironment = async ( const { environmentName, environmentSlug, oldEnvironmentSlug } = req.body; // user should pass both new slug and env name if (!environmentSlug || !environmentName) { - throw new Error('Invalid environment given.'); + throw new Error("Invalid environment given."); } // atomic update the env to avoid conflict const workspace = await Workspace.findById(workspaceId).exec(); if (!workspace) { - throw new Error('Failed to create workspace environment'); + throw new Error("Failed to create workspace environment"); } const isEnvExist = workspace.environments.some( @@ -100,14 +100,14 @@ export const renameWorkspaceEnvironment = async ( (name === environmentName || slug === environmentSlug) ); if (isEnvExist) { - throw new Error('Invalid environment given'); + throw new Error("Invalid environment given"); } const envIndex = workspace?.environments.findIndex( ({ slug }) => slug === oldEnvironmentSlug ); if (envIndex === -1) { - throw new Error('Invalid environment given'); + throw new Error("Invalid environment given"); } workspace.environments[envIndex].name = environmentName; @@ -137,7 +137,7 @@ export const renameWorkspaceEnvironment = async ( await Membership.updateMany( { workspace: workspaceId, - "deniedPermissions.environmentSlug": oldEnvironmentSlug + "deniedPermissions.environmentSlug": oldEnvironmentSlug, }, { $set: { "deniedPermissions.$[element].environmentSlug": environmentSlug } }, { arrayFilters: [{ "element.environmentSlug": oldEnvironmentSlug }] } @@ -145,7 +145,7 @@ export const renameWorkspaceEnvironment = async ( return res.status(200).send({ - message: 'Successfully update environment', + message: "Successfully update environment", workspace: workspaceId, environment: { name: environmentName, @@ -169,14 +169,14 @@ export const deleteWorkspaceEnvironment = async ( // atomic update the env to avoid conflict const workspace = await Workspace.findById(workspaceId).exec(); if (!workspace) { - throw new Error('Failed to create workspace environment'); + throw new Error("Failed to create workspace environment"); } const envIndex = workspace?.environments.findIndex( ({ slug }) => slug === environmentSlug ); if (envIndex === -1) { - throw new Error('Invalid environment given'); + throw new Error("Invalid environment given"); } workspace.environments.splice(envIndex, 1); @@ -211,7 +211,7 @@ export const deleteWorkspaceEnvironment = async ( await EELicenseService.refreshPlan(workspace.organization.toString(), workspaceId); return res.status(200).send({ - message: 'Successfully deleted environment', + message: "Successfully deleted environment", workspace: workspaceId, environment: environmentSlug, }); @@ -225,7 +225,7 @@ export const getAllAccessibleEnvironmentsOfWorkspace = async ( const { workspaceId } = req.params; const workspacesUserIsMemberOf = await Membership.findOne({ workspace: workspaceId, - user: req.user + user: req.user, }) if (!workspacesUserIsMemberOf) { @@ -249,7 +249,7 @@ export const getAllAccessibleEnvironmentsOfWorkspace = async ( name: environment.name, slug: environment.slug, isWriteDenied: isWriteBlocked, - isReadDenied: isReadBlocked + isReadDenied: isReadBlocked, }) } }) diff --git a/backend/src/controllers/v2/index.ts b/backend/src/controllers/v2/index.ts index db78fa503b..5496097db7 100644 --- a/backend/src/controllers/v2/index.ts +++ b/backend/src/controllers/v2/index.ts @@ -1,15 +1,15 @@ -import * as authController from './authController'; -import * as signupController from './signupController'; -import * as usersController from './usersController'; -import * as organizationsController from './organizationsController'; -import * as workspaceController from './workspaceController'; -import * as serviceTokenDataController from './serviceTokenDataController'; -import * as apiKeyDataController from './apiKeyDataController'; -import * as secretController from './secretController'; -import * as secretsController from './secretsController'; -import * as serviceAccountsController from './serviceAccountsController'; -import * as environmentController from './environmentController'; -import * as tagController from './tagController'; +import * as authController from "./authController"; +import * as signupController from "./signupController"; +import * as usersController from "./usersController"; +import * as organizationsController from "./organizationsController"; +import * as workspaceController from "./workspaceController"; +import * as serviceTokenDataController from "./serviceTokenDataController"; +import * as apiKeyDataController from "./apiKeyDataController"; +import * as secretController from "./secretController"; +import * as secretsController from "./secretsController"; +import * as serviceAccountsController from "./serviceAccountsController"; +import * as environmentController from "./environmentController"; +import * as tagController from "./tagController"; export { authController, @@ -23,5 +23,5 @@ export { secretsController, serviceAccountsController, environmentController, - tagController + tagController, } diff --git a/backend/src/controllers/v2/organizationsController.ts b/backend/src/controllers/v2/organizationsController.ts index 3bfd9085e1..301cac9d09 100644 --- a/backend/src/controllers/v2/organizationsController.ts +++ b/backend/src/controllers/v2/organizationsController.ts @@ -1,13 +1,13 @@ -import { Request, Response } from 'express'; -import { Types } from 'mongoose'; +import { Request, Response } from "express"; +import { Types } from "mongoose"; import { - MembershipOrg, Membership, + MembershipOrg, + ServiceAccount, Workspace, - ServiceAccount -} from '../../models'; -import { deleteMembershipOrg } from '../../helpers/membershipOrg'; -import { updateSubscriptionOrgQuantity } from '../../helpers/organization'; +} from "../../models"; +import { deleteMembershipOrg } from "../../helpers/membershipOrg"; +import { updateSubscriptionOrgQuantity } from "../../helpers/organization"; /** * Return memberships for organization with id [organizationId] @@ -51,11 +51,11 @@ export const getOrganizationMemberships = async (req: Request, res: Response) => const { organizationId } = req.params; const memberships = await MembershipOrg.find({ - organization: organizationId - }).populate('user', '+publicKey'); + organization: organizationId, + }).populate("user", "+publicKey"); return res.status(200).send({ - memberships + memberships, }); } @@ -124,14 +124,14 @@ export const updateOrganizationMembership = async (req: Request, res: Response) const membership = await MembershipOrg.findByIdAndUpdate( membershipId, { - role + role, }, { - new: true + new: true, } ); return res.status(200).send({ - membership + membership, }); } @@ -182,15 +182,15 @@ export const deleteOrganizationMembership = async (req: Request, res: Response) // delete organization membership const membership = await deleteMembershipOrg({ - membershipOrgId: membershipId + membershipOrgId: membershipId, }); await updateSubscriptionOrgQuantity({ - organizationId: membership.organization.toString() + organizationId: membership.organization.toString(), }); return res.status(200).send({ - membership + membership, }); } @@ -240,23 +240,23 @@ export const getOrganizationWorkspaces = async (req: Request, res: Response) => ( await Workspace.find( { - organization: organizationId + organization: organizationId, }, - '_id' + "_id" ) ).map((w) => w._id.toString()) ); const workspaces = ( await Membership.find({ - user: req.user._id - }).populate('workspace') + user: req.user._id, + }).populate("workspace") ) .filter((m) => workspacesSet.has(m.workspace._id.toString())) .map((m) => m.workspace); return res.status(200).send({ - workspaces + workspaces, }); } @@ -269,10 +269,10 @@ export const getOrganizationServiceAccounts = async (req: Request, res: Response const { organizationId } = req.params; const serviceAccounts = await ServiceAccount.find({ - organization: new Types.ObjectId(organizationId) + organization: new Types.ObjectId(organizationId), }); return res.status(200).send({ - serviceAccounts + serviceAccounts, }); } diff --git a/backend/src/controllers/v2/secretController.ts b/backend/src/controllers/v2/secretController.ts index fecba43d6e..1b6038f0e7 100644 --- a/backend/src/controllers/v2/secretController.ts +++ b/backend/src/controllers/v2/secretController.ts @@ -2,24 +2,39 @@ import to from "await-to-js"; import { Request, Response } from "express"; import mongoose, { Types } from "mongoose"; import Secret, { ISecret } from "../../models/secret"; -import { CreateSecretRequestBody, ModifySecretRequestBody, SanitizedSecretForCreate, SanitizedSecretModify } from "../../types/secret"; +import { + CreateSecretRequestBody, + ModifySecretRequestBody, + SanitizedSecretForCreate, + SanitizedSecretModify +} from "../../types/secret"; const { ValidationError } = mongoose.Error; -import { BadRequestError, InternalServerError, UnauthorizedRequestError, ValidationError as RouteValidationError } from '../../utils/errors'; -import { AnyBulkWriteOperation } from 'mongodb'; -import { ALGORITHM_AES_256_GCM, ENCODING_SCHEME_UTF8, SECRET_PERSONAL, SECRET_SHARED } from "../../variables"; -import { TelemetryService } from '../../services'; +import { + BadRequestError, + InternalServerError, + ValidationError as RouteValidationError, + UnauthorizedRequestError +} from "../../utils/errors"; +import { AnyBulkWriteOperation } from "mongodb"; +import { + ALGORITHM_AES_256_GCM, + ENCODING_SCHEME_UTF8, + SECRET_PERSONAL, + SECRET_SHARED +} from "../../variables"; +import { TelemetryService } from "../../services"; import { User } from "../../models"; -import { AccountNotFoundError } from '../../utils/errors'; +import { AccountNotFoundError } from "../../utils/errors"; /** * Create secret for workspace with id [workspaceId] and environment [environment] - * @param req - * @param res + * @param req + * @param res */ export const createSecret = async (req: Request, res: Response) => { const postHogClient = await TelemetryService.getPostHogClient(); const secretToCreate: CreateSecretRequestBody = req.body.secret; - const { workspaceId, environment } = req.params + const { workspaceId, environment } = req.params; const sanitizedSecret: SanitizedSecretForCreate = { secretKeyCiphertext: secretToCreate.secretKeyCiphertext, secretKeyIV: secretToCreate.secretKeyIV, @@ -39,45 +54,44 @@ export const createSecret = async (req: Request, res: Response) => { user: new Types.ObjectId(req.user._id), algorithm: ALGORITHM_AES_256_GCM, keyEncoding: ENCODING_SCHEME_UTF8 - } + }; - - const [error, secret] = await to(Secret.create(sanitizedSecret).then()) + const [error, secret] = await to(Secret.create(sanitizedSecret).then()); if (error instanceof ValidationError) { - throw RouteValidationError({ message: error.message, stack: error.stack }) + throw RouteValidationError({ message: error.message, stack: error.stack }); } if (postHogClient) { postHogClient.capture({ - event: 'secrets added', + event: "secrets added", distinctId: req.user.email, properties: { numberOfSecrets: 1, workspaceId, environment, - channel: req.headers?.['user-agent']?.toLowerCase().includes('mozilla') ? 'web' : 'cli', - userAgent: req.headers?.['user-agent'] + channel: req.headers?.["user-agent"]?.toLowerCase().includes("mozilla") ? "web" : "cli", + userAgent: req.headers?.["user-agent"] } }); } res.status(200).send({ secret - }) -} + }); +}; /** * Create many secrets for workspace wiht id [workspaceId] and environment [environment] - * @param req - * @param res + * @param req + * @param res */ export const createSecrets = async (req: Request, res: Response) => { const postHogClient = await TelemetryService.getPostHogClient(); const secretsToCreate: CreateSecretRequestBody[] = req.body.secrets; - const { workspaceId, environment } = req.params - const sanitizedSecretesToCreate: SanitizedSecretForCreate[] = [] + const { workspaceId, environment } = req.params; + const sanitizedSecretesToCreate: SanitizedSecretForCreate[] = []; - secretsToCreate.forEach(rawSecret => { + secretsToCreate.forEach((rawSecret) => { const safeUpdateFields: SanitizedSecretForCreate = { secretKeyCiphertext: rawSecret.secretKeyCiphertext, secretKeyIV: rawSecret.secretKeyIV, @@ -97,140 +111,163 @@ export const createSecrets = async (req: Request, res: Response) => { user: new Types.ObjectId(req.user._id), algorithm: ALGORITHM_AES_256_GCM, keyEncoding: ENCODING_SCHEME_UTF8 - } + }; - sanitizedSecretesToCreate.push(safeUpdateFields) - }) + sanitizedSecretesToCreate.push(safeUpdateFields); + }); - const [bulkCreateError, secrets] = await to(Secret.insertMany(sanitizedSecretesToCreate).then()) + const [bulkCreateError, secrets] = await to(Secret.insertMany(sanitizedSecretesToCreate).then()); if (bulkCreateError) { if (bulkCreateError instanceof ValidationError) { - throw RouteValidationError({ message: bulkCreateError.message, stack: bulkCreateError.stack }) + throw RouteValidationError({ + message: bulkCreateError.message, + stack: bulkCreateError.stack + }); } - throw InternalServerError({ message: "Unable to process your batch create request. Please try again", stack: bulkCreateError.stack }) + throw InternalServerError({ + message: "Unable to process your batch create request. Please try again", + stack: bulkCreateError.stack + }); } if (postHogClient) { postHogClient.capture({ - event: 'secrets added', + event: "secrets added", distinctId: req.user.email, properties: { numberOfSecrets: (secretsToCreate ?? []).length, workspaceId, environment, - channel: req.headers?.['user-agent']?.toLowerCase().includes('mozilla') ? 'web' : 'cli', - userAgent: req.headers?.['user-agent'] + channel: req.headers?.["user-agent"]?.toLowerCase().includes("mozilla") ? "web" : "cli", + userAgent: req.headers?.["user-agent"] } }); } res.status(200).send({ secrets - }) -} + }); +}; /** * Delete secrets in workspace with id [workspaceId] and environment [environment] - * @param req - * @param res + * @param req + * @param res */ export const deleteSecrets = async (req: Request, res: Response) => { const postHogClient = await TelemetryService.getPostHogClient(); - const { workspaceId, environmentName } = req.params - const secretIdsToDelete: string[] = req.body.secretIds + const { workspaceId, environmentName } = req.params; + const secretIdsToDelete: string[] = req.body.secretIds; - const [secretIdsUserCanDeleteError, secretIdsUserCanDelete] = await to(Secret.find({ workspace: workspaceId, environment: environmentName }, { _id: 1 }).then()) + const [secretIdsUserCanDeleteError, secretIdsUserCanDelete] = await to( + Secret.find({ workspace: workspaceId, environment: environmentName }, { _id: 1 }).then() + ); if (secretIdsUserCanDeleteError) { - throw InternalServerError({ message: `Unable to fetch secrets you own: [error=${secretIdsUserCanDeleteError.message}]` }) + throw InternalServerError({ + message: `Unable to fetch secrets you own: [error=${secretIdsUserCanDeleteError.message}]` + }); } - const secretsUserCanDeleteSet: Set = new Set(secretIdsUserCanDelete.map(objectId => objectId._id.toString())); - const deleteOperationsToPerform: AnyBulkWriteOperation[] = [] + const secretsUserCanDeleteSet: Set = new Set( + secretIdsUserCanDelete.map((objectId) => objectId._id.toString()) + ); + const deleteOperationsToPerform: AnyBulkWriteOperation[] = []; let numSecretsDeleted = 0; - secretIdsToDelete.forEach(secretIdToDelete => { + secretIdsToDelete.forEach((secretIdToDelete) => { if (secretsUserCanDeleteSet.has(secretIdToDelete)) { - const deleteOperation = { deleteOne: { filter: { _id: new Types.ObjectId(secretIdToDelete) } } } - deleteOperationsToPerform.push(deleteOperation) + const deleteOperation = { + deleteOne: { filter: { _id: new Types.ObjectId(secretIdToDelete) } } + }; + deleteOperationsToPerform.push(deleteOperation); numSecretsDeleted++; } else { - throw RouteValidationError({ message: "You cannot delete secrets that you do not have access to" }) + throw RouteValidationError({ + message: "You cannot delete secrets that you do not have access to" + }); } - }) + }); - const [bulkDeleteError, bulkDelete] = await to(Secret.bulkWrite(deleteOperationsToPerform).then()) + const [bulkDeleteError] = await to(Secret.bulkWrite(deleteOperationsToPerform).then()); if (bulkDeleteError) { if (bulkDeleteError instanceof ValidationError) { - throw RouteValidationError({ message: "Unable to apply modifications, please try again", stack: bulkDeleteError.stack }) + throw RouteValidationError({ + message: "Unable to apply modifications, please try again", + stack: bulkDeleteError.stack + }); } - throw InternalServerError() + throw InternalServerError(); } if (postHogClient) { postHogClient.capture({ - event: 'secrets deleted', + event: "secrets deleted", distinctId: req.user.email, properties: { numberOfSecrets: numSecretsDeleted, environment: environmentName, workspaceId, - channel: req.headers?.['user-agent']?.toLowerCase().includes('mozilla') ? 'web' : 'cli', - userAgent: req.headers?.['user-agent'] + channel: req.headers?.["user-agent"]?.toLowerCase().includes("mozilla") ? "web" : "cli", + userAgent: req.headers?.["user-agent"] } }); } - res.status(200).send() -} + res.status(200).send(); +}; /** * Delete secret with id [secretId] - * @param req + * @param req * @param res */ export const deleteSecret = async (req: Request, res: Response) => { const postHogClient = await TelemetryService.getPostHogClient(); - await Secret.findByIdAndDelete(req._secret._id) + await Secret.findByIdAndDelete(req._secret._id); if (postHogClient) { postHogClient.capture({ - event: 'secrets deleted', + event: "secrets deleted", distinctId: req.user.email, properties: { numberOfSecrets: 1, workspaceId: req._secret.workspace.toString(), environment: req._secret.environment, - channel: req.headers?.['user-agent']?.toLowerCase().includes('mozilla') ? 'web' : 'cli', - userAgent: req.headers?.['user-agent'] + channel: req.headers?.["user-agent"]?.toLowerCase().includes("mozilla") ? "web" : "cli", + userAgent: req.headers?.["user-agent"] } }); } res.status(200).send({ secret: req._secret - }) -} + }); +}; /** * Update secrets for workspace with id [workspaceId] and environment [environment] - * @param req - * @param res - * @returns + * @param req + * @param res + * @returns */ export const updateSecrets = async (req: Request, res: Response) => { const postHogClient = await TelemetryService.getPostHogClient(); - const { workspaceId, environmentName } = req.params + const { workspaceId, environmentName } = req.params; const secretsModificationsRequested: ModifySecretRequestBody[] = req.body.secrets; - const [secretIdsUserCanModifyError, secretIdsUserCanModify] = await to(Secret.find({ workspace: workspaceId, environment: environmentName }, { _id: 1 }).then()) + const [secretIdsUserCanModifyError, secretIdsUserCanModify] = await to( + Secret.find({ workspace: workspaceId, environment: environmentName }, { _id: 1 }).then() + ); if (secretIdsUserCanModifyError) { - throw InternalServerError({ message: "Unable to fetch secrets you own" }) + throw InternalServerError({ message: "Unable to fetch secrets you own" }); } - const secretsUserCanModifySet: Set = new Set(secretIdsUserCanModify.map(objectId => objectId._id.toString())); - const updateOperationsToPerform: any = [] + const secretsUserCanModifySet: Set = new Set( + secretIdsUserCanModify.map((objectId) => objectId._id.toString()) + ); + const updateOperationsToPerform: any = []; - secretsModificationsRequested.forEach(userModifiedSecret => { + secretsModificationsRequested.forEach((userModifiedSecret) => { if (secretsUserCanModifySet.has(userModifiedSecret._id.toString())) { const sanitizedSecret: SanitizedSecretModify = { secretKeyCiphertext: userModifiedSecret.secretKeyCiphertext, @@ -244,56 +281,70 @@ export const updateSecrets = async (req: Request, res: Response) => { secretCommentCiphertext: userModifiedSecret.secretCommentCiphertext, secretCommentIV: userModifiedSecret.secretCommentIV, secretCommentTag: userModifiedSecret.secretCommentTag, - secretCommentHash: userModifiedSecret.secretCommentHash, - } + secretCommentHash: userModifiedSecret.secretCommentHash + }; - const updateOperation = { updateOne: { filter: { _id: userModifiedSecret._id, workspace: workspaceId }, update: { $inc: { version: 1 }, $set: sanitizedSecret } } } - updateOperationsToPerform.push(updateOperation) + const updateOperation = { + updateOne: { + filter: { _id: userModifiedSecret._id, workspace: workspaceId }, + update: { $inc: { version: 1 }, $set: sanitizedSecret } + } + }; + updateOperationsToPerform.push(updateOperation); } else { - throw UnauthorizedRequestError({ message: "You do not have permission to modify one or more of the requested secrets" }) + throw UnauthorizedRequestError({ + message: "You do not have permission to modify one or more of the requested secrets" + }); } - }) + }); - const [bulkModificationInfoError, bulkModificationInfo] = await to(Secret.bulkWrite(updateOperationsToPerform).then()) + const [bulkModificationInfoError, bulkModificationInfo] = await to( + Secret.bulkWrite(updateOperationsToPerform).then() + ); if (bulkModificationInfoError) { if (bulkModificationInfoError instanceof ValidationError) { - throw RouteValidationError({ message: "Unable to apply modifications, please try again", stack: bulkModificationInfoError.stack }) + throw RouteValidationError({ + message: "Unable to apply modifications, please try again", + stack: bulkModificationInfoError.stack + }); } - throw InternalServerError() + throw InternalServerError(); } if (postHogClient) { postHogClient.capture({ - event: 'secrets modified', + event: "secrets modified", distinctId: req.user.email, properties: { numberOfSecrets: (secretsModificationsRequested ?? []).length, environment: environmentName, workspaceId, - channel: req.headers?.['user-agent']?.toLowerCase().includes('mozilla') ? 'web' : 'cli', - userAgent: req.headers?.['user-agent'] + channel: req.headers?.["user-agent"]?.toLowerCase().includes("mozilla") ? "web" : "cli", + userAgent: req.headers?.["user-agent"] } }); } - return res.status(200).send() -} + return res.status(200).send(); +}; /** * Update a secret within workspace with id [workspaceId] and environment [environment] - * @param req - * @param res - * @returns + * @param req + * @param res + * @returns */ export const updateSecret = async (req: Request, res: Response) => { const postHogClient = await TelemetryService.getPostHogClient(); - const { workspaceId, environmentName } = req.params + const { workspaceId, environmentName } = req.params; const secretModificationsRequested: ModifySecretRequestBody = req.body.secret; - const [secretIdUserCanModifyError, secretIdUserCanModify] = await to(Secret.findOne({ workspace: workspaceId, environment: environmentName }, { _id: 1 }).then()) + const [secretIdUserCanModifyError, secretIdUserCanModify] = await to( + Secret.findOne({ workspace: workspaceId, environment: environmentName }, { _id: 1 }).then() + ); if (secretIdUserCanModifyError && !secretIdUserCanModify) { - throw BadRequestError() + throw BadRequestError(); } const sanitizedSecret: SanitizedSecretModify = { @@ -308,45 +359,53 @@ export const updateSecret = async (req: Request, res: Response) => { secretCommentCiphertext: secretModificationsRequested.secretCommentCiphertext, secretCommentIV: secretModificationsRequested.secretCommentIV, secretCommentTag: secretModificationsRequested.secretCommentTag, - secretCommentHash: secretModificationsRequested.secretCommentHash, - } + secretCommentHash: secretModificationsRequested.secretCommentHash + }; - const [error, singleModificationUpdate] = await to(Secret.updateOne({ _id: secretModificationsRequested._id, workspace: workspaceId }, { $inc: { version: 1 }, $set: sanitizedSecret }).then()) + const [error, singleModificationUpdate] = await to( + Secret.updateOne( + { _id: secretModificationsRequested._id, workspace: workspaceId }, + { $inc: { version: 1 }, $set: sanitizedSecret } + ).then() + ); if (error instanceof ValidationError) { - throw RouteValidationError({ message: "Unable to apply modifications, please try again", stack: error.stack }) + throw RouteValidationError({ + message: "Unable to apply modifications, please try again", + stack: error.stack + }); } if (postHogClient) { postHogClient.capture({ - event: 'secrets modified', + event: "secrets modified", distinctId: req.user.email, properties: { numberOfSecrets: 1, environment: environmentName, workspaceId, - channel: req.headers?.['user-agent']?.toLowerCase().includes('mozilla') ? 'web' : 'cli', - userAgent: req.headers?.['user-agent'] + channel: req.headers?.["user-agent"]?.toLowerCase().includes("mozilla") ? "web" : "cli", + userAgent: req.headers?.["user-agent"] } }); } - return res.status(200).send(singleModificationUpdate) -} + return res.status(200).send(singleModificationUpdate); +}; /** * Return secrets for workspace with id [workspaceId], environment [environment] and user * with id [req.user._id] - * @param req - * @param res - * @returns + * @param req + * @param res + * @returns */ export const getSecrets = async (req: Request, res: Response) => { const postHogClient = await TelemetryService.getPostHogClient(); const { environment } = req.query; const { workspaceId } = req.params; - let userId: Types.ObjectId | undefined = undefined // used for getting personal secrets for user - let userEmail: string | undefined = undefined // used for posthog + let userId: Types.ObjectId | undefined = undefined; // used for getting personal secrets for user + let userEmail: string | undefined = undefined; // used for posthog if (req.user) { userId = req.user._id; userEmail = req.user.email; @@ -354,47 +413,50 @@ export const getSecrets = async (req: Request, res: Response) => { if (req.serviceTokenData) { userId = req.serviceTokenData.user; - - const user = await User.findById(req.serviceTokenData.user, 'email'); + + const user = await User.findById(req.serviceTokenData.user, "email"); if (!user) throw AccountNotFoundError(); userEmail = user.email; } - const [err, secrets] = await to(Secret.find( - { + const [err, secrets] = await to( + Secret.find({ workspace: workspaceId, environment, $or: [{ user: userId }, { user: { $exists: false } }], type: { $in: [SECRET_SHARED, SECRET_PERSONAL] } - } - ).then()) + }).then() + ); if (err) { - throw RouteValidationError({ message: "Failed to get secrets, please try again", stack: err.stack }) + throw RouteValidationError({ + message: "Failed to get secrets, please try again", + stack: err.stack + }); } if (postHogClient) { postHogClient.capture({ - event: 'secrets pulled', + event: "secrets pulled", distinctId: userEmail, properties: { numberOfSecrets: (secrets ?? []).length, environment, workspaceId, - channel: req.headers?.['user-agent']?.toLowerCase().includes('mozilla') ? 'web' : 'cli', - userAgent: req.headers?.['user-agent'] + channel: req.headers?.["user-agent"]?.toLowerCase().includes("mozilla") ? "web" : "cli", + userAgent: req.headers?.["user-agent"] } }); } - return res.json(secrets) -} + return res.json(secrets); +}; /** * Return secret with id [secretId] - * @param req - * @param res - * @returns + * @param req + * @param res + * @returns */ export const getSecret = async (req: Request, res: Response) => { // if (postHogClient) { @@ -414,4 +476,4 @@ export const getSecret = async (req: Request, res: Response) => { return res.status(200).send({ secret: req._secret }); -} \ No newline at end of file +}; diff --git a/backend/src/controllers/v2/secretsController.ts b/backend/src/controllers/v2/secretsController.ts index 256ad248c2..a760a511cd 100644 --- a/backend/src/controllers/v2/secretsController.ts +++ b/backend/src/controllers/v2/secretsController.ts @@ -3,19 +3,19 @@ import { Request, Response } from "express"; import { ISecret, Secret, ServiceTokenData } from "../../models"; import { IAction, SecretVersion } from "../../ee/models"; import { - SECRET_PERSONAL, ACTION_ADD_SECRETS, + ACTION_DELETE_SECRETS, ACTION_READ_SECRETS, ACTION_UPDATE_SECRETS, - ACTION_DELETE_SECRETS, ALGORITHM_AES_256_GCM, ENCODING_SCHEME_UTF8, + SECRET_PERSONAL, } from "../../variables"; import { BadRequestError, UnauthorizedRequestError } from "../../utils/errors"; import { EventService } from "../../services"; import { eventPushSecrets } from "../../events"; -import { EESecretService, EELogService } from "../../ee/services"; -import { TelemetryService, SecretService } from "../../services"; +import { EELogService, EESecretService } from "../../ee/services"; +import { SecretService, TelemetryService } from "../../services"; import { getChannelFromUserAgent } from "../../utils/posthog"; import { PERMISSION_WRITE_SECRETS } from "../../variables"; import { @@ -25,7 +25,7 @@ import { } from "../../ee/helpers/checkMembershipPermissions"; import Tag from "../../models/tag"; import _ from "lodash"; -import { BatchSecretRequest, BatchSecret } from "../../types/secret"; +import { BatchSecret, BatchSecretRequest } from "../../types/secret"; import Folder from "../../models/folder"; import { getFolderByPath, diff --git a/backend/src/controllers/v2/serviceAccountsController.ts b/backend/src/controllers/v2/serviceAccountsController.ts index d0ec62e1b1..0e655782a3 100644 --- a/backend/src/controllers/v2/serviceAccountsController.ts +++ b/backend/src/controllers/v2/serviceAccountsController.ts @@ -1,18 +1,18 @@ -import { Request, Response } from 'express'; -import { Types } from 'mongoose'; -import crypto from 'crypto'; -import bcrypt from 'bcrypt'; +import { Request, Response } from "express"; +import { Types } from "mongoose"; +import crypto from "crypto"; +import bcrypt from "bcrypt"; import { ServiceAccount, ServiceAccountKey, ServiceAccountOrganizationPermission, - ServiceAccountWorkspacePermission -} from '../../models'; + ServiceAccountWorkspacePermission, +} from "../../models"; import { - CreateServiceAccountDto -} from '../../interfaces/serviceAccounts/dto'; -import { BadRequestError, ServiceAccountNotFoundError } from '../../utils/errors'; -import { getSaltRounds } from '../../config'; + CreateServiceAccountDto, +} from "../../interfaces/serviceAccounts/dto"; +import { BadRequestError, ServiceAccountNotFoundError } from "../../utils/errors"; +import { getSaltRounds } from "../../config"; /** * Return service account tied to the request (service account) client @@ -23,11 +23,11 @@ export const getCurrentServiceAccount = async (req: Request, res: Response) => { const serviceAccount = await ServiceAccount.findById(req.serviceAccount._id); if (!serviceAccount) { - throw ServiceAccountNotFoundError({ message: 'Failed to find service account' }); + throw ServiceAccountNotFoundError({ message: "Failed to find service account" }); } return res.status(200).send({ - serviceAccount + serviceAccount, }); } @@ -42,11 +42,11 @@ export const getServiceAccountById = async (req: Request, res: Response) => { const serviceAccount = await ServiceAccount.findById(serviceAccountId); if (!serviceAccount) { - throw ServiceAccountNotFoundError({ message: 'Failed to find service account' }); + throw ServiceAccountNotFoundError({ message: "Failed to find service account" }); } return res.status(200).send({ - serviceAccount + serviceAccount, }); } @@ -71,7 +71,7 @@ export const createServiceAccount = async (req: Request, res: Response) => { expiresAt.setSeconds(expiresAt.getSeconds() + expiresIn); } - const secret = crypto.randomBytes(16).toString('base64'); + const secret = crypto.randomBytes(16).toString("base64"); const secretHash = await bcrypt.hash(secret, await getSaltRounds()); // create service account @@ -82,7 +82,7 @@ export const createServiceAccount = async (req: Request, res: Response) => { publicKey, lastUsed: new Date(), expiresAt, - secretHash + secretHash, }).save(); const serviceAccountObj = serviceAccount.toObject(); @@ -91,14 +91,14 @@ export const createServiceAccount = async (req: Request, res: Response) => { // provision default org-level permission for service account await new ServiceAccountOrganizationPermission({ - serviceAccount: serviceAccount._id + serviceAccount: serviceAccount._id, }).save(); - const secretId = Buffer.from(serviceAccount._id.toString(), 'hex').toString('base64'); + const secretId = Buffer.from(serviceAccount._id.toString(), "hex").toString("base64"); return res.status(200).send({ serviceAccountAccessKey: `sa.${secretId}.${secret}`, - serviceAccount: serviceAccountObj + serviceAccount: serviceAccountObj, }); } @@ -114,18 +114,18 @@ export const changeServiceAccountName = async (req: Request, res: Response) => { const serviceAccount = await ServiceAccount.findOneAndUpdate( { - _id: new Types.ObjectId(serviceAccountId) + _id: new Types.ObjectId(serviceAccountId), }, { - name + name, }, { - new: true + new: true, } ); return res.status(200).send({ - serviceAccount + serviceAccount, }); } @@ -140,7 +140,7 @@ export const addServiceAccountKey = async (req: Request, res: Response) => { const { workspaceId, encryptedKey, - nonce + nonce, } = req.body; const serviceAccountKey = await new ServiceAccountKey({ @@ -148,7 +148,7 @@ export const addServiceAccountKey = async (req: Request, res: Response) => { nonce, sender: req.user._id, serviceAccount: req.serviceAccount._d, - workspace: new Types.ObjectId(workspaceId) + workspace: new Types.ObjectId(workspaceId), }).save(); return serviceAccountKey; @@ -161,11 +161,11 @@ export const addServiceAccountKey = async (req: Request, res: Response) => { */ export const getServiceAccountWorkspacePermissions = async (req: Request, res: Response) => { const serviceAccountWorkspacePermissions = await ServiceAccountWorkspacePermission.find({ - serviceAccount: req.serviceAccount._id - }).populate('workspace'); + serviceAccount: req.serviceAccount._id, + }).populate("workspace"); return res.status(200).send({ - serviceAccountWorkspacePermissions + serviceAccountWorkspacePermissions, }); } @@ -182,34 +182,34 @@ export const addServiceAccountWorkspacePermission = async (req: Request, res: Re read = false, write = false, encryptedKey, - nonce + nonce, } = req.body; if (!req.membership.workspace.environments.some((e: { name: string; slug: string }) => e.slug === environment)) { return res.status(400).send({ - message: 'Failed to validate workspace environment' + message: "Failed to validate workspace environment", }); } const existingPermission = await ServiceAccountWorkspacePermission.findOne({ serviceAccount: new Types.ObjectId(serviceAccountId), workspace: new Types.ObjectId(workspaceId), - environment + environment, }); - if (existingPermission) throw BadRequestError({ message: 'Failed to add workspace permission to service account due to already-existing ' }); + if (existingPermission) throw BadRequestError({ message: "Failed to add workspace permission to service account due to already-existing " }); const serviceAccountWorkspacePermission = await new ServiceAccountWorkspacePermission({ serviceAccount: new Types.ObjectId(serviceAccountId), workspace: new Types.ObjectId(workspaceId), environment, read, - write + write, }).save(); const existingServiceAccountKey = await ServiceAccountKey.findOne({ serviceAccount: new Types.ObjectId(serviceAccountId), - workspace: new Types.ObjectId(workspaceId) + workspace: new Types.ObjectId(workspaceId), }); if (!existingServiceAccountKey) { @@ -218,12 +218,12 @@ export const addServiceAccountWorkspacePermission = async (req: Request, res: Re nonce, sender: req.user._id, serviceAccount: new Types.ObjectId(serviceAccountId), - workspace: new Types.ObjectId(workspaceId) + workspace: new Types.ObjectId(workspaceId), }).save(); } return res.status(200).send({ - serviceAccountWorkspacePermission + serviceAccountWorkspacePermission, }); } @@ -240,19 +240,19 @@ export const deleteServiceAccountWorkspacePermission = async (req: Request, res: const { serviceAccount, workspace } = serviceAccountWorkspacePermission; const count = await ServiceAccountWorkspacePermission.countDocuments({ serviceAccount, - workspace + workspace, }); if (count === 0) { await ServiceAccountKey.findOneAndDelete({ serviceAccount, - workspace + workspace, }); } } return res.status(200).send({ - serviceAccountWorkspacePermission + serviceAccountWorkspacePermission, }); } @@ -269,20 +269,20 @@ export const deleteServiceAccount = async (req: Request, res: Response) => { if (serviceAccount) { await ServiceAccountKey.deleteMany({ - serviceAccount: serviceAccount._id + serviceAccount: serviceAccount._id, }); await ServiceAccountOrganizationPermission.deleteMany({ - serviceAccount: new Types.ObjectId(serviceAccountId) + serviceAccount: new Types.ObjectId(serviceAccountId), }); await ServiceAccountWorkspacePermission.deleteMany({ - serviceAccount: new Types.ObjectId(serviceAccountId) + serviceAccount: new Types.ObjectId(serviceAccountId), }); } return res.status(200).send({ - serviceAccount + serviceAccount, }); } @@ -297,10 +297,10 @@ export const getServiceAccountKeys = async (req: Request, res: Response) => { const serviceAccountKeys = await ServiceAccountKey.find({ serviceAccount: req.serviceAccount._id, - ...(workspaceId ? { workspace: new Types.ObjectId(workspaceId) } : {}) + ...(workspaceId ? { workspace: new Types.ObjectId(workspaceId) } : {}), }); return res.status(200).send({ - serviceAccountKeys + serviceAccountKeys, }); } \ No newline at end of file diff --git a/backend/src/controllers/v2/serviceTokenDataController.ts b/backend/src/controllers/v2/serviceTokenDataController.ts index 21cc29b04d..471ac1f3f6 100644 --- a/backend/src/controllers/v2/serviceTokenDataController.ts +++ b/backend/src/controllers/v2/serviceTokenDataController.ts @@ -1,13 +1,10 @@ import { Request, Response } from "express"; import crypto from "crypto"; import bcrypt from "bcrypt"; -import { User, ServiceAccount, ServiceTokenData } from "../../models"; -import { userHasWorkspaceAccess } from "../../ee/helpers/checkMembershipPermissions"; +import { ServiceAccount, ServiceTokenData, User } from "../../models"; import { - PERMISSION_READ_SECRETS, AUTH_MODE_JWT, AUTH_MODE_SERVICE_ACCOUNT, - AUTH_MODE_SERVICE_TOKEN, } from "../../variables"; import { getSaltRounds } from "../../config"; import { BadRequestError } from "../../utils/errors"; diff --git a/backend/src/controllers/v2/signupController.ts b/backend/src/controllers/v2/signupController.ts index ada119ee92..45a7db963e 100644 --- a/backend/src/controllers/v2/signupController.ts +++ b/backend/src/controllers/v2/signupController.ts @@ -1,14 +1,14 @@ -import { Request, Response } from 'express'; -import { User, MembershipOrg } from '../../models'; -import { completeAccount } from '../../helpers/user'; +import { Request, Response } from "express"; +import { MembershipOrg, User } from "../../models"; +import { completeAccount } from "../../helpers/user"; import { - initializeDefaultOrg -} from '../../helpers/signup'; -import { issueAuthTokens } from '../../helpers/auth'; -import { INVITED, ACCEPTED } from '../../variables'; -import { standardRequest } from '../../config/request'; -import { getLoopsApiKey, getHttpsEnabled } from '../../config'; -import { updateSubscriptionOrgQuantity } from '../../helpers/organization'; + initializeDefaultOrg, +} from "../../helpers/signup"; +import { issueAuthTokens } from "../../helpers/auth"; +import { ACCEPTED, INVITED } from "../../variables"; +import { standardRequest } from "../../config/request"; +import { getHttpsEnabled, getLoopsApiKey } from "../../config"; +import { updateSubscriptionOrgQuantity } from "../../helpers/organization"; /** * Complete setting up user by adding their personal and auth information as part of the @@ -32,7 +32,7 @@ export const completeAccountSignup = async (req: Request, res: Response) => { encryptedPrivateKeyTag, salt, verifier, - organizationName + organizationName, }: { email: string; firstName: string; @@ -56,7 +56,7 @@ export const completeAccountSignup = async (req: Request, res: Response) => { // case 1: user doesn't exist. // case 2: user has already completed account return res.status(403).send({ - error: 'Failed to complete account for complete user' + error: "Failed to complete account for complete user", }); } @@ -74,28 +74,28 @@ export const completeAccountSignup = async (req: Request, res: Response) => { encryptedPrivateKeyIV, encryptedPrivateKeyTag, salt, - verifier + verifier, }); if (!user) - throw new Error('Failed to complete account for non-existent user'); // ensure user is non-null + throw new Error("Failed to complete account for non-existent user"); // ensure user is non-null // initialize default organization and workspace await initializeDefaultOrg({ organizationName, - user + user, }); // update organization membership statuses that are // invited to completed with user attached const membershipsToUpdate = await MembershipOrg.find({ inviteEmail: email, - status: INVITED + status: INVITED, }); membershipsToUpdate.forEach(async (membership) => { await updateSubscriptionOrgQuantity({ - organizationId: membership.organization.toString() + organizationId: membership.organization.toString(), }); }); @@ -104,11 +104,11 @@ export const completeAccountSignup = async (req: Request, res: Response) => { await MembershipOrg.updateMany( { inviteEmail: email, - status: INVITED + status: INVITED, }, { user, - status: ACCEPTED + status: ACCEPTED, } ); @@ -116,7 +116,7 @@ export const completeAccountSignup = async (req: Request, res: Response) => { const tokens = await issueAuthTokens({ userId: user._id, ip: req.realIP, - userAgent: req.headers['user-agent'] ?? '' + userAgent: req.headers["user-agent"] ?? "", }); token = tokens.token; @@ -127,27 +127,27 @@ export const completeAccountSignup = async (req: Request, res: Response) => { "email": email, "eventName": "Sign Up", "firstName": firstName, - "lastName": lastName + "lastName": lastName, }, { headers: { "Accept": "application/json", - "Authorization": "Bearer " + (await getLoopsApiKey()) + "Authorization": "Bearer " + (await getLoopsApiKey()), }, }); } // store (refresh) token in httpOnly cookie - res.cookie('jid', tokens.refreshToken, { + res.cookie("jid", tokens.refreshToken, { httpOnly: true, - path: '/', - sameSite: 'strict', - secure: await getHttpsEnabled() + path: "/", + sameSite: "strict", + secure: await getHttpsEnabled(), }); return res.status(200).send({ - message: 'Successfully set up account', + message: "Successfully set up account", user, - token + token, }); }; @@ -172,7 +172,7 @@ export const completeAccountInvite = async (req: Request, res: Response) => { encryptedPrivateKeyIV, encryptedPrivateKeyTag, salt, - verifier + verifier, } = req.body; // get user @@ -182,16 +182,16 @@ export const completeAccountInvite = async (req: Request, res: Response) => { // case 1: user doesn't exist. // case 2: user has already completed account return res.status(403).send({ - error: 'Failed to complete account for complete user' + error: "Failed to complete account for complete user", }); } const membershipOrg = await MembershipOrg.findOne({ inviteEmail: email, - status: INVITED + status: INVITED, }); - if (!membershipOrg) throw new Error('Failed to find invitations for email'); + if (!membershipOrg) throw new Error("Failed to find invitations for email"); // complete setting up user's account user = await completeAccount({ @@ -207,33 +207,33 @@ export const completeAccountInvite = async (req: Request, res: Response) => { encryptedPrivateKeyIV, encryptedPrivateKeyTag, salt, - verifier + verifier, }); if (!user) - throw new Error('Failed to complete account for non-existent user'); + throw new Error("Failed to complete account for non-existent user"); // update organization membership statuses that are // invited to completed with user attached const membershipsToUpdate = await MembershipOrg.find({ inviteEmail: email, - status: INVITED + status: INVITED, }); membershipsToUpdate.forEach(async (membership) => { await updateSubscriptionOrgQuantity({ - organizationId: membership.organization.toString() + organizationId: membership.organization.toString(), }); }); await MembershipOrg.updateMany( { inviteEmail: email, - status: INVITED + status: INVITED, }, { user, - status: ACCEPTED + status: ACCEPTED, } ); @@ -241,22 +241,22 @@ export const completeAccountInvite = async (req: Request, res: Response) => { const tokens = await issueAuthTokens({ userId: user._id, ip: req.realIP, - userAgent: req.headers['user-agent'] ?? '' + userAgent: req.headers["user-agent"] ?? "", }); token = tokens.token; // store (refresh) token in httpOnly cookie - res.cookie('jid', tokens.refreshToken, { + res.cookie("jid", tokens.refreshToken, { httpOnly: true, - path: '/', - sameSite: 'strict', - secure: await getHttpsEnabled() + path: "/", + sameSite: "strict", + secure: await getHttpsEnabled(), }); return res.status(200).send({ - message: 'Successfully set up account', + message: "Successfully set up account", user, - token + token, }); }; diff --git a/backend/src/controllers/v2/tagController.ts b/backend/src/controllers/v2/tagController.ts index 0175b359a8..926df0ca5f 100644 --- a/backend/src/controllers/v2/tagController.ts +++ b/backend/src/controllers/v2/tagController.ts @@ -1,71 +1,65 @@ -import { Request, Response } from 'express'; -import { Types } from 'mongoose'; -import { - Membership, Secret, -} from '../../models'; -import Tag, { ITag } from '../../models/tag'; -import { Builder } from "builder-pattern" -import to from 'await-to-js'; -import { BadRequestError, UnauthorizedRequestError } from '../../utils/errors'; -import { MongoError } from 'mongodb'; -import { userHasWorkspaceAccess } from '../../ee/helpers/checkMembershipPermissions'; +import { Request, Response } from "express"; +import { Types } from "mongoose"; +import { Membership, Secret } from "../../models"; +import Tag, { ITag } from "../../models/tag"; +import { Builder } from "builder-pattern"; +import to from "await-to-js"; +import { BadRequestError, UnauthorizedRequestError } from "../../utils/errors"; +import { MongoError } from "mongodb"; export const createWorkspaceTag = async (req: Request, res: Response) => { - const { workspaceId } = req.params - const { name, slug } = req.body - const sanitizedTagToCreate = Builder() - .name(name) - .workspace(new Types.ObjectId(workspaceId)) - .slug(slug) - .user(new Types.ObjectId(req.user._id)) - .build(); + const { workspaceId } = req.params; + const { name, slug } = req.body; + const sanitizedTagToCreate = Builder() + .name(name) + .workspace(new Types.ObjectId(workspaceId)) + .slug(slug) + .user(new Types.ObjectId(req.user._id)) + .build(); - const [err, createdTag] = await to(Tag.create(sanitizedTagToCreate)) + const [err, createdTag] = await to(Tag.create(sanitizedTagToCreate)); - if (err) { - if ((err as MongoError).code === 11000) { - throw BadRequestError({ message: "Tags must be unique in a workspace" }) - } + if (err) { + if ((err as MongoError).code === 11000) { + throw BadRequestError({ message: "Tags must be unique in a workspace" }); + } - throw err - } + throw err; + } - res.json(createdTag) -} + res.json(createdTag); +}; export const deleteWorkspaceTag = async (req: Request, res: Response) => { - const { tagId } = req.params + const { tagId } = req.params; - const tagFromDB = await Tag.findById(tagId) - if (!tagFromDB) { - throw BadRequestError() - } + const tagFromDB = await Tag.findById(tagId); + if (!tagFromDB) { + throw BadRequestError(); + } - // can only delete if the request user is one that belongs to the same workspace as the tag - const membership = await Membership.findOne({ - user: req.user, - workspace: tagFromDB.workspace - }); + // can only delete if the request user is one that belongs to the same workspace as the tag + const membership = await Membership.findOne({ + user: req.user, + workspace: tagFromDB.workspace + }); - if (!membership) { - UnauthorizedRequestError({ message: 'Failed to validate membership' }); - } + if (!membership) { + UnauthorizedRequestError({ message: "Failed to validate membership" }); + } - const result = await Tag.findByIdAndDelete(tagId); + const result = await Tag.findByIdAndDelete(tagId); - // remove the tag from secrets - await Secret.updateMany( - { tags: { $in: [tagId] } }, - { $pull: { tags: tagId } } - ); + // remove the tag from secrets + await Secret.updateMany({ tags: { $in: [tagId] } }, { $pull: { tags: tagId } }); - res.json(result); -} + res.json(result); +}; export const getWorkspaceTags = async (req: Request, res: Response) => { - const { workspaceId } = req.params - const workspaceTags = await Tag.find({ workspace: workspaceId }) - return res.json({ - workspaceTags - }) -} + const { workspaceId } = req.params; + const workspaceTags = await Tag.find({ workspace: workspaceId }); + return res.json({ + workspaceTags + }); +}; diff --git a/backend/src/controllers/v2/usersController.ts b/backend/src/controllers/v2/usersController.ts index 2d5cdc51ac..2b4784b293 100644 --- a/backend/src/controllers/v2/usersController.ts +++ b/backend/src/controllers/v2/usersController.ts @@ -1,8 +1,8 @@ -import { Request, Response } from 'express'; +import { Request, Response } from "express"; import { + MembershipOrg, User, - MembershipOrg -} from '../../models'; +} from "../../models"; /** * Return the current user. @@ -38,10 +38,10 @@ export const getMe = async (req: Request, res: Response) => { */ const user = await User .findById(req.user._id) - .select('+salt +publicKey +encryptedPrivateKey +iv +tag +encryptionVersion +protectedKey +protectedKeyIV +protectedKeyTag'); + .select("+salt +publicKey +encryptedPrivateKey +iv +tag +encryptionVersion +protectedKey +protectedKeyIV +protectedKeyTag"); return res.status(200).send({ - user + user, }); } @@ -60,7 +60,7 @@ export const updateMyMfaEnabled = async (req: Request, res: Response) => { if (isMfaEnabled) { // TODO: adapt this route/controller // to work for different forms of MFA - req.user.mfaMethods = ['email']; + req.user.mfaMethods = ["email"]; } else { req.user.mfaMethods = []; } @@ -70,7 +70,7 @@ export const updateMyMfaEnabled = async (req: Request, res: Response) => { const user = req.user; return res.status(200).send({ - user + user, }); } @@ -109,11 +109,11 @@ export const getMyOrganizations = async (req: Request, res: Response) => { */ const organizations = ( await MembershipOrg.find({ - user: req.user._id - }).populate('organization') + user: req.user._id, + }).populate("organization") ).map((m) => m.organization); return res.status(200).send({ - organizations + organizations, }); } diff --git a/backend/src/controllers/v2/workspaceController.ts b/backend/src/controllers/v2/workspaceController.ts index 20778491d5..c0d46f8514 100644 --- a/backend/src/controllers/v2/workspaceController.ts +++ b/backend/src/controllers/v2/workspaceController.ts @@ -1,25 +1,19 @@ -import { Request, Response } from 'express'; -import { Types } from 'mongoose'; +import { Request, Response } from "express"; +import { Types } from "mongoose"; import { - Workspace, - Secret, - Membership, - MembershipOrg, - Integration, - IntegrationAuth, Key, - IUser, - ServiceToken, - ServiceTokenData -} from '../../models'; + Membership, + ServiceTokenData, + Workspace, +} from "../../models"; import { - v2PushSecrets as push, pullSecrets as pull, - reformatPullSecrets -} from '../../helpers/secret'; -import { pushKeys } from '../../helpers/key'; -import { TelemetryService, EventService } from '../../services'; -import { eventPushSecrets } from '../../events'; + v2PushSecrets as push, + reformatPullSecrets, +} from "../../helpers/secret"; +import { pushKeys } from "../../helpers/key"; +import { EventService, TelemetryService } from "../../services"; +import { eventPushSecrets } from "../../events"; interface V2PushSecret { type: string; // personal or shared @@ -54,12 +48,12 @@ export const pushWorkspaceSecrets = async (req: Request, res: Response) => { // validate environment const workspaceEnvs = req.membership.workspace.environments; if (!workspaceEnvs.find(({ slug }: { slug: string }) => slug === environment)) { - throw new Error('Failed to validate environment'); + throw new Error("Failed to validate environment"); } // sanitize secrets secrets = secrets.filter( - (s: V2PushSecret) => s.secretKeyCiphertext !== '' && s.secretValueCiphertext !== '' + (s: V2PushSecret) => s.secretKeyCiphertext !== "" && s.secretValueCiphertext !== "" ); await push({ @@ -67,26 +61,26 @@ export const pushWorkspaceSecrets = async (req: Request, res: Response) => { workspaceId, environment, secrets, - channel: channel ? channel : 'cli', - ipAddress: req.realIP + channel: channel ? channel : "cli", + ipAddress: req.realIP, }); await pushKeys({ userId: req.user._id, workspaceId, - keys + keys, }); if (postHogClient) { postHogClient.capture({ - event: 'secrets pushed', + event: "secrets pushed", distinctId: req.user.email, properties: { numberOfSecrets: secrets.length, environment, workspaceId, - channel: channel ? channel : 'cli' - } + channel: channel ? channel : "cli", + }, }); } @@ -94,12 +88,12 @@ export const pushWorkspaceSecrets = async (req: Request, res: Response) => { EventService.handleEvent({ event: eventPushSecrets({ workspaceId: new Types.ObjectId(workspaceId), - environment - }) + environment, + }), }); return res.status(200).send({ - message: 'Successfully uploaded workspace secrets' + message: "Successfully uploaded workspace secrets", }); }; @@ -126,18 +120,18 @@ export const pullSecrets = async (req: Request, res: Response) => { // validate environment const workspaceEnvs = req.membership.workspace.environments; if (!workspaceEnvs.find(({ slug }: { slug: string }) => slug === environment)) { - throw new Error('Failed to validate environment'); + throw new Error("Failed to validate environment"); } secrets = await pull({ userId, workspaceId, environment, - channel: channel ? channel : 'cli', - ipAddress: req.realIP + channel: channel ? channel : "cli", + ipAddress: req.realIP, }); - if (channel !== 'cli') { + if (channel !== "cli") { secrets = reformatPullSecrets({ secrets }); } @@ -145,18 +139,18 @@ export const pullSecrets = async (req: Request, res: Response) => { // capture secrets pushed event in production postHogClient.capture({ distinctId: req.user.email, - event: 'secrets pulled', + event: "secrets pulled", properties: { numberOfSecrets: secrets.length, environment, workspaceId, - channel: channel ? channel : 'cli' - } + channel: channel ? channel : "cli", + }, }); } return res.status(200).send({ - secrets + secrets, }); }; @@ -194,10 +188,10 @@ export const getWorkspaceKey = async (req: Request, res: Response) => { key = await Key.findOne({ workspace: workspaceId, - receiver: req.user._id - }).populate('sender', '+publicKey'); + receiver: req.user._id, + }).populate("sender", "+publicKey"); - if (!key) throw new Error('Failed to find workspace key'); + if (!key) throw new Error("Failed to find workspace key"); return res.status(200).json(key); } @@ -209,12 +203,12 @@ export const getWorkspaceServiceTokenData = async ( const serviceTokenData = await ServiceTokenData .find({ - workspace: workspaceId + workspace: workspaceId, }) - .select('+encryptedKey +iv +tag'); + .select("+encryptedKey +iv +tag"); return res.status(200).send({ - serviceTokenData + serviceTokenData, }); } @@ -261,11 +255,11 @@ export const getWorkspaceMemberships = async (req: Request, res: Response) => { const { workspaceId } = req.params; const memberships = await Membership.find({ - workspace: workspaceId - }).populate('user', '+publicKey'); + workspace: workspaceId, + }).populate("user", "+publicKey"); return res.status(200).send({ - memberships + memberships, }); } @@ -330,21 +324,21 @@ export const updateWorkspaceMembership = async (req: Request, res: Response) => } */ const { - membershipId + membershipId, } = req.params; const { role } = req.body; const membership = await Membership.findByIdAndUpdate( membershipId, { - role + role, }, { - new: true + new: true, } ); return res.status(200).send({ - membership + membership, }); } @@ -392,20 +386,20 @@ export const deleteWorkspaceMembership = async (req: Request, res: Response) => } */ const { - membershipId + membershipId, } = req.params; const membership = await Membership.findByIdAndDelete(membershipId); - if (!membership) throw new Error('Failed to delete workspace membership'); + if (!membership) throw new Error("Failed to delete workspace membership"); await Key.deleteMany({ receiver: membership.user, - workspace: membership.workspace + workspace: membership.workspace, }); return res.status(200).send({ - membership + membership, }); } @@ -421,18 +415,18 @@ export const toggleAutoCapitalization = async (req: Request, res: Response) => { const workspace = await Workspace.findOneAndUpdate( { - _id: workspaceId + _id: workspaceId, }, { - autoCapitalization + autoCapitalization, }, { - new: true + new: true, } ); return res.status(200).send({ - message: 'Successfully changed autoCapitalization setting', - workspace + message: "Successfully changed autoCapitalization setting", + workspace, }); }; diff --git a/backend/src/controllers/v3/authController.ts b/backend/src/controllers/v3/authController.ts index afb670269b..7a70f171c1 100644 --- a/backend/src/controllers/v3/authController.ts +++ b/backend/src/controllers/v3/authController.ts @@ -1,29 +1,29 @@ /* eslint-disable @typescript-eslint/no-var-requires */ -import { Request, Response } from 'express'; -import jwt from 'jsonwebtoken'; -import * as Sentry from '@sentry/node'; -import * as bigintConversion from 'bigint-conversion'; -const jsrp = require('jsrp'); -import { User, LoginSRPDetail } from '../../models'; -import { issueAuthTokens, createToken, validateProviderAuthToken } from '../../helpers/auth'; -import { checkUserDevice } from '../../helpers/user'; -import { sendMail } from '../../helpers/nodemailer'; -import { TokenService } from '../../services'; -import { EELogService } from '../../ee/services'; -import { BadRequestError, InternalServerError } from '../../utils/errors'; +import { Request, Response } from "express"; +import jwt from "jsonwebtoken"; +import * as Sentry from "@sentry/node"; +import * as bigintConversion from "bigint-conversion"; +const jsrp = require("jsrp"); +import { LoginSRPDetail, User } from "../../models"; +import { createToken, issueAuthTokens, validateProviderAuthToken } from "../../helpers/auth"; +import { checkUserDevice } from "../../helpers/user"; +import { sendMail } from "../../helpers/nodemailer"; +import { TokenService } from "../../services"; +import { EELogService } from "../../ee/services"; +import { BadRequestError, InternalServerError } from "../../utils/errors"; import { + ACTION_LOGIN, TOKEN_EMAIL_MFA, - ACTION_LOGIN -} from '../../variables'; -import { getChannelFromUserAgent } from '../../utils/posthog'; // TODO: move this +} from "../../variables"; +import { getChannelFromUserAgent } from "../../utils/posthog"; // TODO: move this import { + getHttpsEnabled, getJwtMfaLifetime, getJwtMfaSecret, - getHttpsEnabled, -} from '../../config'; -import { AuthProvider } from '../../models/user'; +} from "../../config"; +import { AuthProvider } from "../../models/user"; -declare module 'jsonwebtoken' { +declare module "jsonwebtoken" { export interface ProviderAuthJwtPayload extends jwt.JwtPayload { userId: string; email: string; @@ -43,7 +43,7 @@ export const login1 = async (req: Request, res: Response) => { const { email, providerAuthToken, - clientPublicKey + clientPublicKey, }: { email: string; clientPublicKey: string, @@ -52,9 +52,9 @@ export const login1 = async (req: Request, res: Response) => { const user = await User.findOne({ email, - }).select('+salt +verifier'); + }).select("+salt +verifier"); - if (!user) throw new Error('Failed to find user'); + if (!user) throw new Error("Failed to find user"); if (user.authProvider) { await validateProviderAuthToken({ @@ -68,13 +68,13 @@ export const login1 = async (req: Request, res: Response) => { server.init( { salt: user.salt, - verifier: user.verifier + verifier: user.verifier, }, async () => { // generate server-side public key const serverPublicKey = server.getPublicKey(); await LoginSRPDetail.findOneAndReplace({ - email: email + email: email, }, { email, userId: user.id, @@ -84,7 +84,7 @@ export const login1 = async (req: Request, res: Response) => { return res.status(200).send({ serverPublicKey, - salt: user.salt + salt: user.salt, }); } ); @@ -92,7 +92,7 @@ export const login1 = async (req: Request, res: Response) => { Sentry.setUser(null); Sentry.captureException(err); return res.status(400).send({ - message: 'Failed to start authentication process' + message: "Failed to start authentication process", }); } }; @@ -107,15 +107,15 @@ export const login1 = async (req: Request, res: Response) => { export const login2 = async (req: Request, res: Response) => { try { - if (!req.headers['user-agent']) throw InternalServerError({ message: 'User-Agent header is required' }); + if (!req.headers["user-agent"]) throw InternalServerError({ message: "User-Agent header is required" }); const { email, clientProof, providerAuthToken } = req.body; const user = await User.findOne({ email, - }).select('+salt +verifier +encryptionVersion +protectedKey +protectedKeyIV +protectedKeyTag +publicKey +encryptedPrivateKey +iv +tag +devices'); + }).select("+salt +verifier +encryptionVersion +protectedKey +protectedKeyIV +protectedKeyTag +publicKey +encryptedPrivateKey +iv +tag +devices"); - if (!user) throw new Error('Failed to find user'); + if (!user) throw new Error("Failed to find user"); if (user.authProvider) { await validateProviderAuthToken({ @@ -136,7 +136,7 @@ export const login2 = async (req: Request, res: Response) => { { salt: user.salt, verifier: user.verifier, - b: loginSRPDetail.serverBInt + b: loginSRPDetail.serverBInt, }, async () => { server.setClientPublicKey(loginSRPDetail.clientPublicKey); @@ -150,52 +150,52 @@ export const login2 = async (req: Request, res: Response) => { // generate temporary MFA token const token = createToken({ payload: { - userId: user._id.toString() + userId: user._id.toString(), }, expiresIn: await getJwtMfaLifetime(), - secret: await getJwtMfaSecret() + secret: await getJwtMfaSecret(), }); const code = await TokenService.createToken({ type: TOKEN_EMAIL_MFA, - email + email, }); // send MFA code [code] to [email] await sendMail({ - template: 'emailMfa.handlebars', - subjectLine: 'Infisical MFA code', + template: "emailMfa.handlebars", + subjectLine: "Infisical MFA code", recipients: [user.email], substitutions: { - code - } + code, + }, }); return res.status(200).send({ mfaEnabled: true, - token + token, }); } await checkUserDevice({ user, ip: req.realIP, - userAgent: req.headers['user-agent'] ?? '' + userAgent: req.headers["user-agent"] ?? "", }); // issue tokens const tokens = await issueAuthTokens({ userId: user._id, ip: req.realIP, - userAgent: req.headers['user-agent'] ?? '' + userAgent: req.headers["user-agent"] ?? "", }); // store (refresh) token in httpOnly cookie - res.cookie('jid', tokens.refreshToken, { + res.cookie("jid", tokens.refreshToken, { httpOnly: true, - path: '/', - sameSite: 'strict', - secure: await getHttpsEnabled() + path: "/", + sameSite: "strict", + secure: await getHttpsEnabled(), }); // case: user does not have MFA enablgged @@ -221,7 +221,7 @@ export const login2 = async (req: Request, res: Response) => { publicKey: user.publicKey, encryptedPrivateKey: user.encryptedPrivateKey, iv: user.iv, - tag: user.tag + tag: user.tag, } if ( @@ -236,21 +236,21 @@ export const login2 = async (req: Request, res: Response) => { const loginAction = await EELogService.createAction({ name: ACTION_LOGIN, - userId: user._id + userId: user._id, }); loginAction && await EELogService.createLog({ userId: user._id, actions: [loginAction], - channel: getChannelFromUserAgent(req.headers['user-agent']), - ipAddress: req.realIP + channel: getChannelFromUserAgent(req.headers["user-agent"]), + ipAddress: req.realIP, }); return res.status(200).send(response); } return res.status(400).send({ - message: 'Failed to authenticate. Try again?' + message: "Failed to authenticate. Try again?", }); } ); @@ -258,7 +258,7 @@ export const login2 = async (req: Request, res: Response) => { Sentry.setUser(null); Sentry.captureException(err); return res.status(400).send({ - message: 'Failed to authenticate. Try again?' + message: "Failed to authenticate. Try again?", }); } }; diff --git a/backend/src/controllers/v3/index.ts b/backend/src/controllers/v3/index.ts index 9d3f118d3d..959bab5327 100644 --- a/backend/src/controllers/v3/index.ts +++ b/backend/src/controllers/v3/index.ts @@ -1,7 +1,7 @@ -import * as secretsController from './secretsController'; -import * as workspacesController from './workspacesController'; -import * as authController from './authController'; -import * as signupController from './signupController'; +import * as secretsController from "./secretsController"; +import * as workspacesController from "./workspacesController"; +import * as authController from "./authController"; +import * as signupController from "./signupController"; export { authController, diff --git a/backend/src/controllers/v3/secretsController.ts b/backend/src/controllers/v3/secretsController.ts index 182d7f14f4..3c7336241a 100644 --- a/backend/src/controllers/v3/secretsController.ts +++ b/backend/src/controllers/v3/secretsController.ts @@ -1,6 +1,6 @@ import { Request, Response } from "express"; import { Types } from "mongoose"; -import { SecretService, EventService } from "../../services"; +import { EventService, SecretService } from "../../services"; import { eventPushSecrets } from "../../events"; import { BotService } from "../../services"; import { repackageSecretToRaw } from "../../helpers/secrets"; @@ -25,18 +25,18 @@ export const getSecretsRaw = async (req: Request, res: Response) => { }); const key = await BotService.getWorkspaceKeyWithBot({ - workspaceId: new Types.ObjectId(workspaceId) + workspaceId: new Types.ObjectId(workspaceId), }); return res.status(200).send({ secrets: secrets.map((secret) => { const rep = repackageSecretToRaw({ secret, - key + key, }); return rep; - }) + }), }); }; @@ -62,14 +62,14 @@ export const getSecretByNameRaw = async (req: Request, res: Response) => { }); const key = await BotService.getWorkspaceKeyWithBot({ - workspaceId: new Types.ObjectId(workspaceId) + workspaceId: new Types.ObjectId(workspaceId), }); return res.status(200).send({ secret: repackageSecretToRaw({ secret, - key - }) + key, + }), }); }; @@ -86,26 +86,26 @@ export const createSecretRaw = async (req: Request, res: Response) => { type, secretValue, secretComment, - secretPath = "/" + secretPath = "/", } = req.body; const key = await BotService.getWorkspaceKeyWithBot({ - workspaceId: new Types.ObjectId(workspaceId) + workspaceId: new Types.ObjectId(workspaceId), }); const secretKeyEncrypted = encryptSymmetric128BitHexKeyUTF8({ plaintext: secretName, - key + key, }); const secretValueEncrypted = encryptSymmetric128BitHexKeyUTF8({ plaintext: secretValue, - key + key, }); const secretCommentEncrypted = encryptSymmetric128BitHexKeyUTF8({ plaintext: secretComment, - key + key, }); const secret = await SecretService.createSecret({ @@ -123,7 +123,7 @@ export const createSecretRaw = async (req: Request, res: Response) => { secretPath, secretCommentCiphertext: secretCommentEncrypted.ciphertext, secretCommentIV: secretCommentEncrypted.iv, - secretCommentTag: secretCommentEncrypted.tag + secretCommentTag: secretCommentEncrypted.tag, }); await EventService.handleEvent({ @@ -139,8 +139,8 @@ export const createSecretRaw = async (req: Request, res: Response) => { return res.status(200).send({ secret: repackageSecretToRaw({ secret: secretWithoutBlindIndex, - key - }) + key, + }), }); } @@ -160,12 +160,12 @@ export const updateSecretByNameRaw = async (req: Request, res: Response) => { } = req.body; const key = await BotService.getWorkspaceKeyWithBot({ - workspaceId: new Types.ObjectId(workspaceId) + workspaceId: new Types.ObjectId(workspaceId), }); const secretValueEncrypted = encryptSymmetric128BitHexKeyUTF8({ plaintext: secretValue, - key + key, }); const secret = await SecretService.updateSecret({ @@ -190,8 +190,8 @@ export const updateSecretByNameRaw = async (req: Request, res: Response) => { return res.status(200).send({ secret: repackageSecretToRaw({ secret, - key - }) + key, + }), }); }; @@ -206,7 +206,7 @@ export const deleteSecretByNameRaw = async (req: Request, res: Response) => { workspaceId, environment, type, - secretPath = "/" + secretPath = "/", } = req.body; const { secret } = await SecretService.deleteSecret({ @@ -226,14 +226,14 @@ export const deleteSecretByNameRaw = async (req: Request, res: Response) => { }); const key = await BotService.getWorkspaceKeyWithBot({ - workspaceId: new Types.ObjectId(workspaceId) + workspaceId: new Types.ObjectId(workspaceId), }); return res.status(200).send({ secret: repackageSecretToRaw({ secret, - key - }) + key, + }), }); }; @@ -324,7 +324,7 @@ export const createSecret = async (req: Request, res: Response) => { secretPath, secretCommentCiphertext, secretCommentIV, - secretCommentTag + secretCommentTag, }); await EventService.handleEvent({ @@ -395,7 +395,7 @@ export const deleteSecretByName = async (req: Request, res: Response) => { workspaceId, environment, type, - secretPath = "/" + secretPath = "/", } = req.body; const { secret } = await SecretService.deleteSecret({ diff --git a/backend/src/controllers/v3/signupController.ts b/backend/src/controllers/v3/signupController.ts index 5944e289a8..3d9f897c46 100644 --- a/backend/src/controllers/v3/signupController.ts +++ b/backend/src/controllers/v3/signupController.ts @@ -1,17 +1,17 @@ -import jwt from 'jsonwebtoken'; -import { Request, Response } from 'express'; -import * as Sentry from '@sentry/node'; -import { User, MembershipOrg } from '../../models'; -import { completeAccount } from '../../helpers/user'; +import jwt from "jsonwebtoken"; +import { Request, Response } from "express"; +import * as Sentry from "@sentry/node"; +import { MembershipOrg, User } from "../../models"; +import { completeAccount } from "../../helpers/user"; import { - initializeDefaultOrg -} from '../../helpers/signup'; -import { issueAuthTokens, validateProviderAuthToken } from '../../helpers/auth'; -import { INVITED, ACCEPTED } from '../../variables'; -import { standardRequest } from '../../config/request'; -import { getLoopsApiKey, getHttpsEnabled, getJwtSignupSecret } from '../../config'; -import { BadRequestError } from '../../utils/errors'; -import { TelemetryService } from '../../services'; + initializeDefaultOrg, +} from "../../helpers/signup"; +import { issueAuthTokens, validateProviderAuthToken } from "../../helpers/auth"; +import { ACCEPTED, INVITED } from "../../variables"; +import { standardRequest } from "../../config/request"; +import { getHttpsEnabled, getJwtSignupSecret, getLoopsApiKey } from "../../config"; +import { BadRequestError } from "../../utils/errors"; +import { TelemetryService } from "../../services"; /** * Complete setting up user by adding their personal and auth information as part of the @@ -63,7 +63,7 @@ export const completeAccountSignup = async (req: Request, res: Response) => { // case 1: user doesn't exist. // case 2: user has already completed account return res.status(403).send({ - error: 'Failed to complete account for complete user' + error: "Failed to complete account for complete user", }); } @@ -74,16 +74,16 @@ export const completeAccountSignup = async (req: Request, res: Response) => { user, }); } else { - const [AUTH_TOKEN_TYPE, AUTH_TOKEN_VALUE] = <[string, string]>req.headers['authorization']?.split(' ', 2) ?? [null, null] + const [AUTH_TOKEN_TYPE, AUTH_TOKEN_VALUE] = <[string, string]>req.headers["authorization"]?.split(" ", 2) ?? [null, null] if (AUTH_TOKEN_TYPE === null) { - throw BadRequestError({ message: `Missing Authorization Header in the request header.` }); + throw BadRequestError({ message: "Missing Authorization Header in the request header." }); } - if (AUTH_TOKEN_TYPE.toLowerCase() !== 'bearer') { + if (AUTH_TOKEN_TYPE.toLowerCase() !== "bearer") { throw BadRequestError({ message: `The provided authentication type '${AUTH_TOKEN_TYPE}' is not supported.` }) } if (AUTH_TOKEN_VALUE === null) { throw BadRequestError({ - message: 'Missing Authorization Body in the request header', + message: "Missing Authorization Body in the request header", }) } @@ -110,16 +110,16 @@ export const completeAccountSignup = async (req: Request, res: Response) => { encryptedPrivateKeyIV, encryptedPrivateKeyTag, salt, - verifier + verifier, }); if (!user) - throw new Error('Failed to complete account for non-existent user'); // ensure user is non-null + throw new Error("Failed to complete account for non-existent user"); // ensure user is non-null // initialize default organization and workspace await initializeDefaultOrg({ organizationName, - user + user, }); // update organization membership statuses that are @@ -127,11 +127,11 @@ export const completeAccountSignup = async (req: Request, res: Response) => { await MembershipOrg.updateMany( { inviteEmail: email, - status: INVITED + status: INVITED, }, { user, - status: ACCEPTED + status: ACCEPTED, } ); @@ -139,7 +139,7 @@ export const completeAccountSignup = async (req: Request, res: Response) => { const tokens = await issueAuthTokens({ userId: user._id, ip: req.realIP, - userAgent: req.headers['user-agent'] ?? '' + userAgent: req.headers["user-agent"] ?? "", }); token = tokens.token; @@ -150,45 +150,45 @@ export const completeAccountSignup = async (req: Request, res: Response) => { "email": email, "eventName": "Sign Up", "firstName": firstName, - "lastName": lastName + "lastName": lastName, }, { headers: { "Accept": "application/json", - "Authorization": "Bearer " + (await getLoopsApiKey()) + "Authorization": "Bearer " + (await getLoopsApiKey()), }, }); } // store (refresh) token in httpOnly cookie - res.cookie('jid', tokens.refreshToken, { + res.cookie("jid", tokens.refreshToken, { httpOnly: true, - path: '/', - sameSite: 'strict', - secure: await getHttpsEnabled() + path: "/", + sameSite: "strict", + secure: await getHttpsEnabled(), }); const postHogClient = await TelemetryService.getPostHogClient(); if (postHogClient) { postHogClient.capture({ - event: 'User Signed Up', + event: "User Signed Up", distinctId: email, properties: { email, - attributionSource - } + attributionSource, + }, }); } } catch (err) { Sentry.setUser(null); Sentry.captureException(err); return res.status(400).send({ - message: 'Failed to complete account setup' + message: "Failed to complete account setup", }); } return res.status(200).send({ - message: 'Successfully set up account', + message: "Successfully set up account", user, - token + token, }); }; diff --git a/backend/src/controllers/v3/workspacesController.ts b/backend/src/controllers/v3/workspacesController.ts index aac6682d7a..4298adba27 100644 --- a/backend/src/controllers/v3/workspacesController.ts +++ b/backend/src/controllers/v3/workspacesController.ts @@ -1,7 +1,7 @@ -import { Request, Response } from 'express'; -import { Types } from 'mongoose'; -import { Secret } from '../../models'; -import { SecretService } from'../../services'; +import { Request, Response } from "express"; +import { Types } from "mongoose"; +import { Secret } from "../../models"; +import { SecretService } from"../../services"; /** * Return whether or not all secrets in workspace with id [workspaceId] @@ -16,8 +16,8 @@ export const getWorkspaceBlindIndexStatus = async (req: Request, res: Response) const secretsWithoutBlindIndex = await Secret.countDocuments({ workspace: new Types.ObjectId(workspaceId), secretBlindIndex: { - $exists: false - } + $exists: false, + }, }); return res.status(200).send(secretsWithoutBlindIndex === 0); @@ -30,11 +30,11 @@ export const getWorkspaceSecrets = async (req: Request, res: Response) => { const { workspaceId } = req.params; const secrets = await Secret.find({ - workspace: new Types.ObjectId (workspaceId) + workspace: new Types.ObjectId (workspaceId), }); return res.status(200).send({ - secrets + secrets, }); } @@ -51,14 +51,14 @@ export const nameWorkspaceSecrets = async (req: Request, res: Response) => { const { workspaceId } = req.params; const { - secretsToUpdate + secretsToUpdate, }: { secretsToUpdate: SecretToUpdate[]; } = req.body; // get secret blind index salt const salt = await SecretService.getSecretBlindIndexSalt({ - workspaceId: new Types.ObjectId(workspaceId) + workspaceId: new Types.ObjectId(workspaceId), }); // update secret blind indices @@ -66,18 +66,18 @@ export const nameWorkspaceSecrets = async (req: Request, res: Response) => { secretsToUpdate.map(async (secretToUpdate: SecretToUpdate) => { const secretBlindIndex = await SecretService.generateSecretBlindIndexWithSalt({ secretName: secretToUpdate.secretName, - salt + salt, }); return ({ updateOne: { filter: { - _id: new Types.ObjectId(secretToUpdate._id) + _id: new Types.ObjectId(secretToUpdate._id), }, update: { - secretBlindIndex - } - } + secretBlindIndex, + }, + }, }); }) ); @@ -85,6 +85,6 @@ export const nameWorkspaceSecrets = async (req: Request, res: Response) => { await Secret.bulkWrite(operations); return res.status(200).send({ - message: 'Successfully named workspace secrets' + message: "Successfully named workspace secrets", }); } \ No newline at end of file diff --git a/backend/src/ee/controllers/v1/actionController.ts b/backend/src/ee/controllers/v1/actionController.ts index 4b3117b207..484c253519 100644 --- a/backend/src/ee/controllers/v1/actionController.ts +++ b/backend/src/ee/controllers/v1/actionController.ts @@ -1,6 +1,6 @@ -import { Request, Response } from 'express'; -import { Action, SecretVersion } from '../../models'; -import { ActionNotFoundError } from '../../../utils/errors'; +import { Request, Response } from "express"; +import { Action } from "../../models"; +import { ActionNotFoundError } from "../../../utils/errors"; export const getAction = async (req: Request, res: Response) => { let action; @@ -10,21 +10,21 @@ export const getAction = async (req: Request, res: Response) => { action = await Action .findById(actionId) .populate([ - 'payload.secretVersions.oldSecretVersion', - 'payload.secretVersions.newSecretVersion' + "payload.secretVersions.oldSecretVersion", + "payload.secretVersions.newSecretVersion", ]); if (!action) throw ActionNotFoundError({ - message: 'Failed to find action' + message: "Failed to find action", }); } catch (err) { throw ActionNotFoundError({ - message: 'Failed to find action' + message: "Failed to find action", }); } return res.status(200).send({ - action + action, }); } diff --git a/backend/src/ee/controllers/v1/cloudProductsController.ts b/backend/src/ee/controllers/v1/cloudProductsController.ts index c7d60ca1a6..e66fc66e56 100644 --- a/backend/src/ee/controllers/v1/cloudProductsController.ts +++ b/backend/src/ee/controllers/v1/cloudProductsController.ts @@ -1,7 +1,7 @@ -import { Request, Response } from 'express'; -import { EELicenseService } from '../../services'; -import { getLicenseServerUrl } from '../../../config'; -import { licenseServerKeyRequest } from '../../../config/request'; +import { Request, Response } from "express"; +import { EELicenseService } from "../../services"; +import { getLicenseServerUrl } from "../../../config"; +import { licenseServerKeyRequest } from "../../../config/request"; /** * Return available cloud product information. @@ -11,9 +11,9 @@ import { licenseServerKeyRequest } from '../../../config/request'; * @returns */ export const getCloudProducts = async (req: Request, res: Response) => { - const billingCycle = req.query['billing-cycle'] as string; + const billingCycle = req.query["billing-cycle"] as string; - if (EELicenseService.instanceType === 'cloud') { + if (EELicenseService.instanceType === "cloud") { const { data } = await licenseServerKeyRequest.get( `${await getLicenseServerUrl()}/api/license-server/v1/cloud-products?billing-cycle=${billingCycle}` ); @@ -23,6 +23,6 @@ export const getCloudProducts = async (req: Request, res: Response) => { return res.status(200).send({ head: [], - rows: [] + rows: [], }); } diff --git a/backend/src/ee/controllers/v1/index.ts b/backend/src/ee/controllers/v1/index.ts index bf3992b17b..c8b9f48a20 100644 --- a/backend/src/ee/controllers/v1/index.ts +++ b/backend/src/ee/controllers/v1/index.ts @@ -1,11 +1,11 @@ -import * as stripeController from './stripeController'; -import * as secretController from './secretController'; -import * as secretSnapshotController from './secretSnapshotController'; -import * as organizationsController from './organizationsController'; -import * as workspaceController from './workspaceController'; -import * as actionController from './actionController'; -import * as membershipController from './membershipController'; -import * as cloudProductsController from './cloudProductsController'; +import * as stripeController from "./stripeController"; +import * as secretController from "./secretController"; +import * as secretSnapshotController from "./secretSnapshotController"; +import * as organizationsController from "./organizationsController"; +import * as workspaceController from "./workspaceController"; +import * as actionController from "./actionController"; +import * as membershipController from "./membershipController"; +import * as cloudProductsController from "./cloudProductsController"; export { stripeController, @@ -15,5 +15,5 @@ export { workspaceController, actionController, membershipController, - cloudProductsController + cloudProductsController, } \ No newline at end of file diff --git a/backend/src/ee/controllers/v1/membershipController.ts b/backend/src/ee/controllers/v1/membershipController.ts index 35534d19c5..1a03d36d0e 100644 --- a/backend/src/ee/controllers/v1/membershipController.ts +++ b/backend/src/ee/controllers/v1/membershipController.ts @@ -3,7 +3,7 @@ import { Membership, Workspace } from "../../../models"; import { IMembershipPermission } from "../../../models/membership"; import { BadRequestError, UnauthorizedRequestError } from "../../../utils/errors"; import { ADMIN, MEMBER } from "../../../variables/organization"; -import { PERMISSION_READ_SECRETS, PERMISSION_WRITE_SECRETS } from '../../../variables'; +import { PERMISSION_READ_SECRETS, PERMISSION_WRITE_SECRETS } from "../../../variables"; import { Builder } from "builder-pattern" import _ from "lodash"; @@ -39,7 +39,7 @@ export const denyMembershipPermissions = async (req: Request, res: Response) => throw BadRequestError({ message: "Something went wrong when locating the related workspace" }) } - const uniqueEnvironmentSlugs = new Set(_.uniq(_.map(relatedWorkspace.environments, 'slug'))); + const uniqueEnvironmentSlugs = new Set(_.uniq(_.map(relatedWorkspace.environments, "slug"))); sanitizedMembershipPermissionsUnique.forEach(permission => { if (!uniqueEnvironmentSlugs.has(permission.environmentSlug)) { @@ -59,6 +59,6 @@ export const denyMembershipPermissions = async (req: Request, res: Response) => } res.send({ - permissionsDenied: updatedMembershipWithPermissions.deniedPermissions + permissionsDenied: updatedMembershipWithPermissions.deniedPermissions, }) } diff --git a/backend/src/ee/controllers/v1/organizationsController.ts b/backend/src/ee/controllers/v1/organizationsController.ts index 2d2867d71c..54c154c7a6 100644 --- a/backend/src/ee/controllers/v1/organizationsController.ts +++ b/backend/src/ee/controllers/v1/organizationsController.ts @@ -1,7 +1,7 @@ -import { Request, Response } from 'express'; -import { getLicenseServerUrl } from '../../../config'; -import { licenseServerKeyRequest } from '../../../config/request'; -import { EELicenseService } from '../../services'; +import { Request, Response } from "express"; +import { getLicenseServerUrl } from "../../../config"; +import { licenseServerKeyRequest } from "../../../config/request"; +import { EELicenseService } from "../../services"; /** * Return the organization's current plan and allowed feature set @@ -25,13 +25,13 @@ export const getOrganizationPlan = async (req: Request, res: Response) => { */ export const updateOrganizationPlan = async (req: Request, res: Response) => { const { - productId + productId, } = req.body; const { data } = await licenseServerKeyRequest.patch( `${await getLicenseServerUrl()}/api/license-server/v1/customers/${req.organization.customerId}/cloud-plan`, { - productId + productId, } ); @@ -47,7 +47,7 @@ export const getOrganizationPmtMethods = async (req: Request, res: Response) => ); return res.status(200).send({ - pmtMethods + pmtMethods, }); } @@ -57,19 +57,19 @@ export const getOrganizationPmtMethods = async (req: Request, res: Response) => export const addOrganizationPmtMethod = async (req: Request, res: Response) => { const { success_url, - cancel_url + cancel_url, } = req.body; const { data: { url } } = await licenseServerKeyRequest.post( `${await getLicenseServerUrl()}/api/license-server/v1/customers/${req.organization.customerId}/billing-details/payment-methods`, { success_url, - cancel_url + cancel_url, } ); return res.status(200).send({ - url + url, }); } diff --git a/backend/src/ee/controllers/v1/secretSnapshotController.ts b/backend/src/ee/controllers/v1/secretSnapshotController.ts index 445add15ad..c10188b10c 100644 --- a/backend/src/ee/controllers/v1/secretSnapshotController.ts +++ b/backend/src/ee/controllers/v1/secretSnapshotController.ts @@ -17,11 +17,11 @@ export const getSecretSnapshot = async (req: Request, res: Response) => { const secretSnapshot = await SecretSnapshot.findById(secretSnapshotId) .lean() .populate<{ secretVersions: ISecretVersion[] }>({ - path: 'secretVersions', + path: "secretVersions", populate: { - path: 'tags', - model: 'Tag' - } + path: "tags", + model: "Tag", + }, }) .populate<{ folderVersion: TFolderRootVersionSchema }>("folderVersion"); diff --git a/backend/src/ee/controllers/v1/stripeController.ts b/backend/src/ee/controllers/v1/stripeController.ts index 172df32205..bd3ed7704d 100644 --- a/backend/src/ee/controllers/v1/stripeController.ts +++ b/backend/src/ee/controllers/v1/stripeController.ts @@ -1,6 +1,6 @@ -import { Request, Response } from 'express'; -import Stripe from 'stripe'; -import { getStripeSecretKey, getStripeWebhookSecret } from '../../../config'; +import { Request, Response } from "express"; +import Stripe from "stripe"; +import { getStripeSecretKey, getStripeWebhookSecret } from "../../../config"; /** * Handle service provisioning/un-provisioning via Stripe @@ -10,11 +10,11 @@ import { getStripeSecretKey, getStripeWebhookSecret } from '../../../config'; */ export const handleWebhook = async (req: Request, res: Response) => { const stripe = new Stripe(await getStripeSecretKey(), { - apiVersion: '2022-08-01' + apiVersion: "2022-08-01", }); // check request for valid stripe signature - const sig = req.headers['stripe-signature'] as string; + const sig = req.headers["stripe-signature"] as string; const event = stripe.webhooks.constructEvent( req.body, sig, @@ -22,7 +22,7 @@ export const handleWebhook = async (req: Request, res: Response) => { ); switch (event.type) { - case '': + case "": break; default: } diff --git a/backend/src/ee/controllers/v1/workspaceController.ts b/backend/src/ee/controllers/v1/workspaceController.ts index 166171ccdc..5ec54d6764 100644 --- a/backend/src/ee/controllers/v1/workspaceController.ts +++ b/backend/src/ee/controllers/v1/workspaceController.ts @@ -2,11 +2,11 @@ import { Request, Response } from "express"; import { PipelineStage, Types } from "mongoose"; import { Secret } from "../../../models"; import { - SecretSnapshot, - Log, - SecretVersion, - ISecretVersion, FolderVersion, + ISecretVersion, + Log, + SecretSnapshot, + SecretVersion, TFolderRootVersionSchema, } from "../../models"; import { EESecretService } from "../../services"; diff --git a/backend/src/ee/helpers/action.ts b/backend/src/ee/helpers/action.ts index 94e6bd24de..3279e86ca7 100644 --- a/backend/src/ee/helpers/action.ts +++ b/backend/src/ee/helpers/action.ts @@ -1,17 +1,17 @@ -import { Types } from 'mongoose'; -import { Action } from '../models'; +import { Types } from "mongoose"; +import { Action } from "../models"; import { + getLatestNSecretSecretVersionIds, getLatestSecretVersionIds, - getLatestNSecretSecretVersionIds -} from '../helpers/secretVersion'; +} from "../helpers/secretVersion"; import { + ACTION_ADD_SECRETS, + ACTION_DELETE_SECRETS, ACTION_LOGIN, ACTION_LOGOUT, - ACTION_ADD_SECRETS, ACTION_READ_SECRETS, - ACTION_DELETE_SECRETS, ACTION_UPDATE_SECRETS, -} from '../../variables'; +} from "../../variables"; /** * Create an (audit) action for updating secrets @@ -26,7 +26,7 @@ const createActionUpdateSecret = async ({ serviceAccountId, serviceTokenDataId, workspaceId, - secretIds + secretIds, }: { name: string; userId?: Types.ObjectId; @@ -37,11 +37,11 @@ const createActionUpdateSecret = async ({ }) => { const latestSecretVersions = (await getLatestNSecretSecretVersionIds({ secretIds, - n: 2 + n: 2, })) .map((s) => ({ oldSecretVersion: s.versions[0]._id, - newSecretVersion: s.versions[1]._id + newSecretVersion: s.versions[1]._id, })); const action = await new Action({ @@ -51,8 +51,8 @@ const createActionUpdateSecret = async ({ serviceTokenData: serviceTokenDataId, workspace: workspaceId, payload: { - secretVersions: latestSecretVersions - } + secretVersions: latestSecretVersions, + }, }).save(); return action; @@ -72,7 +72,7 @@ const createActionSecret = async ({ serviceAccountId, serviceTokenDataId, workspaceId, - secretIds + secretIds, }: { name: string; userId?: Types.ObjectId; @@ -84,10 +84,10 @@ const createActionSecret = async ({ // case: action is adding, deleting, or reading secrets // -> add new secret versions const latestSecretVersions = (await getLatestSecretVersionIds({ - secretIds + secretIds, })) .map((s) => ({ - newSecretVersion: s.versionId + newSecretVersion: s.versionId, })); const action = await new Action({ @@ -97,8 +97,8 @@ const createActionSecret = async ({ serviceTokenData: serviceTokenDataId, workspace: workspaceId, payload: { - secretVersions: latestSecretVersions - } + secretVersions: latestSecretVersions, + }, }).save(); return action; @@ -116,7 +116,7 @@ const createActionClient = ({ name, userId, serviceAccountId, - serviceTokenDataId + serviceTokenDataId, }: { name: string; userId?: Types.ObjectId; @@ -127,7 +127,7 @@ const createActionClient = ({ name, user: userId, serviceAccount: serviceAccountId, - serviceTokenData: serviceTokenDataId + serviceTokenData: serviceTokenDataId, }).save(); return action; @@ -162,27 +162,27 @@ const createActionHelper = async ({ case ACTION_LOGOUT: action = await createActionClient({ name, - userId + userId, }); break; case ACTION_ADD_SECRETS: case ACTION_READ_SECRETS: case ACTION_DELETE_SECRETS: - if (!workspaceId || !secretIds) throw new Error('Missing required params workspace id or secret ids to create action secret'); + if (!workspaceId || !secretIds) throw new Error("Missing required params workspace id or secret ids to create action secret"); action = await createActionSecret({ name, userId, workspaceId, - secretIds + secretIds, }); break; case ACTION_UPDATE_SECRETS: - if (!workspaceId || !secretIds) throw new Error('Missing required params workspace id or secret ids to create action secret'); + if (!workspaceId || !secretIds) throw new Error("Missing required params workspace id or secret ids to create action secret"); action = await createActionUpdateSecret({ name, userId, workspaceId, - secretIds + secretIds, }); break; } @@ -191,5 +191,5 @@ const createActionHelper = async ({ } export { - createActionHelper + createActionHelper, }; diff --git a/backend/src/ee/helpers/checkMembershipPermissions.ts b/backend/src/ee/helpers/checkMembershipPermissions.ts index c97a516192..4f6ddc7713 100644 --- a/backend/src/ee/helpers/checkMembershipPermissions.ts +++ b/backend/src/ee/helpers/checkMembershipPermissions.ts @@ -1,7 +1,7 @@ -import { Types } from 'mongoose'; +import { Types } from "mongoose"; import _ from "lodash"; import { Membership } from "../../models"; -import { PERMISSION_READ_SECRETS, PERMISSION_WRITE_SECRETS } from '../../variables'; +import { PERMISSION_READ_SECRETS, PERMISSION_WRITE_SECRETS } from "../../variables"; export const userHasWorkspaceAccess = async (userId: Types.ObjectId, workspaceId: Types.ObjectId, environment: string, action: any) => { const membershipForWorkspace = await Membership.findOne({ workspace: workspaceId, user: userId }) diff --git a/backend/src/ee/helpers/log.ts b/backend/src/ee/helpers/log.ts index 5b6d78f316..feb52d151e 100644 --- a/backend/src/ee/helpers/log.ts +++ b/backend/src/ee/helpers/log.ts @@ -1,8 +1,8 @@ -import { Types } from 'mongoose'; +import { Types } from "mongoose"; import { + IAction, Log, - IAction -} from '../models'; +} from "../models"; /** * Create an (audit) log @@ -21,7 +21,7 @@ const createLogHelper = async ({ workspaceId, actions, channel, - ipAddress + ipAddress, }: { userId?: Types.ObjectId; serviceAccountId?: Types.ObjectId; @@ -39,12 +39,12 @@ const createLogHelper = async ({ actionNames: actions.map((a) => a.name), actions, channel, - ipAddress + ipAddress, }).save(); return log; } export { - createLogHelper + createLogHelper, } diff --git a/backend/src/ee/helpers/secret.ts b/backend/src/ee/helpers/secret.ts index b315310cb2..54b26f56e4 100644 --- a/backend/src/ee/helpers/secret.ts +++ b/backend/src/ee/helpers/secret.ts @@ -1,10 +1,10 @@ import { Types } from "mongoose"; -import { Secret, ISecret } from "../../models"; +import { Secret } from "../../models"; import { + FolderVersion, + ISecretVersion, SecretSnapshot, SecretVersion, - ISecretVersion, - FolderVersion, } from "../models"; /** diff --git a/backend/src/ee/middleware/index.ts b/backend/src/ee/middleware/index.ts index ff92679659..a984d924b3 100644 --- a/backend/src/ee/middleware/index.ts +++ b/backend/src/ee/middleware/index.ts @@ -1,7 +1,7 @@ -import requireLicenseAuth from './requireLicenseAuth'; -import requireSecretSnapshotAuth from './requireSecretSnapshotAuth'; +import requireLicenseAuth from "./requireLicenseAuth"; +import requireSecretSnapshotAuth from "./requireSecretSnapshotAuth"; export { requireLicenseAuth, - requireSecretSnapshotAuth + requireSecretSnapshotAuth, } \ No newline at end of file diff --git a/backend/src/ee/middleware/requireLicenseAuth.ts b/backend/src/ee/middleware/requireLicenseAuth.ts index c577563f3a..476a3e82bf 100644 --- a/backend/src/ee/middleware/requireLicenseAuth.ts +++ b/backend/src/ee/middleware/requireLicenseAuth.ts @@ -1,4 +1,4 @@ -import { Request, Response, NextFunction } from 'express'; +import { NextFunction, Request, Response } from "express"; /** * Validate if organization hosting meets license requirements to @@ -7,7 +7,7 @@ import { Request, Response, NextFunction } from 'express'; * @param {String[]} obj.acceptedTiers */ const requireLicenseAuth = ({ - acceptedTiers + acceptedTiers, }: { acceptedTiers: string[]; }) => { diff --git a/backend/src/ee/middleware/requireSecretSnapshotAuth.ts b/backend/src/ee/middleware/requireSecretSnapshotAuth.ts index af4d1e21cb..7cc5d1de7a 100644 --- a/backend/src/ee/middleware/requireSecretSnapshotAuth.ts +++ b/backend/src/ee/middleware/requireSecretSnapshotAuth.ts @@ -1,9 +1,9 @@ -import { Request, Response, NextFunction } from 'express'; -import { UnauthorizedRequestError, SecretSnapshotNotFoundError } from '../../utils/errors'; -import { SecretSnapshot } from '../models'; +import { NextFunction, Request, Response } from "express"; +import { SecretSnapshotNotFoundError } from "../../utils/errors"; +import { SecretSnapshot } from "../models"; import { - validateMembership -} from '../../helpers/membership'; + validateMembership, +} from "../../helpers/membership"; /** * Validate if user on request has proper membership for secret snapshot @@ -15,7 +15,7 @@ import { const requireSecretSnapshotAuth = ({ acceptedRoles, }: { - acceptedRoles: Array<'admin' | 'member'>; + acceptedRoles: Array<"admin" | "member">; }) => { return async (req: Request, res: Response, next: NextFunction) => { const { secretSnapshotId } = req.params; @@ -24,14 +24,14 @@ const requireSecretSnapshotAuth = ({ if (!secretSnapshot) { return next(SecretSnapshotNotFoundError({ - message: 'Failed to find secret snapshot' + message: "Failed to find secret snapshot", })); } await validateMembership({ userId: req.user._id, workspaceId: secretSnapshot.workspace, - acceptedRoles + acceptedRoles, }); req.secretSnapshot = secretSnapshot as any; diff --git a/backend/src/ee/models/action.ts b/backend/src/ee/models/action.ts index 055e144fd4..2e84329146 100644 --- a/backend/src/ee/models/action.ts +++ b/backend/src/ee/models/action.ts @@ -1,12 +1,12 @@ -import { Schema, model, Types } from 'mongoose'; +import { Schema, Types, model } from "mongoose"; import { + ACTION_ADD_SECRETS, + ACTION_DELETE_SECRETS, ACTION_LOGIN, ACTION_LOGOUT, - ACTION_ADD_SECRETS, - ACTION_UPDATE_SECRETS, ACTION_READ_SECRETS, - ACTION_DELETE_SECRETS -} from '../../variables'; + ACTION_UPDATE_SECRETS, +} from "../../variables"; export interface IAction { name: string; @@ -30,42 +30,42 @@ const actionSchema = new Schema( ACTION_ADD_SECRETS, ACTION_UPDATE_SECRETS, ACTION_READ_SECRETS, - ACTION_DELETE_SECRETS - ] + ACTION_DELETE_SECRETS, + ], }, user: { type: Schema.Types.ObjectId, - ref: 'User' + ref: "User", }, serviceAccount: { type: Schema.Types.ObjectId, - ref: 'ServiceAccount' + ref: "ServiceAccount", }, serviceTokenData: { type: Schema.Types.ObjectId, - ref: 'ServiceTokenData' + ref: "ServiceTokenData", }, workspace: { type: Schema.Types.ObjectId, - ref: 'Workspace' + ref: "Workspace", }, payload: { secretVersions: [{ oldSecretVersion: { type: Schema.Types.ObjectId, - ref: 'SecretVersion' + ref: "SecretVersion", }, newSecretVersion: { type: Schema.Types.ObjectId, - ref: 'SecretVersion' - } - }] - } + ref: "SecretVersion", + }, + }], + }, }, { - timestamps: true + timestamps: true, } ); -const Action = model('Action', actionSchema); +const Action = model("Action", actionSchema); export default Action; \ No newline at end of file diff --git a/backend/src/ee/models/folderVersion.ts b/backend/src/ee/models/folderVersion.ts index f0fa5afbf5..4bfa2f67cc 100644 --- a/backend/src/ee/models/folderVersion.ts +++ b/backend/src/ee/models/folderVersion.ts @@ -1,4 +1,4 @@ -import { model, Schema, Types } from "mongoose"; +import { Schema, Types, model } from "mongoose"; export type TFolderRootVersionSchema = { _id: Types.ObjectId; diff --git a/backend/src/ee/models/log.ts b/backend/src/ee/models/log.ts index 9ed5526406..5e3d0dbbbf 100644 --- a/backend/src/ee/models/log.ts +++ b/backend/src/ee/models/log.ts @@ -1,12 +1,12 @@ -import { Schema, model, Types } from 'mongoose'; +import { Schema, Types, model } from "mongoose"; import { + ACTION_ADD_SECRETS, + ACTION_DELETE_SECRETS, ACTION_LOGIN, ACTION_LOGOUT, - ACTION_ADD_SECRETS, - ACTION_UPDATE_SECRETS, ACTION_READ_SECRETS, - ACTION_DELETE_SECRETS -} from '../../variables'; + ACTION_UPDATE_SECRETS, +} from "../../variables"; export interface ILog { _id: Types.ObjectId; @@ -24,19 +24,19 @@ const logSchema = new Schema( { user: { type: Schema.Types.ObjectId, - ref: 'User' + ref: "User", }, serviceAccount: { type: Schema.Types.ObjectId, - ref: 'ServiceAccount' + ref: "ServiceAccount", }, serviceTokenData: { type: Schema.Types.ObjectId, - ref: 'ServiceTokenData' + ref: "ServiceTokenData", }, workspace: { type: Schema.Types.ObjectId, - ref: 'Workspace' + ref: "Workspace", }, actionNames: { type: [String], @@ -46,28 +46,28 @@ const logSchema = new Schema( ACTION_ADD_SECRETS, ACTION_UPDATE_SECRETS, ACTION_READ_SECRETS, - ACTION_DELETE_SECRETS + ACTION_DELETE_SECRETS, ], - required: true + required: true, }, actions: [{ type: Schema.Types.ObjectId, - ref: 'Action', - required: true + ref: "Action", + required: true, }], channel: { type: String, - enum: ['web', 'cli', 'auto', 'k8-operator', 'other'], - required: true + enum: ["web", "cli", "auto", "k8-operator", "other"], + required: true, }, ipAddress: { - type: String - } + type: String, + }, }, { - timestamps: true + timestamps: true, } ); -const Log = model('Log', logSchema); +const Log = model("Log", logSchema); export default Log; \ No newline at end of file diff --git a/backend/src/ee/models/secretSnapshot.ts b/backend/src/ee/models/secretSnapshot.ts index cfc5b03b79..d0fb61110b 100644 --- a/backend/src/ee/models/secretSnapshot.ts +++ b/backend/src/ee/models/secretSnapshot.ts @@ -1,4 +1,4 @@ -import { Schema, model, Types } from "mongoose"; +import { Schema, Types, model } from "mongoose"; export interface ISecretSnapshot { workspace: Types.ObjectId; diff --git a/backend/src/ee/models/secretVersion.ts b/backend/src/ee/models/secretVersion.ts index b915e640ed..1922d45399 100644 --- a/backend/src/ee/models/secretVersion.ts +++ b/backend/src/ee/models/secretVersion.ts @@ -1,10 +1,10 @@ -import { Schema, model, Types } from "mongoose"; +import { Schema, Types, model } from "mongoose"; import { - SECRET_SHARED, - SECRET_PERSONAL, ALGORITHM_AES_256_GCM, - ENCODING_SCHEME_UTF8, ENCODING_SCHEME_BASE64, + ENCODING_SCHEME_UTF8, + SECRET_PERSONAL, + SECRET_SHARED, } from "../../variables"; export interface ISecretVersion { @@ -114,9 +114,9 @@ const secretVersionSchema = new Schema( required: true, }, tags: { - ref: 'Tag', + ref: "Tag", type: [Schema.Types.ObjectId], - default: [] + default: [], }, }, { diff --git a/backend/src/ee/routes/v1/action.ts b/backend/src/ee/routes/v1/action.ts index 5dca83cf96..b77a841887 100644 --- a/backend/src/ee/routes/v1/action.ts +++ b/backend/src/ee/routes/v1/action.ts @@ -1,15 +1,15 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); import { - validateRequest -} from '../../../middleware'; -import { param } from 'express-validator'; -import { actionController } from '../../controllers/v1'; + validateRequest, +} from "../../../middleware"; +import { param } from "express-validator"; +import { actionController } from "../../controllers/v1"; // TODO: put into action controller router.get( - '/:actionId', - param('actionId').exists().trim(), + "/:actionId", + param("actionId").exists().trim(), validateRequest, actionController.getAction ); diff --git a/backend/src/ee/routes/v1/cloudProducts.ts b/backend/src/ee/routes/v1/cloudProducts.ts index 73af00aca5..a9be347474 100644 --- a/backend/src/ee/routes/v1/cloudProducts.ts +++ b/backend/src/ee/routes/v1/cloudProducts.ts @@ -1,18 +1,18 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); import { requireAuth, - validateRequest -} from '../../../middleware'; -import { query } from 'express-validator'; -import { cloudProductsController } from '../../controllers/v1'; + validateRequest, +} from "../../../middleware"; +import { query } from "express-validator"; +import { cloudProductsController } from "../../controllers/v1"; router.get( - '/', + "/", requireAuth({ - acceptedAuthModes: ['jwt', 'apiKey'] + acceptedAuthModes: ["jwt", "apiKey"], }), - query('billing-cycle').exists().isIn(['monthly', 'yearly']), + query("billing-cycle").exists().isIn(["monthly", "yearly"]), validateRequest, cloudProductsController.getCloudProducts ); diff --git a/backend/src/ee/routes/v1/index.ts b/backend/src/ee/routes/v1/index.ts index 7568e45d61..c68196c647 100644 --- a/backend/src/ee/routes/v1/index.ts +++ b/backend/src/ee/routes/v1/index.ts @@ -1,9 +1,9 @@ -import secret from './secret'; -import secretSnapshot from './secretSnapshot'; -import organizations from './organizations'; -import workspace from './workspace'; -import action from './action'; -import cloudProducts from './cloudProducts'; +import secret from "./secret"; +import secretSnapshot from "./secretSnapshot"; +import organizations from "./organizations"; +import workspace from "./workspace"; +import action from "./action"; +import cloudProducts from "./cloudProducts"; export { secret, @@ -11,5 +11,5 @@ export { organizations, workspace, action, - cloudProducts + cloudProducts, } \ No newline at end of file diff --git a/backend/src/ee/routes/v1/organizations.ts b/backend/src/ee/routes/v1/organizations.ts index 711b5a17f2..5a9c603b18 100644 --- a/backend/src/ee/routes/v1/organizations.ts +++ b/backend/src/ee/routes/v1/organizations.ts @@ -1,86 +1,86 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); import { requireAuth, requireOrganizationAuth, - validateRequest -} from '../../../middleware'; -import { param, body, query } from 'express-validator'; -import { organizationsController } from '../../controllers/v1'; + validateRequest, +} from "../../../middleware"; +import { body, param, query } from "express-validator"; +import { organizationsController } from "../../controllers/v1"; import { - OWNER, ADMIN, MEMBER, ACCEPTED -} from '../../../variables'; + ACCEPTED, ADMIN, MEMBER, OWNER, +} from "../../../variables"; router.get( - '/:organizationId/plan', + "/:organizationId/plan", requireAuth({ - acceptedAuthModes: ['jwt', 'apiKey'] + acceptedAuthModes: ["jwt", "apiKey"], }), requireOrganizationAuth({ acceptedRoles: [OWNER, ADMIN, MEMBER], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), - param('organizationId').exists().trim(), - query('workspaceId').optional().isString(), + param("organizationId").exists().trim(), + query("workspaceId").optional().isString(), validateRequest, organizationsController.getOrganizationPlan ); router.patch( - '/:organizationId/plan', + "/:organizationId/plan", requireAuth({ - acceptedAuthModes: ['jwt', 'apiKey'] + acceptedAuthModes: ["jwt", "apiKey"], }), requireOrganizationAuth({ acceptedRoles: [OWNER, ADMIN, MEMBER], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), - param('organizationId').exists().trim(), - body('productId').exists().isString(), + param("organizationId").exists().trim(), + body("productId").exists().isString(), validateRequest, organizationsController.updateOrganizationPlan ); router.get( - '/:organizationId/billing-details/payment-methods', + "/:organizationId/billing-details/payment-methods", requireAuth({ - acceptedAuthModes: ['jwt', 'apiKey'] + acceptedAuthModes: ["jwt", "apiKey"], }), requireOrganizationAuth({ acceptedRoles: [OWNER, ADMIN, MEMBER], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), - param('organizationId').exists().trim(), + param("organizationId").exists().trim(), validateRequest, organizationsController.getOrganizationPmtMethods ); router.post( - '/:organizationId/billing-details/payment-methods', + "/:organizationId/billing-details/payment-methods", requireAuth({ - acceptedAuthModes: ['jwt', 'apiKey'] + acceptedAuthModes: ["jwt", "apiKey"], }), requireOrganizationAuth({ acceptedRoles: [OWNER, ADMIN, MEMBER], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), - param('organizationId').exists().trim(), - body('success_url').exists().isString(), - body('cancel_url').exists().isString(), + param("organizationId").exists().trim(), + body("success_url").exists().isString(), + body("cancel_url").exists().isString(), validateRequest, organizationsController.addOrganizationPmtMethod ); router.delete( - '/:organizationId/billing-details/payment-methods/:pmtMethodId', + "/:organizationId/billing-details/payment-methods/:pmtMethodId", requireAuth({ - acceptedAuthModes: ['jwt', 'apiKey'] + acceptedAuthModes: ["jwt", "apiKey"], }), requireOrganizationAuth({ acceptedRoles: [OWNER, ADMIN, MEMBER], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), - param('organizationId').exists().trim(), + param("organizationId").exists().trim(), validateRequest, organizationsController.deleteOrganizationPmtMethod ); diff --git a/backend/src/ee/routes/v1/secret.ts b/backend/src/ee/routes/v1/secret.ts index 3e956a388f..7be6f311a4 100644 --- a/backend/src/ee/routes/v1/secret.ts +++ b/backend/src/ee/routes/v1/secret.ts @@ -1,46 +1,46 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); import { requireAuth, requireSecretAuth, - validateRequest -} from '../../../middleware'; -import { query, param, body } from 'express-validator'; -import { secretController } from '../../controllers/v1'; + validateRequest, +} from "../../../middleware"; +import { body, param, query } from "express-validator"; +import { secretController } from "../../controllers/v1"; import { ADMIN, MEMBER, PERMISSION_READ_SECRETS, - PERMISSION_WRITE_SECRETS -} from '../../../variables'; + PERMISSION_WRITE_SECRETS, +} from "../../../variables"; router.get( - '/:secretId/secret-versions', + "/:secretId/secret-versions", requireAuth({ - acceptedAuthModes: ['jwt', 'apiKey'] + acceptedAuthModes: ["jwt", "apiKey"], }), requireSecretAuth({ acceptedRoles: [ADMIN, MEMBER], - requiredPermissions: [PERMISSION_READ_SECRETS] + requiredPermissions: [PERMISSION_READ_SECRETS], }), - param('secretId').exists().trim(), - query('offset').exists().isInt(), - query('limit').exists().isInt(), + param("secretId").exists().trim(), + query("offset").exists().isInt(), + query("limit").exists().isInt(), validateRequest, secretController.getSecretVersions ); router.post( - '/:secretId/secret-versions/rollback', + "/:secretId/secret-versions/rollback", requireAuth({ - acceptedAuthModes: ['jwt', 'apiKey'] + acceptedAuthModes: ["jwt", "apiKey"], }), requireSecretAuth({ acceptedRoles: [ADMIN, MEMBER], - requiredPermissions: [PERMISSION_READ_SECRETS, PERMISSION_WRITE_SECRETS] + requiredPermissions: [PERMISSION_READ_SECRETS, PERMISSION_WRITE_SECRETS], }), - param('secretId').exists().trim(), - body('version').exists().isInt(), + param("secretId").exists().trim(), + body("version").exists().isInt(), secretController.rollbackSecretVersion ); diff --git a/backend/src/ee/routes/v1/secretSnapshot.ts b/backend/src/ee/routes/v1/secretSnapshot.ts index 80aa7d1ee3..fe0c2690c2 100644 --- a/backend/src/ee/routes/v1/secretSnapshot.ts +++ b/backend/src/ee/routes/v1/secretSnapshot.ts @@ -1,25 +1,25 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); import { - requireSecretSnapshotAuth -} from '../../middleware'; + requireSecretSnapshotAuth, +} from "../../middleware"; import { requireAuth, - validateRequest -} from '../../../middleware'; -import { param } from 'express-validator'; -import { ADMIN, MEMBER } from '../../../variables'; -import { secretSnapshotController } from '../../controllers/v1'; + validateRequest, +} from "../../../middleware"; +import { param } from "express-validator"; +import { ADMIN, MEMBER } from "../../../variables"; +import { secretSnapshotController } from "../../controllers/v1"; router.get( - '/:secretSnapshotId', + "/:secretSnapshotId", requireAuth({ - acceptedAuthModes: ['jwt'] + acceptedAuthModes: ["jwt"], }), requireSecretSnapshotAuth({ - acceptedRoles: [ADMIN, MEMBER] + acceptedRoles: [ADMIN, MEMBER], }), - param('secretSnapshotId').exists().trim(), + param("secretSnapshotId").exists().trim(), validateRequest, secretSnapshotController.getSecretSnapshot ); diff --git a/backend/src/ee/routes/v1/stripe.ts b/backend/src/ee/routes/v1/stripe.ts index 02d68c4ea8..101f44f24d 100644 --- a/backend/src/ee/routes/v1/stripe.ts +++ b/backend/src/ee/routes/v1/stripe.ts @@ -1,7 +1,7 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); -import { stripeController } from '../../controllers/v1'; +import { stripeController } from "../../controllers/v1"; -router.post('/webhook', stripeController.handleWebhook); +router.post("/webhook", stripeController.handleWebhook); export default router; \ No newline at end of file diff --git a/backend/src/ee/routes/v1/workspace.ts b/backend/src/ee/routes/v1/workspace.ts index 2b840892f1..40392b45f4 100644 --- a/backend/src/ee/routes/v1/workspace.ts +++ b/backend/src/ee/routes/v1/workspace.ts @@ -5,7 +5,7 @@ import { requireWorkspaceAuth, validateRequest, } from "../../../middleware"; -import { param, query, body } from "express-validator"; +import { body, param, query } from "express-validator"; import { ADMIN, MEMBER } from "../../../variables"; import { workspaceController } from "../../controllers/v1"; diff --git a/backend/src/ee/services/EELicenseService.ts b/backend/src/ee/services/EELicenseService.ts index 89e71e57bd..6417eeb1c5 100644 --- a/backend/src/ee/services/EELicenseService.ts +++ b/backend/src/ee/services/EELicenseService.ts @@ -1,22 +1,22 @@ -import * as Sentry from '@sentry/node'; -import NodeCache from 'node-cache'; +import * as Sentry from "@sentry/node"; +import NodeCache from "node-cache"; import { getLicenseKey, getLicenseServerKey, - getLicenseServerUrl -} from '../../config'; + getLicenseServerUrl, +} from "../../config"; import { licenseKeyRequest, licenseServerKeyRequest, + refreshLicenseKeyToken, refreshLicenseServerKeyToken, - refreshLicenseKeyToken -} from '../../config/request'; -import { Organization } from '../../models'; -import { OrganizationNotFoundError } from '../../utils/errors'; +} from "../../config/request"; +import { Organization } from "../../models"; +import { OrganizationNotFoundError } from "../../utils/errors"; interface FeatureSet { _id: string | null; - slug: 'starter' | 'team' | 'pro' | 'enterprise' | null; + slug: "starter" | "team" | "pro" | "enterprise" | null; tier: number; workspaceLimit: number | null; workspacesUsed: number; @@ -42,7 +42,7 @@ class EELicenseService { private readonly _isLicenseValid: boolean; // TODO: deprecate - public instanceType: 'self-hosted' | 'enterprise-self-hosted' | 'cloud' = 'self-hosted'; + public instanceType: "self-hosted" | "enterprise-self-hosted" | "cloud" = "self-hosted"; public globalFeatureSet: FeatureSet = { _id: null, @@ -59,7 +59,7 @@ class EELicenseService { rbac: true, customRateLimits: true, customAlerts: true, - auditLogs: false + auditLogs: false, } public localFeatureSet: NodeCache; @@ -67,14 +67,14 @@ class EELicenseService { constructor() { this._isLicenseValid = true; this.localFeatureSet = new NodeCache({ - stdTTL: 300 + stdTTL: 300, }); } public async getPlan(organizationId: string, workspaceId?: string): Promise { try { - if (this.instanceType === 'cloud') { - const cachedPlan = this.localFeatureSet.get(`${organizationId}-${workspaceId ?? ''}`); + if (this.instanceType === "cloud") { + const cachedPlan = this.localFeatureSet.get(`${organizationId}-${workspaceId ?? ""}`); if (cachedPlan) { return cachedPlan; } @@ -91,7 +91,7 @@ class EELicenseService { const { data: { currentPlan } } = await licenseServerKeyRequest.get(url); // cache fetched plan for organization - this.localFeatureSet.set(`${organizationId}-${workspaceId ?? ''}`, currentPlan); + this.localFeatureSet.set(`${organizationId}-${workspaceId ?? ""}`, currentPlan); return currentPlan; } @@ -103,8 +103,8 @@ class EELicenseService { } public async refreshPlan(organizationId: string, workspaceId?: string) { - if (this.instanceType === 'cloud') { - this.localFeatureSet.del(`${organizationId}-${workspaceId ?? ''}`); + if (this.instanceType === "cloud") { + this.localFeatureSet.del(`${organizationId}-${workspaceId ?? ""}`); await this.getPlan(organizationId, workspaceId); } } @@ -119,7 +119,7 @@ class EELicenseService { const token = await refreshLicenseServerKeyToken() if (token) { - this.instanceType = 'cloud'; + this.instanceType = "cloud"; } return; @@ -135,7 +135,7 @@ class EELicenseService { ); this.globalFeatureSet = currentPlan; - this.instanceType = 'enterprise-self-hosted'; + this.instanceType = "enterprise-self-hosted"; } } } catch (err) { diff --git a/backend/src/ee/services/EELogService.ts b/backend/src/ee/services/EELogService.ts index 81d26765fb..70f7029538 100644 --- a/backend/src/ee/services/EELogService.ts +++ b/backend/src/ee/services/EELogService.ts @@ -1,14 +1,14 @@ -import { Types } from 'mongoose'; +import { Types } from "mongoose"; import { - IAction -} from '../models'; + IAction, +} from "../models"; import { - createLogHelper -} from '../helpers/log'; + createLogHelper, +} from "../helpers/log"; import { - createActionHelper -} from '../helpers/action'; -import EELicenseService from './EELicenseService'; + createActionHelper, +} from "../helpers/action"; +import EELicenseService from "./EELicenseService"; /** * Class to handle Enterprise Edition log actions @@ -31,7 +31,7 @@ class EELogService { workspaceId, actions, channel, - ipAddress + ipAddress, }: { userId?: Types.ObjectId; serviceAccountId?: Types.ObjectId; @@ -49,7 +49,7 @@ class EELogService { workspaceId, actions, channel, - ipAddress + ipAddress, }) } @@ -68,7 +68,7 @@ class EELogService { serviceAccountId, serviceTokenDataId, workspaceId, - secretIds + secretIds, }: { name: string; userId?: Types.ObjectId; @@ -83,7 +83,7 @@ class EELogService { serviceAccountId, serviceTokenDataId, workspaceId, - secretIds + secretIds, }); } } diff --git a/backend/src/ee/services/EESecretService.ts b/backend/src/ee/services/EESecretService.ts index a0803dd36c..5a1c4d3cb9 100644 --- a/backend/src/ee/services/EESecretService.ts +++ b/backend/src/ee/services/EESecretService.ts @@ -1,11 +1,11 @@ -import { Types } from 'mongoose'; -import { ISecretVersion } from '../models'; +import { Types } from "mongoose"; +import { ISecretVersion } from "../models"; import { - takeSecretSnapshotHelper, addSecretVersionsHelper, markDeletedSecretVersionsHelper, -} from '../helpers/secret'; -import EELicenseService from './EELicenseService'; + takeSecretSnapshotHelper, +} from "../helpers/secret"; +import EELicenseService from "./EELicenseService"; /** * Class to handle Enterprise Edition secret actions diff --git a/backend/src/ee/services/index.ts b/backend/src/ee/services/index.ts index b3544bcff1..afc3fb80eb 100644 --- a/backend/src/ee/services/index.ts +++ b/backend/src/ee/services/index.ts @@ -5,5 +5,5 @@ import EELogService from "./EELogService"; export { EELicenseService, EESecretService, - EELogService + EELogService, } \ No newline at end of file diff --git a/backend/src/events/index.ts b/backend/src/events/index.ts index 461a3ece62..d8198d2fb3 100644 --- a/backend/src/events/index.ts +++ b/backend/src/events/index.ts @@ -1,5 +1,5 @@ import { eventPushSecrets } from "./secret" export { - eventPushSecrets + eventPushSecrets, } \ No newline at end of file diff --git a/backend/src/events/secret.ts b/backend/src/events/secret.ts index 6007dd6829..23ff9f59cb 100644 --- a/backend/src/events/secret.ts +++ b/backend/src/events/secret.ts @@ -1,8 +1,8 @@ -import { Types } from 'mongoose'; +import { Types } from "mongoose"; import { + EVENT_PULL_SECRETS, EVENT_PUSH_SECRETS, - EVENT_PULL_SECRETS -} from '../variables'; +} from "../variables"; interface PushSecret { ciphertextKey: string; @@ -13,7 +13,7 @@ interface PushSecret { ivValue: string; tagValue: string; hashValue: string; - type: 'shared' | 'personal'; + type: "shared" | "personal"; } /** @@ -24,7 +24,7 @@ interface PushSecret { */ const eventPushSecrets = ({ workspaceId, - environment + environment, }: { workspaceId: Types.ObjectId; environment?: string; @@ -35,7 +35,7 @@ const eventPushSecrets = ({ environment, payload: { - } + }, }); } @@ -55,10 +55,10 @@ const eventPullSecrets = ({ workspaceId, payload: { - } + }, }); } export { - eventPushSecrets + eventPushSecrets, } diff --git a/backend/src/helpers/auth.ts b/backend/src/helpers/auth.ts index ce61f3650e..00ed43abad 100644 --- a/backend/src/helpers/auth.ts +++ b/backend/src/helpers/auth.ts @@ -1,36 +1,36 @@ -import { Types } from 'mongoose'; -import jwt from 'jsonwebtoken'; -import bcrypt from 'bcrypt'; +import { Types } from "mongoose"; +import jwt from "jsonwebtoken"; +import bcrypt from "bcrypt"; import { - IUser, - User, - ServiceTokenData, - ServiceAccount, APIKeyData, + ITokenVersion, + IUser, + ServiceAccount, + ServiceTokenData, TokenVersion, - ITokenVersion -} from '../models'; + User, +} from "../models"; import { - AccountNotFoundError, - ServiceTokenDataNotFoundError, - ServiceAccountNotFoundError, APIKeyDataNotFoundError, + AccountNotFoundError, + BadRequestError, + ServiceAccountNotFoundError, + ServiceTokenDataNotFoundError, UnauthorizedRequestError, - BadRequestError -} from '../utils/errors'; +} from "../utils/errors"; import { getJwtAuthLifetime, getJwtAuthSecret, getJwtProviderAuthSecret, getJwtRefreshLifetime, - getJwtRefreshSecret -} from '../config'; + getJwtRefreshSecret, +} from "../config"; import { + AUTH_MODE_API_KEY, AUTH_MODE_JWT, AUTH_MODE_SERVICE_ACCOUNT, AUTH_MODE_SERVICE_TOKEN, - AUTH_MODE_API_KEY -} from '../variables'; +} from "../variables"; /** * @@ -39,41 +39,41 @@ import { */ export const validateAuthMode = ({ headers, - acceptedAuthModes + acceptedAuthModes, }: { headers: { [key: string]: string | string[] | undefined }, acceptedAuthModes: string[] }) => { - const apiKey = headers['x-api-key']; - const authHeader = headers['authorization']; + const apiKey = headers["x-api-key"]; + const authHeader = headers["authorization"]; let authMode, authTokenValue; if (apiKey === undefined && authHeader === undefined) { // case: no auth or X-API-KEY header present - throw BadRequestError({ message: 'Missing Authorization or X-API-KEY in request header.' }); + throw BadRequestError({ message: "Missing Authorization or X-API-KEY in request header." }); } - if (typeof apiKey === 'string') { + if (typeof apiKey === "string") { // case: treat request authentication type as via X-API-KEY (i.e. API Key) authMode = AUTH_MODE_API_KEY; authTokenValue = apiKey; } - if (typeof authHeader === 'string') { + if (typeof authHeader === "string") { // case: treat request authentication type as via Authorization header (i.e. either JWT or service token) - const [tokenType, tokenValue] = <[string, string]>authHeader.split(' ', 2) ?? [null, null] + const [tokenType, tokenValue] = <[string, string]>authHeader.split(" ", 2) ?? [null, null] if (tokenType === null) - throw BadRequestError({ message: `Missing Authorization Header in the request header.` }); - if (tokenType.toLowerCase() !== 'bearer') + throw BadRequestError({ message: "Missing Authorization Header in the request header." }); + if (tokenType.toLowerCase() !== "bearer") throw BadRequestError({ message: `The provided authentication type '${tokenType}' is not supported.` }); if (tokenValue === null) - throw BadRequestError({ message: 'Missing Authorization Body in the request header.' }); + throw BadRequestError({ message: "Missing Authorization Body in the request header." }); - switch (tokenValue.split('.', 1)[0]) { - case 'st': + switch (tokenValue.split(".", 1)[0]) { + case "st": authMode = AUTH_MODE_SERVICE_TOKEN; break; - case 'sa': + case "sa": authMode = AUTH_MODE_SERVICE_ACCOUNT; break; default: @@ -83,13 +83,13 @@ export const validateAuthMode = ({ authTokenValue = tokenValue; } - if (!authMode || !authTokenValue) throw BadRequestError({ message: 'Missing valid Authorization or X-API-KEY in request header.' }); + if (!authMode || !authTokenValue) throw BadRequestError({ message: "Missing valid Authorization or X-API-KEY in request header." }); - if (!acceptedAuthModes.includes(authMode)) throw BadRequestError({ message: 'The provided authentication type is not supported.' }); + if (!acceptedAuthModes.includes(authMode)) throw BadRequestError({ message: "The provided authentication type is not supported." }); return ({ authMode, - authTokenValue + authTokenValue, }); } @@ -100,7 +100,7 @@ export const validateAuthMode = ({ * @returns {User} user - user corresponding to JWT token */ export const getAuthUserPayload = async ({ - authTokenValue + authTokenValue, }: { authTokenValue: string; }) => { @@ -109,31 +109,31 @@ export const getAuthUserPayload = async ({ ); const user = await User.findOne({ - _id: new Types.ObjectId(decodedToken.userId) - }).select('+publicKey +accessVersion'); + _id: new Types.ObjectId(decodedToken.userId), + }).select("+publicKey +accessVersion"); - if (!user) throw AccountNotFoundError({ message: 'Failed to find user' }); + if (!user) throw AccountNotFoundError({ message: "Failed to find user" }); - if (!user?.publicKey) throw UnauthorizedRequestError({ message: 'Failed to authenticate user with partially set up account' }); + if (!user?.publicKey) throw UnauthorizedRequestError({ message: "Failed to authenticate user with partially set up account" }); const tokenVersion = await TokenVersion.findOneAndUpdate({ _id: new Types.ObjectId(decodedToken.tokenVersionId), - user: user._id + user: user._id, }, { - lastUsed: new Date() + lastUsed: new Date(), }); if (!tokenVersion) throw UnauthorizedRequestError({ - message: 'Failed to validate access token' + message: "Failed to validate access token", }); if (decodedToken.accessVersion !== tokenVersion.accessVersion) throw UnauthorizedRequestError({ - message: 'Failed to validate access token' + message: "Failed to validate access token", }); return ({ user, - tokenVersionId: tokenVersion._id + tokenVersionId: tokenVersion._id, }); } @@ -144,41 +144,41 @@ export const getAuthUserPayload = async ({ * @returns {ServiceTokenData} serviceTokenData - service token data */ export const getAuthSTDPayload = async ({ - authTokenValue + authTokenValue, }: { authTokenValue: string; }) => { - const [_, TOKEN_IDENTIFIER, TOKEN_SECRET] = <[string, string, string]>authTokenValue.split('.', 3); + const [_, TOKEN_IDENTIFIER, TOKEN_SECRET] = <[string, string, string]>authTokenValue.split(".", 3); let serviceTokenData = await ServiceTokenData - .findById(TOKEN_IDENTIFIER, '+secretHash +expiresAt'); + .findById(TOKEN_IDENTIFIER, "+secretHash +expiresAt"); if (!serviceTokenData) { - throw ServiceTokenDataNotFoundError({ message: 'Failed to find service token data' }); + throw ServiceTokenDataNotFoundError({ message: "Failed to find service token data" }); } else if (serviceTokenData?.expiresAt && new Date(serviceTokenData.expiresAt) < new Date()) { // case: service token expired await ServiceTokenData.findByIdAndDelete(serviceTokenData._id); throw UnauthorizedRequestError({ - message: 'Failed to authenticate expired service token' + message: "Failed to authenticate expired service token", }); } const isMatch = await bcrypt.compare(TOKEN_SECRET, serviceTokenData.secretHash); if (!isMatch) throw UnauthorizedRequestError({ - message: 'Failed to authenticate service token' + message: "Failed to authenticate service token", }); serviceTokenData = await ServiceTokenData .findOneAndUpdate({ - _id: new Types.ObjectId(TOKEN_IDENTIFIER) + _id: new Types.ObjectId(TOKEN_IDENTIFIER), }, { - lastUsed: new Date() + lastUsed: new Date(), }, { - new: true + new: true, }) - .select('+encryptedKey +iv +tag'); + .select("+encryptedKey +iv +tag"); - if (!serviceTokenData) throw ServiceTokenDataNotFoundError({ message: 'Failed to find service token data' }); + if (!serviceTokenData) throw ServiceTokenDataNotFoundError({ message: "Failed to find service token data" }); return serviceTokenData; } @@ -190,23 +190,23 @@ export const getAuthSTDPayload = async ({ * @returns {ServiceAccount} serviceAccount */ export const getAuthSAAKPayload = async ({ - authTokenValue + authTokenValue, }: { authTokenValue: string; }) => { - const [_, TOKEN_IDENTIFIER, TOKEN_SECRET] = <[string, string, string]>authTokenValue.split('.', 3); + const [_, TOKEN_IDENTIFIER, TOKEN_SECRET] = <[string, string, string]>authTokenValue.split(".", 3); const serviceAccount = await ServiceAccount.findById( - Buffer.from(TOKEN_IDENTIFIER, 'base64').toString('hex') - ).select('+secretHash'); + Buffer.from(TOKEN_IDENTIFIER, "base64").toString("hex") + ).select("+secretHash"); if (!serviceAccount) { - throw ServiceAccountNotFoundError({ message: 'Failed to find service account' }); + throw ServiceAccountNotFoundError({ message: "Failed to find service account" }); } const result = await bcrypt.compare(TOKEN_SECRET, serviceAccount.secretHash); if (!result) throw UnauthorizedRequestError({ - message: 'Failed to authenticate service account access key' + message: "Failed to authenticate service account access key", }); return serviceAccount; @@ -219,48 +219,48 @@ export const getAuthSAAKPayload = async ({ * @returns {APIKeyData} apiKeyData - API key data */ export const getAuthAPIKeyPayload = async ({ - authTokenValue + authTokenValue, }: { authTokenValue: string; }) => { - const [_, TOKEN_IDENTIFIER, TOKEN_SECRET] = <[string, string, string]>authTokenValue.split('.', 3); + const [_, TOKEN_IDENTIFIER, TOKEN_SECRET] = <[string, string, string]>authTokenValue.split(".", 3); let apiKeyData = await APIKeyData - .findById(TOKEN_IDENTIFIER, '+secretHash +expiresAt') - .populate<{ user: IUser }>('user', '+publicKey'); + .findById(TOKEN_IDENTIFIER, "+secretHash +expiresAt") + .populate<{ user: IUser }>("user", "+publicKey"); if (!apiKeyData) { - throw APIKeyDataNotFoundError({ message: 'Failed to find API key data' }); + throw APIKeyDataNotFoundError({ message: "Failed to find API key data" }); } else if (apiKeyData?.expiresAt && new Date(apiKeyData.expiresAt) < new Date()) { // case: API key expired await APIKeyData.findByIdAndDelete(apiKeyData._id); throw UnauthorizedRequestError({ - message: 'Failed to authenticate expired API key' + message: "Failed to authenticate expired API key", }); } const isMatch = await bcrypt.compare(TOKEN_SECRET, apiKeyData.secretHash); if (!isMatch) throw UnauthorizedRequestError({ - message: 'Failed to authenticate API key' + message: "Failed to authenticate API key", }); apiKeyData = await APIKeyData.findOneAndUpdate({ - _id: new Types.ObjectId(TOKEN_IDENTIFIER) + _id: new Types.ObjectId(TOKEN_IDENTIFIER), }, { - lastUsed: new Date() + lastUsed: new Date(), }, { - new: true + new: true, }); if (!apiKeyData) { - throw APIKeyDataNotFoundError({ message: 'Failed to find API key data' }); + throw APIKeyDataNotFoundError({ message: "Failed to find API key data" }); } - const user = await User.findById(apiKeyData.user).select('+publicKey'); + const user = await User.findById(apiKeyData.user).select("+publicKey"); if (!user) { throw AccountNotFoundError({ - message: 'Failed to find user' + message: "Failed to find user", }); } @@ -278,7 +278,7 @@ export const getAuthAPIKeyPayload = async ({ export const issueAuthTokens = async ({ userId, ip, - userAgent + userAgent, }: { userId: Types.ObjectId; ip: string; @@ -290,7 +290,7 @@ export const issueAuthTokens = async ({ tokenVersion = await TokenVersion.findOne({ user: userId, ip, - userAgent + userAgent, }); if (!tokenVersion) { @@ -302,7 +302,7 @@ export const issueAuthTokens = async ({ accessVersion: 0, ip, userAgent, - lastUsed: new Date() + lastUsed: new Date(), }).save(); } @@ -311,25 +311,25 @@ export const issueAuthTokens = async ({ payload: { userId, tokenVersionId: tokenVersion._id.toString(), - accessVersion: tokenVersion.accessVersion + accessVersion: tokenVersion.accessVersion, }, expiresIn: await getJwtAuthLifetime(), - secret: await getJwtAuthSecret() + secret: await getJwtAuthSecret(), }); const refreshToken = createToken({ payload: { userId, tokenVersionId: tokenVersion._id.toString(), - refreshVersion: tokenVersion.refreshVersion + refreshVersion: tokenVersion.refreshVersion, }, expiresIn: await getJwtRefreshLifetime(), - secret: await getJwtRefreshSecret() + secret: await getJwtRefreshSecret(), }); return { token, - refreshToken + refreshToken, }; }; @@ -342,12 +342,12 @@ export const clearTokens = async (tokenVersionId: Types.ObjectId): Promise // increment refreshVersion on user by 1 await TokenVersion.findOneAndUpdate({ - _id: tokenVersionId + _id: tokenVersionId, }, { $inc: { refreshVersion: 1, - accessVersion: 1 - } + accessVersion: 1, + }, }); }; @@ -362,14 +362,14 @@ export const clearTokens = async (tokenVersionId: Types.ObjectId): Promise export const createToken = ({ payload, expiresIn, - secret + secret, }: { payload: any; expiresIn: string | number; secret: string; }) => { return jwt.sign(payload, secret, { - expiresIn + expiresIn, }); }; @@ -383,7 +383,7 @@ export const validateProviderAuthToken = async ({ providerAuthToken?: string; }) => { if (!providerAuthToken) { - throw new Error('Invalid authentication request.'); + throw new Error("Invalid authentication request."); } const decodedToken = ( @@ -394,6 +394,6 @@ export const validateProviderAuthToken = async ({ decodedToken.authProvider !== user.authProvider || decodedToken.email !== email ) { - throw new Error('Invalid authentication credentials.') + throw new Error("Invalid authentication credentials.") } } \ No newline at end of file diff --git a/backend/src/helpers/bot.ts b/backend/src/helpers/bot.ts index 8c3b5b8163..c7c5904c7c 100644 --- a/backend/src/helpers/bot.ts +++ b/backend/src/helpers/bot.ts @@ -1,18 +1,18 @@ import { Types } from "mongoose"; -import { Bot, BotKey, Secret, ISecret, IUser } from "../models"; +import { Bot, BotKey, ISecret, IUser, Secret } from "../models"; import { - generateKeyPair, - encryptSymmetric128BitHexKeyUTF8, - decryptSymmetric128BitHexKeyUTF8, decryptAsymmetric, + decryptSymmetric128BitHexKeyUTF8, + encryptSymmetric128BitHexKeyUTF8, + generateKeyPair, } from "../utils/crypto"; import { - SECRET_SHARED, ALGORITHM_AES_256_GCM, - ENCODING_SCHEME_UTF8, ENCODING_SCHEME_BASE64, + ENCODING_SCHEME_UTF8, + SECRET_SHARED, } from "../variables"; -import { getEncryptionKey, getRootEncryptionKey, client } from "../config"; +import { client, getEncryptionKey, getRootEncryptionKey } from "../config"; import { InternalServerError } from "../utils/errors"; import Folder from "../models/folder"; import { getFolderByPath } from "../services/FolderService"; diff --git a/backend/src/helpers/database.ts b/backend/src/helpers/database.ts index b9284bbf8c..4780be346d 100644 --- a/backend/src/helpers/database.ts +++ b/backend/src/helpers/database.ts @@ -1,5 +1,5 @@ -import mongoose from 'mongoose'; -import { getLogger } from '../utils/logger'; +import mongoose from "mongoose"; +import { getLogger } from "../utils/logger"; /** * Initialize database connection @@ -8,7 +8,7 @@ import { getLogger } from '../utils/logger'; * @returns */ export const initDatabaseHelper = async ({ - mongoURL + mongoURL, }: { mongoURL: string; }) => { @@ -16,7 +16,7 @@ export const initDatabaseHelper = async ({ await mongoose.connect(mongoURL); // allow empty strings to pass the required validator - mongoose.Schema.Types.String.checkRequired(v => typeof v === 'string'); + mongoose.Schema.Types.String.checkRequired(v => typeof v === "string"); (await getLogger("database")).info("Database connection established"); @@ -35,10 +35,10 @@ export const closeDatabaseHelper = async () => { new Promise((resolve) => { if (mongoose.connection && mongoose.connection.readyState == 1) { mongoose.connection.close() - .then(() => resolve('Database connection closed')); + .then(() => resolve("Database connection closed")); } else { - resolve('Database connection already closed'); + resolve("Database connection already closed"); } - }) + }), ]); } \ No newline at end of file diff --git a/backend/src/helpers/event.ts b/backend/src/helpers/event.ts index 47c2437494..124da257c9 100644 --- a/backend/src/helpers/event.ts +++ b/backend/src/helpers/event.ts @@ -1,5 +1,5 @@ import { Types } from "mongoose"; -import { Bot, IBot } from "../models"; +import { Bot } from "../models"; import { EVENT_PUSH_SECRETS } from "../variables"; import { IntegrationService } from "../services"; diff --git a/backend/src/helpers/index.ts b/backend/src/helpers/index.ts index b9d85f8713..f9a0009fc8 100644 --- a/backend/src/helpers/index.ts +++ b/backend/src/helpers/index.ts @@ -1,17 +1,17 @@ -export * from './auth'; -export * from './bot'; -export * from './database'; -export * from './event'; -export * from './integration'; -export * from './key'; -export * from './membership'; -export * from './membershipOrg'; -export * from './nodemailer'; -export * from './organization'; -export * from './rateLimiter'; -export * from './secret'; -export * from './secrets'; -export * from './signup'; -export * from './token'; -export * from './user'; -export * from './workspace'; \ No newline at end of file +export * from "./auth"; +export * from "./bot"; +export * from "./database"; +export * from "./event"; +export * from "./integration"; +export * from "./key"; +export * from "./membership"; +export * from "./membershipOrg"; +export * from "./nodemailer"; +export * from "./organization"; +export * from "./rateLimiter"; +export * from "./secret"; +export * from "./secrets"; +export * from "./signup"; +export * from "./token"; +export * from "./user"; +export * from "./workspace"; \ No newline at end of file diff --git a/backend/src/helpers/integration.ts b/backend/src/helpers/integration.ts index baf41d762c..f2dd1ba666 100644 --- a/backend/src/helpers/integration.ts +++ b/backend/src/helpers/integration.ts @@ -3,10 +3,10 @@ import { Bot, Integration, IntegrationAuth } from "../models"; import { exchangeCode, exchangeRefresh, syncSecrets } from "../integrations"; import { BotService } from "../services"; import { - INTEGRATION_VERCEL, - INTEGRATION_NETLIFY, ALGORITHM_AES_256_GCM, ENCODING_SCHEME_UTF8, + INTEGRATION_NETLIFY, + INTEGRATION_VERCEL, } from "../variables"; import { UnauthorizedRequestError } from "../utils/errors"; diff --git a/backend/src/helpers/key.ts b/backend/src/helpers/key.ts index afb4f6396b..88bf28f473 100644 --- a/backend/src/helpers/key.ts +++ b/backend/src/helpers/key.ts @@ -1,4 +1,4 @@ -import { Key, IKey } from '../models'; +import { IKey, Key } from "../models"; interface Key { encryptedKey: string; @@ -20,7 +20,7 @@ interface Key { export const pushKeys = async ({ userId, workspaceId, - keys + keys, }: { userId: string; workspaceId: string; @@ -31,9 +31,9 @@ export const pushKeys = async ({ ( await Key.find( { - workspace: workspaceId + workspace: workspaceId, }, - 'receiver' + "receiver" ) ).map((k: IKey) => k.receiver.toString()) ); @@ -47,7 +47,7 @@ export const pushKeys = async ({ nonce: k.nonce, sender: userId, receiver: k.userId, - workspace: workspaceId + workspace: workspaceId, })) ); }; \ No newline at end of file diff --git a/backend/src/helpers/membership.ts b/backend/src/helpers/membership.ts index 9762975129..d2fcf5b173 100644 --- a/backend/src/helpers/membership.ts +++ b/backend/src/helpers/membership.ts @@ -1,6 +1,6 @@ import { Types } from "mongoose"; -import { Membership, Key } from "../models"; -import { MembershipNotFoundError, BadRequestError } from "../utils/errors"; +import { Key, Membership } from "../models"; +import { BadRequestError, MembershipNotFoundError } from "../utils/errors"; /** * Validate that user with id [userId] is a member of workspace with id [workspaceId] @@ -62,7 +62,7 @@ export const findMembership = async (queryObj: any) => { export const addMemberships = async ({ userIds, workspaceId, - roles + roles, }: { userIds: string[]; workspaceId: string; @@ -95,7 +95,7 @@ export const addMemberships = async ({ */ export const deleteMembership = async ({ membershipId }: { membershipId: string }) => { const deletedMembership = await Membership.findOneAndDelete({ - _id: membershipId + _id: membershipId, }); // delete keys associated with the membership diff --git a/backend/src/helpers/membershipOrg.ts b/backend/src/helpers/membershipOrg.ts index f29f3cec02..3ed5be0887 100644 --- a/backend/src/helpers/membershipOrg.ts +++ b/backend/src/helpers/membershipOrg.ts @@ -1,14 +1,14 @@ -import { Types } from 'mongoose'; +import { Types } from "mongoose"; import { - MembershipOrg, - Workspace, + Key, Membership, - Key -} from '../models'; + MembershipOrg, + Workspace, +} from "../models"; import { MembershipOrgNotFoundError, - UnauthorizedRequestError -} from '../utils/errors'; + UnauthorizedRequestError, +} from "../utils/errors"; /** * Validate that user with id [userId] is a member of organization with id [organizationId] @@ -22,31 +22,31 @@ export const validateMembershipOrg = async ({ userId, organizationId, acceptedRoles, - acceptedStatuses + acceptedStatuses, }: { userId: Types.ObjectId; organizationId: Types.ObjectId; - acceptedRoles?: Array<'owner' | 'admin' | 'member'>; - acceptedStatuses?: Array<'invited' | 'accepted'>; + acceptedRoles?: Array<"owner" | "admin" | "member">; + acceptedStatuses?: Array<"invited" | "accepted">; }) => { const membershipOrg = await MembershipOrg.findOne({ user: userId, - organization: organizationId + organization: organizationId, }); if (!membershipOrg) { - throw MembershipOrgNotFoundError({ message: 'Failed to find organization membership' }); + throw MembershipOrgNotFoundError({ message: "Failed to find organization membership" }); } if (acceptedRoles) { if (!acceptedRoles.includes(membershipOrg.role)) { - throw UnauthorizedRequestError({ message: 'Failed to validate organization membership role' }); + throw UnauthorizedRequestError({ message: "Failed to validate organization membership role" }); } } if (acceptedStatuses) { if (!acceptedStatuses.includes(membershipOrg.status)) { - throw UnauthorizedRequestError({ message: 'Failed to validate organization membership status' }); + throw UnauthorizedRequestError({ message: "Failed to validate organization membership status" }); } } @@ -76,7 +76,7 @@ export const addMembershipsOrg = async ({ userIds, organizationId, roles, - statuses + statuses, }: { userIds: string[]; organizationId: string; @@ -90,16 +90,16 @@ export const addMembershipsOrg = async ({ user: userId, organization: organizationId, role: roles[idx], - status: statuses[idx] + status: statuses[idx], }, update: { user: userId, organization: organizationId, role: roles[idx], - status: statuses[idx] + status: statuses[idx], }, - upsert: true - } + upsert: true, + }, }; }); @@ -112,15 +112,15 @@ export const addMembershipsOrg = async ({ * @param {String} obj.membershipOrgId - id of organization membership to delete */ export const deleteMembershipOrg = async ({ - membershipOrgId + membershipOrgId, }: { membershipOrgId: string; }) => { const deletedMembershipOrg = await MembershipOrg.findOneAndDelete({ - _id: membershipOrgId + _id: membershipOrgId, }); - if (!deletedMembershipOrg) throw new Error('Failed to delete organization membership'); + if (!deletedMembershipOrg) throw new Error("Failed to delete organization membership"); // delete keys associated with organization membership if (deletedMembershipOrg?.user) { @@ -128,22 +128,22 @@ export const deleteMembershipOrg = async ({ const workspaces = ( await Workspace.find({ - organization: deletedMembershipOrg.organization + organization: deletedMembershipOrg.organization, }) ).map((w) => w._id.toString()); await Membership.deleteMany({ user: deletedMembershipOrg.user, workspace: { - $in: workspaces - } + $in: workspaces, + }, }); await Key.deleteMany({ receiver: deletedMembershipOrg.user, workspace: { - $in: workspaces - } + $in: workspaces, + }, }); } diff --git a/backend/src/helpers/nodemailer.ts b/backend/src/helpers/nodemailer.ts index ffd39d7ddb..b83d9bf615 100644 --- a/backend/src/helpers/nodemailer.ts +++ b/backend/src/helpers/nodemailer.ts @@ -1,8 +1,8 @@ -import fs from 'fs'; -import path from 'path'; -import handlebars from 'handlebars'; -import nodemailer from 'nodemailer'; -import { getSmtpFromName, getSmtpFromAddress, getSmtpConfigured } from '../config'; +import fs from "fs"; +import path from "path"; +import handlebars from "handlebars"; +import nodemailer from "nodemailer"; +import { getSmtpConfigured, getSmtpFromAddress, getSmtpFromName } from "../config"; let smtpTransporter: nodemailer.Transporter; @@ -17,7 +17,7 @@ export const sendMail = async ({ template, subjectLine, recipients, - substitutions + substitutions, }: { template: string; subjectLine: string; @@ -26,17 +26,17 @@ export const sendMail = async ({ }) => { if (await getSmtpConfigured()) { const html = fs.readFileSync( - path.resolve(__dirname, '../templates/' + template), - 'utf8' + path.resolve(__dirname, "../templates/" + template), + "utf8" ); const temp = handlebars.compile(html); const htmlToSend = temp(substitutions); await smtpTransporter.sendMail({ from: `"${await getSmtpFromName()}" <${await getSmtpFromAddress()}>`, - to: recipients.join(', '), + to: recipients.join(", "), subject: subjectLine, - html: htmlToSend + html: htmlToSend, }); } }; diff --git a/backend/src/helpers/organization.ts b/backend/src/helpers/organization.ts index b88fbdf126..642a1233bb 100644 --- a/backend/src/helpers/organization.ts +++ b/backend/src/helpers/organization.ts @@ -1,25 +1,25 @@ import Stripe from "stripe"; import { Types } from "mongoose"; -import { Organization, MembershipOrg } from "../models"; +import { MembershipOrg, Organization } from "../models"; import { - ACCEPTED + ACCEPTED, } from "../variables"; import { - getStripeSecretKey, getStripeProductPro, - getStripeProductTeam, getStripeProductStarter, + getStripeProductTeam, + getStripeSecretKey, } from "../config"; import { - EELicenseService -} from '../ee/services'; + EELicenseService, +} from "../ee/services"; import { - getLicenseServerUrl -} from '../config'; + getLicenseServerUrl, +} from "../config"; import { + licenseKeyRequest, licenseServerKeyRequest, - licenseKeyRequest -} from '../config/request'; +} from "../config/request"; /** * Create an organization with name [name] @@ -137,7 +137,7 @@ export const updateSubscriptionOrgQuantity = async ({ }); if (organization && organization.customerId) { - if (EELicenseService.instanceType === 'cloud') { + if (EELicenseService.instanceType === "cloud") { // instance of Infisical is a cloud instance const quantity = await MembershipOrg.countDocuments({ organization: new Types.ObjectId(organizationId), @@ -147,7 +147,7 @@ export const updateSubscriptionOrgQuantity = async ({ await licenseServerKeyRequest.patch( `${await getLicenseServerUrl()}/api/license-server/v1/customers/${organization.customerId}/cloud-plan`, { - quantity + quantity, } ); @@ -155,17 +155,17 @@ export const updateSubscriptionOrgQuantity = async ({ } } - if (EELicenseService.instanceType === 'enterprise-self-hosted') { + if (EELicenseService.instanceType === "enterprise-self-hosted") { // instance of Infisical is an enterprise self-hosted instance const usedSeats = await MembershipOrg.countDocuments({ - status: ACCEPTED + status: ACCEPTED, }); await licenseKeyRequest.patch( `${await getLicenseServerUrl()}/api/license/v1/license`, { - usedSeats + usedSeats, } ); } diff --git a/backend/src/helpers/rateLimiter.ts b/backend/src/helpers/rateLimiter.ts index 123b230a49..853e7c2ed7 100644 --- a/backend/src/helpers/rateLimiter.ts +++ b/backend/src/helpers/rateLimiter.ts @@ -1,4 +1,4 @@ -import rateLimit from 'express-rate-limit'; +import rateLimit from "express-rate-limit"; // const MongoStore = require('rate-limit-mongo'); // 200 per minute @@ -14,11 +14,11 @@ export const apiLimiter = rateLimit({ standardHeaders: true, legacyHeaders: false, skip: (request) => { - return request.path === '/healthcheck' || request.path === '/api/status' + return request.path === "/healthcheck" || request.path === "/api/status" }, keyGenerator: (req, res) => { return req.realIP - } + }, }); // 50 requests per 1 hours @@ -35,7 +35,7 @@ const authLimit = rateLimit({ legacyHeaders: false, keyGenerator: (req, res) => { return req.realIP - } + }, }); // 5 requests per 1 hour @@ -52,11 +52,11 @@ export const passwordLimiter = rateLimit({ legacyHeaders: false, keyGenerator: (req, res) => { return req.realIP - } + }, }); export const authLimiter = (req: any, res: any, next: any) => { - if (process.env.NODE_ENV === 'production') { + if (process.env.NODE_ENV === "production") { authLimit(req, res, next); } else { next(); diff --git a/backend/src/helpers/secret.ts b/backend/src/helpers/secret.ts index 31f6c6c9cd..c86807f032 100644 --- a/backend/src/helpers/secret.ts +++ b/backend/src/helpers/secret.ts @@ -1,16 +1,16 @@ import { Types } from "mongoose"; -import { Secret, ISecret } from "../models"; -import { EESecretService, EELogService } from "../ee/services"; +import { ISecret, Secret } from "../models"; +import { EELogService, EESecretService } from "../ee/services"; import { IAction, SecretVersion } from "../ee/models"; import { - SECRET_SHARED, - SECRET_PERSONAL, ACTION_ADD_SECRETS, - ACTION_UPDATE_SECRETS, ACTION_DELETE_SECRETS, ACTION_READ_SECRETS, + ACTION_UPDATE_SECRETS, ALGORITHM_AES_256_GCM, ENCODING_SCHEME_UTF8, + SECRET_PERSONAL, + SECRET_SHARED, } from "../variables"; interface V1PushSecret { diff --git a/backend/src/helpers/secrets.ts b/backend/src/helpers/secrets.ts index 7c8c69e972..51731bb6a8 100644 --- a/backend/src/helpers/secrets.ts +++ b/backend/src/helpers/secrets.ts @@ -1,45 +1,45 @@ import { Types } from "mongoose"; import { CreateSecretParams, - GetSecretsParams, - GetSecretParams, - UpdateSecretParams, DeleteSecretParams, -} from '../interfaces/services/SecretService'; + GetSecretParams, + GetSecretsParams, + UpdateSecretParams, +} from "../interfaces/services/SecretService"; import { - Secret, ISecret, + Secret, SecretBlindIndexData, ServiceTokenData, } from "../models"; import { SecretVersion } from "../ee/models"; import { BadRequestError, - SecretNotFoundError, - SecretBlindIndexDataNotFoundError, InternalServerError, + SecretBlindIndexDataNotFoundError, + SecretNotFoundError, UnauthorizedRequestError, } from "../utils/errors"; import { - SECRET_PERSONAL, - SECRET_SHARED, ACTION_ADD_SECRETS, + ACTION_DELETE_SECRETS, ACTION_READ_SECRETS, ACTION_UPDATE_SECRETS, - ACTION_DELETE_SECRETS, ALGORITHM_AES_256_GCM, - ENCODING_SCHEME_UTF8, ENCODING_SCHEME_BASE64, + ENCODING_SCHEME_UTF8, + SECRET_PERSONAL, + SECRET_SHARED, } from "../variables"; import crypto from "crypto"; import * as argon2 from "argon2"; import { - encryptSymmetric128BitHexKeyUTF8, decryptSymmetric128BitHexKeyUTF8, -} from '../utils/crypto'; -import { TelemetryService } from '../services'; -import { getEncryptionKey, client, getRootEncryptionKey } from "../config"; -import { EESecretService, EELogService } from "../ee/services"; + encryptSymmetric128BitHexKeyUTF8, +} from "../utils/crypto"; +import { TelemetryService } from "../services"; +import { client, getEncryptionKey, getRootEncryptionKey } from "../config"; +import { EELogService, EESecretService } from "../ee/services"; import { getAuthDataPayloadIdObj, getAuthDataPayloadUserObj, @@ -56,7 +56,7 @@ import { getFolderIdFromServiceToken } from "../services/FolderService"; */ export const repackageSecretToRaw = ({ secret, - key + key, }: { secret: ISecret; key: string; @@ -66,24 +66,24 @@ export const repackageSecretToRaw = ({ ciphertext: secret.secretKeyCiphertext, iv: secret.secretKeyIV, tag: secret.secretKeyTag, - key + key, }); const secretValue = decryptSymmetric128BitHexKeyUTF8({ ciphertext: secret.secretValueCiphertext, iv: secret.secretValueIV, tag: secret.secretValueTag, - key + key, }); - let secretComment: string = ''; + let secretComment = ""; if (secret.secretCommentCiphertext && secret.secretCommentIV && secret.secretCommentTag) { secretComment = decryptSymmetric128BitHexKeyUTF8({ ciphertext: secret.secretCommentCiphertext, iv: secret.secretCommentIV, tag: secret.secretCommentTag, - key + key, }); } @@ -96,7 +96,7 @@ export const repackageSecretToRaw = ({ user: secret.user, secretKey, secretValue, - secretComment + secretComment, }); } @@ -944,6 +944,6 @@ export const deleteSecretHelper = async ({ return ({ secrets, - secret + secret, }); }; diff --git a/backend/src/helpers/signup.ts b/backend/src/helpers/signup.ts index d747de20de..da494f4f76 100644 --- a/backend/src/helpers/signup.ts +++ b/backend/src/helpers/signup.ts @@ -1,10 +1,10 @@ -import { IUser } from '../models'; -import { createOrganization } from './organization'; -import { addMembershipsOrg } from './membershipOrg'; -import { OWNER, ACCEPTED } from '../variables'; -import { sendMail } from '../helpers/nodemailer'; -import { TokenService } from '../services'; -import { TOKEN_EMAIL_CONFIRMATION } from '../variables'; +import { IUser } from "../models"; +import { createOrganization } from "./organization"; +import { addMembershipsOrg } from "./membershipOrg"; +import { ACCEPTED, OWNER } from "../variables"; +import { sendMail } from "../helpers/nodemailer"; +import { TokenService } from "../services"; +import { TOKEN_EMAIL_CONFIRMATION } from "../variables"; /** * Send magic link to verify email to [email] @@ -16,17 +16,17 @@ import { TOKEN_EMAIL_CONFIRMATION } from '../variables'; export const sendEmailVerification = async ({ email }: { email: string }) => { const token = await TokenService.createToken({ type: TOKEN_EMAIL_CONFIRMATION, - email + email, }); // send mail await sendMail({ - template: 'emailVerification.handlebars', - subjectLine: 'Infisical confirmation code', + template: "emailVerification.handlebars", + subjectLine: "Infisical confirmation code", recipients: [email], substitutions: { - code: token - } + code: token, + }, }); }; @@ -38,7 +38,7 @@ export const sendEmailVerification = async ({ email }: { email: string }) => { */ export const checkEmailVerification = async ({ email, - code + code, }: { email: string; code: string; @@ -46,7 +46,7 @@ export const checkEmailVerification = async ({ await TokenService.validateToken({ type: TOKEN_EMAIL_CONFIRMATION, email, - token: code + token: code, }); }; @@ -59,7 +59,7 @@ export const checkEmailVerification = async ({ */ export const initializeDefaultOrg = async ({ organizationName, - user + user, }: { organizationName: string; user: IUser; @@ -69,14 +69,14 @@ export const initializeDefaultOrg = async ({ // subscription const organization = await createOrganization({ email: user.email, - name: organizationName + name: organizationName, }); await addMembershipsOrg({ userIds: [user._id.toString()], organizationId: organization._id.toString(), roles: [OWNER], - statuses: [ACCEPTED] + statuses: [ACCEPTED], }); } catch (err) { throw new Error(`Failed to initialize default organization and workspace [err=${err}]`); diff --git a/backend/src/helpers/user.ts b/backend/src/helpers/user.ts index a69b726955..59030ff8ce 100644 --- a/backend/src/helpers/user.ts +++ b/backend/src/helpers/user.ts @@ -1,8 +1,8 @@ import { IUser, User, -} from '../models'; -import { sendMail } from './nodemailer'; +} from "../models"; +import { sendMail } from "./nodemailer"; /** * Initialize a user under email [email] @@ -12,7 +12,7 @@ import { sendMail } from './nodemailer'; */ export const setupAccount = async ({ email }: { email: string }) => { const user = await new User({ - email + email, }).save(); return user; @@ -49,7 +49,7 @@ export const completeAccount = async ({ encryptedPrivateKeyIV, encryptedPrivateKeyTag, salt, - verifier + verifier, }: { userId: string; firstName: string; @@ -66,7 +66,7 @@ export const completeAccount = async ({ verifier: string; }) => { const options = { - new: true + new: true, }; const user = await User.findByIdAndUpdate( userId, @@ -82,7 +82,7 @@ export const completeAccount = async ({ iv: encryptedPrivateKeyIV, tag: encryptedPrivateKeyTag, salt, - verifier + verifier, }, options ); @@ -100,7 +100,7 @@ export const completeAccount = async ({ export const checkUserDevice = async ({ user, ip, - userAgent + userAgent, }: { user: IUser; ip: string; @@ -114,22 +114,22 @@ export const checkUserDevice = async ({ user.devices = user.devices.concat([{ ip: String(ip), - userAgent + userAgent, }]); await user.save(); // send MFA code [code] to [email] await sendMail({ - template: 'newDevice.handlebars', - subjectLine: `Successful login from new device`, + template: "newDevice.handlebars", + subjectLine: "Successful login from new device", recipients: [user.email], substitutions: { email: user.email, timestamp: new Date().toString(), ip, - userAgent - } + userAgent, + }, }); } } \ No newline at end of file diff --git a/backend/src/helpers/workspace.ts b/backend/src/helpers/workspace.ts index 694540f862..d79d6c4537 100644 --- a/backend/src/helpers/workspace.ts +++ b/backend/src/helpers/workspace.ts @@ -1,13 +1,13 @@ import { - Workspace, Bot, - Membership, Key, - Secret -} from '../models'; -import { createBot } from '../helpers/bot'; -import { EELicenseService } from '../ee/services'; -import { SecretService } from '../services'; + Membership, + Secret, + Workspace, +} from "../models"; +import { createBot } from "../helpers/bot"; +import { EELicenseService } from "../ee/services"; +import { SecretService } from "../services"; /** * Create a workspace with name [name] in organization with id [organizationId] @@ -18,7 +18,7 @@ import { SecretService } from '../services'; */ export const createWorkspace = async ({ name, - organizationId + organizationId, }: { name: string; organizationId: string; @@ -27,18 +27,18 @@ export const createWorkspace = async ({ const workspace = await new Workspace({ name, organization: organizationId, - autoCapitalization: true + autoCapitalization: true, }).save(); // initialize bot for workspace await createBot({ - name: 'Infisical Bot', - workspaceId: workspace._id + name: "Infisical Bot", + workspaceId: workspace._id, }); // initialize blind index salt for workspace await SecretService.createSecretBlindIndexData({ - workspaceId: workspace._id + workspaceId: workspace._id, }); await EELicenseService.refreshPlan(organizationId); @@ -55,15 +55,15 @@ export const createWorkspace = async ({ export const deleteWorkspace = async ({ id }: { id: string }) => { await Workspace.deleteOne({ _id: id }); await Bot.deleteOne({ - workspace: id + workspace: id, }); await Membership.deleteMany({ - workspace: id + workspace: id, }); await Secret.deleteMany({ - workspace: id + workspace: id, }); await Key.deleteMany({ - workspace: id + workspace: id, }); }; diff --git a/backend/src/index.ts b/backend/src/index.ts index af3e0b24b3..d0cd67ae52 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -2,7 +2,7 @@ import dotenv from "dotenv"; dotenv.config(); import express from "express"; // eslint-disable-next-line @typescript-eslint/no-var-requires -require('express-async-errors'); +require("express-async-errors"); import helmet from "helmet"; import cors from "cors"; import { DatabaseService } from "./services"; @@ -15,32 +15,32 @@ const swaggerFile = require("../spec.json"); // eslint-disable-next-line @typescript-eslint/no-var-requires import { apiLimiter } from "./helpers/rateLimiter"; import { - workspace as eeWorkspaceRouter, + action as eeActionRouter, + cloudProducts as eeCloudProductsRouter, + organizations as eeOrganizationsRouter, secret as eeSecretRouter, secretSnapshot as eeSecretSnapshotRouter, - action as eeActionRouter, - organizations as eeOrganizationsRouter, - cloudProducts as eeCloudProductsRouter, + workspace as eeWorkspaceRouter, } from "./ee/routes/v1"; import { - signup as v1SignupRouter, auth as v1AuthRouter, bot as v1BotRouter, - organization as v1OrganizationRouter, - workspace as v1WorkspaceRouter, + integrationAuth as v1IntegrationAuthRouter, + integration as v1IntegrationRouter, + inviteOrg as v1InviteOrgRouter, + key as v1KeyRouter, membershipOrg as v1MembershipOrgRouter, membership as v1MembershipRouter, - key as v1KeyRouter, - inviteOrg as v1InviteOrgRouter, - user as v1UserRouter, - userAction as v1UserActionRouter, - secret as v1SecretRouter, - serviceToken as v1ServiceTokenRouter, + organization as v1OrganizationRouter, password as v1PasswordRouter, - stripe as v1StripeRouter, - integration as v1IntegrationRouter, - integrationAuth as v1IntegrationAuthRouter, + secret as v1SecretRouter, secretsFolder as v1SecretsFolder, + serviceToken as v1ServiceTokenRouter, + signup as v1SignupRouter, + stripe as v1StripeRouter, + userAction as v1UserActionRouter, + user as v1UserRouter, + workspace as v1WorkspaceRouter, } from "./routes/v1"; import { signup as v2SignupRouter, @@ -95,7 +95,7 @@ const main = async () => { app.use((req, res, next) => { // default to IP address provided by Cloudflare - const cfIp = req.headers['cf-connecting-ip']; + const cfIp = req.headers["cf-connecting-ip"]; req.realIP = Array.isArray(cfIp) ? cfIp[0] : (cfIp as string) || req.ip; next(); }); diff --git a/backend/src/integrations/apps.ts b/backend/src/integrations/apps.ts index 6e1a8b5012..e93e47fb5a 100644 --- a/backend/src/integrations/apps.ts +++ b/backend/src/integrations/apps.ts @@ -2,32 +2,32 @@ import { Octokit } from "@octokit/rest"; import { IIntegrationAuth } from "../models"; import { standardRequest } from "../config/request"; import { - INTEGRATION_AZURE_KEY_VAULT, INTEGRATION_AWS_PARAMETER_STORE, INTEGRATION_AWS_SECRET_MANAGER, - INTEGRATION_HEROKU, - INTEGRATION_VERCEL, - INTEGRATION_NETLIFY, + INTEGRATION_AZURE_KEY_VAULT, + INTEGRATION_CHECKLY, + INTEGRATION_CHECKLY_API_URL, + INTEGRATION_CIRCLECI, + INTEGRATION_CIRCLECI_API_URL, + INTEGRATION_FLYIO, + INTEGRATION_FLYIO_API_URL, INTEGRATION_GITHUB, INTEGRATION_GITLAB, - INTEGRATION_RENDER, - INTEGRATION_RAILWAY, - INTEGRATION_FLYIO, - INTEGRATION_CIRCLECI, - INTEGRATION_TRAVISCI, - INTEGRATION_SUPABASE, - INTEGRATION_CHECKLY, - INTEGRATION_HEROKU_API_URL, INTEGRATION_GITLAB_API_URL, - INTEGRATION_VERCEL_API_URL, + INTEGRATION_HEROKU, + INTEGRATION_HEROKU_API_URL, + INTEGRATION_NETLIFY, INTEGRATION_NETLIFY_API_URL, - INTEGRATION_RENDER_API_URL, + INTEGRATION_RAILWAY, INTEGRATION_RAILWAY_API_URL, - INTEGRATION_FLYIO_API_URL, - INTEGRATION_CIRCLECI_API_URL, - INTEGRATION_TRAVISCI_API_URL, + INTEGRATION_RENDER, + INTEGRATION_RENDER_API_URL, + INTEGRATION_SUPABASE, INTEGRATION_SUPABASE_API_URL, - INTEGRATION_CHECKLY_API_URL + INTEGRATION_TRAVISCI, + INTEGRATION_TRAVISCI_API_URL, + INTEGRATION_VERCEL, + INTEGRATION_VERCEL_API_URL, } from "../variables"; interface App { @@ -214,7 +214,7 @@ const getAppsNetlify = async ({ accessToken }: { accessToken: string }) => { const params = new URLSearchParams({ page: String(page), per_page: String(perPage), - filter: 'all' + filter: "all", }); const { data } = await standardRequest.get( diff --git a/backend/src/integrations/exchange.ts b/backend/src/integrations/exchange.ts index a4d5f5b06c..12948d4030 100644 --- a/backend/src/integrations/exchange.ts +++ b/backend/src/integrations/exchange.ts @@ -1,31 +1,31 @@ import { standardRequest } from "../config/request"; import { INTEGRATION_AZURE_KEY_VAULT, - INTEGRATION_HEROKU, - INTEGRATION_VERCEL, - INTEGRATION_NETLIFY, - INTEGRATION_GITHUB, - INTEGRATION_GITLAB, INTEGRATION_AZURE_TOKEN_URL, - INTEGRATION_HEROKU_TOKEN_URL, - INTEGRATION_VERCEL_TOKEN_URL, - INTEGRATION_NETLIFY_TOKEN_URL, + INTEGRATION_GITHUB, INTEGRATION_GITHUB_TOKEN_URL, + INTEGRATION_GITLAB, INTEGRATION_GITLAB_TOKEN_URL, + INTEGRATION_HEROKU, + INTEGRATION_HEROKU_TOKEN_URL, + INTEGRATION_NETLIFY, + INTEGRATION_NETLIFY_TOKEN_URL, + INTEGRATION_VERCEL, + INTEGRATION_VERCEL_TOKEN_URL, } from "../variables"; import { - getSiteURL, getClientIdAzure, - getClientSecretAzure, - getClientSecretHeroku, - getClientIdVercel, - getClientSecretVercel, - getClientIdNetlify, - getClientSecretNetlify, getClientIdGitHub, - getClientSecretGitHub, getClientIdGitLab, + getClientIdNetlify, + getClientIdVercel, + getClientSecretAzure, + getClientSecretGitHub, getClientSecretGitLab, + getClientSecretHeroku, + getClientSecretNetlify, + getClientSecretVercel, + getSiteURL, } from "../config"; interface ExchangeCodeAzureResponse { diff --git a/backend/src/integrations/index.ts b/backend/src/integrations/index.ts index 8439ff3ba2..14e2da7f98 100644 --- a/backend/src/integrations/index.ts +++ b/backend/src/integrations/index.ts @@ -1,9 +1,9 @@ -import { exchangeCode } from './exchange'; -import { exchangeRefresh } from './refresh'; -import { getApps } from './apps'; -import { getTeams } from './teams'; -import { syncSecrets } from './sync'; -import { revokeAccess } from './revoke'; +import { exchangeCode } from "./exchange"; +import { exchangeRefresh } from "./refresh"; +import { getApps } from "./apps"; +import { getTeams } from "./teams"; +import { syncSecrets } from "./sync"; +import { revokeAccess } from "./revoke"; export { exchangeCode, @@ -11,5 +11,5 @@ export { getApps, getTeams, syncSecrets, - revokeAccess + revokeAccess, } \ No newline at end of file diff --git a/backend/src/integrations/refresh.ts b/backend/src/integrations/refresh.ts index 0c401bf15e..d530ab2f58 100644 --- a/backend/src/integrations/refresh.ts +++ b/backend/src/integrations/refresh.ts @@ -2,22 +2,22 @@ import { standardRequest } from "../config/request"; import { IIntegrationAuth } from "../models"; import { INTEGRATION_AZURE_KEY_VAULT, - INTEGRATION_HEROKU, INTEGRATION_GITLAB, + INTEGRATION_HEROKU, } from "../variables"; import { INTEGRATION_AZURE_TOKEN_URL, - INTEGRATION_HEROKU_TOKEN_URL, INTEGRATION_GITLAB_TOKEN_URL, + INTEGRATION_HEROKU_TOKEN_URL, } from "../variables"; import { IntegrationService } from "../services"; import { - getSiteURL, getClientIdAzure, - getClientSecretAzure, - getClientSecretHeroku, getClientIdGitLab, + getClientSecretAzure, getClientSecretGitLab, + getClientSecretHeroku, + getSiteURL, } from "../config"; interface RefreshTokenAzureResponse { diff --git a/backend/src/integrations/revoke.ts b/backend/src/integrations/revoke.ts index 46c93017d8..d4747a52a9 100644 --- a/backend/src/integrations/revoke.ts +++ b/backend/src/integrations/revoke.ts @@ -1,21 +1,19 @@ import { IIntegrationAuth, - IntegrationAuth, - Integration, - Bot, - BotKey -} from '../models'; + Integration, + IntegrationAuth, +} from "../models"; import { - INTEGRATION_HEROKU, - INTEGRATION_VERCEL, - INTEGRATION_NETLIFY, INTEGRATION_GITHUB, INTEGRATION_GITLAB, -} from '../variables'; + INTEGRATION_HEROKU, + INTEGRATION_NETLIFY, + INTEGRATION_VERCEL, +} from "../variables"; const revokeAccess = async ({ integrationAuth, - accessToken + accessToken, }: { integrationAuth: IIntegrationAuth; accessToken: string; @@ -36,12 +34,12 @@ const revokeAccess = async ({ } deletedIntegrationAuth = await IntegrationAuth.findOneAndDelete({ - _id: integrationAuth._id + _id: integrationAuth._id, }); if (deletedIntegrationAuth) { await Integration.deleteMany({ - integrationAuth: deletedIntegrationAuth._id + integrationAuth: deletedIntegrationAuth._id, }); } diff --git a/backend/src/integrations/sync.ts b/backend/src/integrations/sync.ts index 76d0099449..907ea9e16c 100644 --- a/backend/src/integrations/sync.ts +++ b/backend/src/integrations/sync.ts @@ -1,45 +1,45 @@ -import _ from 'lodash'; -import AWS from 'aws-sdk'; +import _ from "lodash"; +import AWS from "aws-sdk"; import { - SecretsManagerClient, - UpdateSecretCommand, - CreateSecretCommand, + CreateSecretCommand, GetSecretValueCommand, - ResourceNotFoundException -} from '@aws-sdk/client-secrets-manager'; + ResourceNotFoundException, + SecretsManagerClient, + UpdateSecretCommand, +} from "@aws-sdk/client-secrets-manager"; import { Octokit } from "@octokit/rest"; import sodium from "libsodium-wrappers"; import { IIntegration, IIntegrationAuth } from "../models"; import { - INTEGRATION_AZURE_KEY_VAULT, INTEGRATION_AWS_PARAMETER_STORE, INTEGRATION_AWS_SECRET_MANAGER, - INTEGRATION_HEROKU, - INTEGRATION_VERCEL, - INTEGRATION_NETLIFY, - INTEGRATION_GITHUB, - INTEGRATION_GITLAB, - INTEGRATION_RENDER, - INTEGRATION_RAILWAY, - INTEGRATION_FLYIO, - INTEGRATION_CIRCLECI, - INTEGRATION_TRAVISCI, - INTEGRATION_SUPABASE, - INTEGRATION_HEROKU_API_URL, - INTEGRATION_GITLAB_API_URL, - INTEGRATION_VERCEL_API_URL, - INTEGRATION_NETLIFY_API_URL, - INTEGRATION_RENDER_API_URL, - INTEGRATION_RAILWAY_API_URL, - INTEGRATION_FLYIO_API_URL, - INTEGRATION_CIRCLECI_API_URL, - INTEGRATION_TRAVISCI_API_URL, - INTEGRATION_SUPABASE_API_URL, + INTEGRATION_AZURE_KEY_VAULT, INTEGRATION_CHECKLY, INTEGRATION_CHECKLY_API_URL, - INTEGRATION_HASHICORP_VAULT + INTEGRATION_CIRCLECI, + INTEGRATION_CIRCLECI_API_URL, + INTEGRATION_FLYIO, + INTEGRATION_FLYIO_API_URL, + INTEGRATION_GITHUB, + INTEGRATION_GITLAB, + INTEGRATION_GITLAB_API_URL, + INTEGRATION_HASHICORP_VAULT, + INTEGRATION_HEROKU, + INTEGRATION_HEROKU_API_URL, + INTEGRATION_NETLIFY, + INTEGRATION_NETLIFY_API_URL, + INTEGRATION_RAILWAY, + INTEGRATION_RAILWAY_API_URL, + INTEGRATION_RENDER, + INTEGRATION_RENDER_API_URL, + INTEGRATION_SUPABASE, + INTEGRATION_SUPABASE_API_URL, + INTEGRATION_TRAVISCI, + INTEGRATION_TRAVISCI_API_URL, + INTEGRATION_VERCEL, + INTEGRATION_VERCEL_API_URL, } from "../variables"; -import { standardRequest} from '../config/request'; +import { standardRequest} from "../config/request"; /** * Sync/push [secrets] to [app] in integration named [integration] @@ -68,7 +68,7 @@ const syncSecrets = async ({ await syncSecretsAzureKeyVault({ integration, secrets, - accessToken + accessToken, }); break; case INTEGRATION_AWS_PARAMETER_STORE: @@ -76,7 +76,7 @@ const syncSecrets = async ({ integration, secrets, accessId, - accessToken + accessToken, }); break; case INTEGRATION_AWS_SECRET_MANAGER: @@ -84,7 +84,7 @@ const syncSecrets = async ({ integration, secrets, accessId, - accessToken + accessToken, }); break; case INTEGRATION_HEROKU: @@ -135,7 +135,7 @@ const syncSecrets = async ({ await syncSecretsRailway({ integration, secrets, - accessToken + accessToken, }); break; case INTEGRATION_FLYIO: @@ -163,7 +163,7 @@ const syncSecrets = async ({ await syncSecretsSupabase({ integration, secrets, - accessToken + accessToken, }); break; case INTEGRATION_FLYIO: @@ -191,7 +191,7 @@ const syncSecrets = async ({ await syncSecretsSupabase({ integration, secrets, - accessToken + accessToken, }); break; case INTEGRATION_CHECKLY: @@ -207,7 +207,7 @@ const syncSecrets = async ({ integrationAuth, secrets, accessId, - accessToken + accessToken, }); break; } @@ -223,7 +223,7 @@ const syncSecrets = async ({ const syncSecretsAzureKeyVault = async ({ integration, secrets, - accessToken + accessToken, }: { integration: IIntegration; secrets: any; @@ -254,8 +254,8 @@ const syncSecretsAzureKeyVault = async ({ while (url) { const res = await standardRequest.get(url, { headers: { - Authorization: `Bearer ${accessToken}` - } + Authorization: `Bearer ${accessToken}`, + }, }); result = result.concat(res.data.value); @@ -271,13 +271,13 @@ const syncSecretsAzureKeyVault = async ({ let lastSlashIndex: number; const res = (await Promise.all(getAzureKeyVaultSecrets.map(async (getAzureKeyVaultSecret) => { if (!lastSlashIndex) { - lastSlashIndex = getAzureKeyVaultSecret.id.lastIndexOf('/'); + lastSlashIndex = getAzureKeyVaultSecret.id.lastIndexOf("/"); } const azureKeyVaultSecret = await standardRequest.get(`${getAzureKeyVaultSecret.id}?api-version=7.3`, { headers: { - 'Authorization': `Bearer ${accessToken}` - } + "Authorization": `Bearer ${accessToken}`, + }, }); return ({ @@ -287,7 +287,7 @@ const syncSecretsAzureKeyVault = async ({ }))) .reduce((obj: any, secret: any) => ({ ...obj, - [secret.key]: secret + [secret.key]: secret, }), {}); const setSecrets: { @@ -296,19 +296,19 @@ const syncSecretsAzureKeyVault = async ({ }[] = []; Object.keys(secrets).forEach((key) => { - const hyphenatedKey = key.replace(/_/g, '-'); + const hyphenatedKey = key.replace(/_/g, "-"); if (!(hyphenatedKey in res)) { // case: secret has been created setSecrets.push({ key: hyphenatedKey, - value: secrets[key] + value: secrets[key], }); } else { if (secrets[key] !== res[hyphenatedKey].value) { // case: secret has been updated setSecrets.push({ key: hyphenatedKey, - value: secrets[key] + value: secrets[key], }); } } @@ -317,7 +317,7 @@ const syncSecretsAzureKeyVault = async ({ const deleteSecrets: AzureKeyVaultSecret[] = []; Object.keys(res).forEach((key) => { - const underscoredKey = key.replace(/-/g, '_'); + const underscoredKey = key.replace(/-/g, "_"); if (!(underscoredKey in secrets)) { deleteSecrets.push(res[key]); } @@ -327,7 +327,7 @@ const syncSecretsAzureKeyVault = async ({ key, value, integration, - accessToken + accessToken, }: { key: string; value: string; @@ -343,12 +343,12 @@ const syncSecretsAzureKeyVault = async ({ await standardRequest.put( `${integration.app}/secrets/${key}?api-version=7.3`, { - value + value, }, { headers: { - Authorization: `Bearer ${accessToken}` - } + Authorization: `Bearer ${accessToken}`, + }, } ); @@ -356,13 +356,13 @@ const syncSecretsAzureKeyVault = async ({ } catch (err) { const error: any = err; - if (error?.response?.data?.error?.innererror?.code === 'ObjectIsDeletedButRecoverable') { + if (error?.response?.data?.error?.innererror?.code === "ObjectIsDeletedButRecoverable") { await standardRequest.post( `${integration.app}/deletedsecrets/${key}/recover?api-version=7.3`, {}, { headers: { - Authorization: `Bearer ${accessToken}` - } + Authorization: `Bearer ${accessToken}`, + }, } ); await new Promise(resolve => setTimeout(resolve, 10000)); @@ -381,7 +381,7 @@ const syncSecretsAzureKeyVault = async ({ key, value, integration, - accessToken + accessToken, }); } @@ -389,8 +389,8 @@ const syncSecretsAzureKeyVault = async ({ const { key } = deleteSecret; await standardRequest.delete(`${integration.app}/secrets/${key}?api-version=7.3`, { headers: { - 'Authorization': `Bearer ${accessToken}` - } + "Authorization": `Bearer ${accessToken}`, + }, }); } }; @@ -407,7 +407,7 @@ const syncSecretsAWSParameterStore = async ({ integration, secrets, accessId, - accessToken + accessToken, }: { integration: IIntegration; secrets: any; @@ -419,18 +419,18 @@ const syncSecretsAWSParameterStore = async ({ AWS.config.update({ region: integration.region, accessKeyId: accessId, - secretAccessKey: accessToken + secretAccessKey: accessToken, }); const ssm = new AWS.SSM({ - apiVersion: '2014-11-06', - region: integration.region + apiVersion: "2014-11-06", + region: integration.region, }); const params = { Path: integration.path, Recursive: true, - WithDecryption: true + WithDecryption: true, }; const parameterList = (await ssm.getParametersByPath(params).promise()).Parameters @@ -442,7 +442,7 @@ const syncSecretsAWSParameterStore = async ({ if (parameterList) { awsParameterStoreSecretsObj = parameterList.reduce((obj: any, secret: any) => ({ ...obj, - [secret.Name.split("/").pop()]: secret + [secret.Name.split("/").pop()]: secret, }), {}); } @@ -453,9 +453,9 @@ const syncSecretsAWSParameterStore = async ({ // -> create secret await ssm.putParameter({ Name: `${integration.path}${key}`, - Type: 'SecureString', + Type: "SecureString", Value: secrets[key], - Overwrite: true + Overwrite: true, }).promise(); } else { // case: secret exists in AWS parameter store @@ -465,9 +465,9 @@ const syncSecretsAWSParameterStore = async ({ // -> update secret await ssm.putParameter({ Name: `${integration.path}${key}`, - Type: 'SecureString', + Type: "SecureString", Value: secrets[key], - Overwrite: true + Overwrite: true, }).promise(); } } @@ -479,7 +479,7 @@ const syncSecretsAWSParameterStore = async ({ // case: // -> delete secret await ssm.deleteParameter({ - Name: awsParameterStoreSecretsObj[key].Name + Name: awsParameterStoreSecretsObj[key].Name, }).promise(); } }); @@ -487,7 +487,7 @@ const syncSecretsAWSParameterStore = async ({ AWS.config.update({ region: undefined, accessKeyId: undefined, - secretAccessKey: undefined + secretAccessKey: undefined, }); } @@ -503,7 +503,7 @@ const syncSecretsAWSSecretManager = async ({ integration, secrets, accessId, - accessToken + accessToken, }: { integration: IIntegration; secrets: any; @@ -517,20 +517,20 @@ const syncSecretsAWSSecretManager = async ({ AWS.config.update({ region: integration.region, accessKeyId: accessId, - secretAccessKey: accessToken + secretAccessKey: accessToken, }); secretsManager = new SecretsManagerClient({ region: integration.region, credentials: { accessKeyId: accessId, - secretAccessKey: accessToken - } + secretAccessKey: accessToken, + }, }); const awsSecretManagerSecret = await secretsManager.send( new GetSecretValueCommand({ - SecretId: integration.app + SecretId: integration.app, }) ); @@ -543,26 +543,26 @@ const syncSecretsAWSSecretManager = async ({ if (!_.isEqual(awsSecretManagerSecretObj, secrets)) { await secretsManager.send(new UpdateSecretCommand({ SecretId: integration.app, - SecretString: JSON.stringify(secrets) + SecretString: JSON.stringify(secrets), })); } AWS.config.update({ region: undefined, accessKeyId: undefined, - secretAccessKey: undefined + secretAccessKey: undefined, }); } catch (err) { if (err instanceof ResourceNotFoundException && secretsManager) { await secretsManager.send(new CreateSecretCommand({ Name: integration.app, - SecretString: JSON.stringify(secrets) + SecretString: JSON.stringify(secrets), })); } AWS.config.update({ region: undefined, accessKeyId: undefined, - secretAccessKey: undefined + secretAccessKey: undefined, }); } } @@ -590,7 +590,7 @@ const syncSecretsHeroku = async ({ headers: { Accept: "application/vnd.heroku+json; version=3", Authorization: `Bearer ${accessToken}`, - 'Accept-Encoding': 'application/json' + "Accept-Encoding": "application/json", }, } ) @@ -609,7 +609,7 @@ const syncSecretsHeroku = async ({ headers: { Accept: "application/vnd.heroku+json; version=3", Authorization: `Bearer ${accessToken}`, - 'Accept-Encoding': 'application/json' + "Accept-Encoding": "application/json", }, } ); @@ -657,8 +657,8 @@ const syncSecretsVercel = async ({ params, headers: { Authorization: `Bearer ${accessToken}`, - 'Accept-Encoding': 'application/json' - } + "Accept-Encoding": "application/json", + }, } )) .data @@ -669,7 +669,7 @@ const syncSecretsVercel = async ({ return false; } - if (integration.targetEnvironment === 'preview' && integration.path && integration.path !== secret.gitBranch) { + if (integration.targetEnvironment === "preview" && integration.path && integration.path !== secret.gitBranch) { // case: secret on preview environment does not have same target git branch return false; } @@ -682,7 +682,7 @@ const syncSecretsVercel = async ({ const res: { [key: string]: VercelSecret } = {}; for await (const vercelSecret of vercelSecrets) { - if (vercelSecret.type === 'encrypted') { + if (vercelSecret.type === "encrypted") { // case: secret is encrypted -> need to decrypt const decryptedSecret = (await standardRequest.get( `${INTEGRATION_VERCEL_API_URL}/v9/projects/${integration.app}/env/${vercelSecret.id}`, @@ -690,8 +690,8 @@ const syncSecretsVercel = async ({ params, headers: { Authorization: `Bearer ${accessToken}`, - 'Accept-Encoding': 'application/json' - } + "Accept-Encoding": "application/json", + }, } )).data; @@ -715,8 +715,8 @@ const syncSecretsVercel = async ({ type: "encrypted", target: [integration.targetEnvironment], ...(integration.path ? { - gitBranch: integration.path - } : {}) + gitBranch: integration.path, + } : {}), }); } }); @@ -735,8 +735,8 @@ const syncSecretsVercel = async ({ ? [...res[key].target] : [...res[key].target, integration.targetEnvironment], ...(integration.path ? { - gitBranch: integration.path - } : {}) + gitBranch: integration.path, + } : {}), }); } } else { @@ -748,8 +748,8 @@ const syncSecretsVercel = async ({ type: "encrypted", // value doesn't matter target: [integration.targetEnvironment], ...(integration.path ? { - gitBranch: integration.path - } : {}) + gitBranch: integration.path, + } : {}), }); } }); @@ -763,14 +763,14 @@ const syncSecretsVercel = async ({ params, headers: { Authorization: `Bearer ${accessToken}`, - 'Accept-Encoding': 'application/json' + "Accept-Encoding": "application/json", }, } ); } for await (const secret of updateSecrets) { - if (secret.type !== 'sensitive') { + if (secret.type !== "sensitive") { const { id, ...updatedSecret } = secret; await standardRequest.patch( `${INTEGRATION_VERCEL_API_URL}/v9/projects/${integration.app}/env/${secret.id}`, @@ -779,7 +779,7 @@ const syncSecretsVercel = async ({ params, headers: { Authorization: `Bearer ${accessToken}`, - 'Accept-Encoding': 'application/json' + "Accept-Encoding": "application/json", }, } ); @@ -793,7 +793,7 @@ const syncSecretsVercel = async ({ params, headers: { Authorization: `Bearer ${accessToken}`, - 'Accept-Encoding': 'application/json' + "Accept-Encoding": "application/json", }, } ); @@ -846,7 +846,7 @@ const syncSecretsNetlify = async ({ params: getParams, headers: { Authorization: `Bearer ${accessToken}`, - 'Accept-Encoding': 'application/json' + "Accept-Encoding": "application/json", }, } ) @@ -961,7 +961,7 @@ const syncSecretsNetlify = async ({ params: syncParams, headers: { Authorization: `Bearer ${accessToken}`, - 'Accept-Encoding': 'application/json' + "Accept-Encoding": "application/json", }, } ); @@ -979,7 +979,7 @@ const syncSecretsNetlify = async ({ params: syncParams, headers: { Authorization: `Bearer ${accessToken}`, - 'Accept-Encoding': 'application/json' + "Accept-Encoding": "application/json", }, } ); @@ -994,7 +994,7 @@ const syncSecretsNetlify = async ({ params: syncParams, headers: { Authorization: `Bearer ${accessToken}`, - 'Accept-Encoding': 'application/json' + "Accept-Encoding": "application/json", }, } ); @@ -1009,7 +1009,7 @@ const syncSecretsNetlify = async ({ params: syncParams, headers: { Authorization: `Bearer ${accessToken}`, - 'Accept-Encoding': 'application/json' + "Accept-Encoding": "application/json", }, } ); @@ -1061,7 +1061,7 @@ const syncSecretsGitHub = async ({ "GET /repos/{owner}/{repo}/actions/secrets/public-key", { owner: integration.owner, - repo: integration.app + repo: integration.app, } ) ).data; @@ -1151,7 +1151,7 @@ const syncSecretsRender = async ({ { headers: { Authorization: `Bearer ${accessToken}`, - 'Accept-Encoding': 'application/json' + "Accept-Encoding": "application/json", }, } ); @@ -1167,7 +1167,7 @@ const syncSecretsRender = async ({ const syncSecretsRailway = async ({ integration, secrets, - accessToken + accessToken, }: { integration: IIntegration; secrets: any; @@ -1184,7 +1184,7 @@ const syncSecretsRailway = async ({ environmentId: integration.targetEnvironmentId, ...(integration.targetServiceId ? { serviceId: integration.targetServiceId } : {}), replace: true, - variables: secrets + variables: secrets, }; await standardRequest.post(INTEGRATION_RAILWAY_API_URL, { @@ -1194,9 +1194,9 @@ const syncSecretsRailway = async ({ }, }, { headers: { - 'Authorization': `Bearer ${accessToken}`, - 'Content-Type': 'application/json', - 'Accept-Encoding': 'application/json' + "Authorization": `Bearer ${accessToken}`, + "Content-Type": "application/json", + "Accept-Encoding": "application/json", }, }); } @@ -1252,7 +1252,7 @@ const syncSecretsFlyio = async ({ }, { headers: { Authorization: "Bearer " + accessToken, - 'Accept-Encoding': 'application/json', + "Accept-Encoding": "application/json", }, }); @@ -1281,8 +1281,8 @@ const syncSecretsFlyio = async ({ }, { headers: { Authorization: "Bearer " + accessToken, - 'Content-Type': 'application/json', - 'Accept-Encoding': 'application/json', + "Content-Type": "application/json", + "Accept-Encoding": "application/json", }, })).data.data.app.secrets; @@ -1321,7 +1321,7 @@ const syncSecretsFlyio = async ({ headers: { Authorization: "Bearer " + accessToken, "Content-Type": "application/json", - 'Accept-Encoding': 'application/json', + "Accept-Encoding": "application/json", }, }); }; @@ -1432,7 +1432,7 @@ const syncSecretsTravisCI = async ({ ?.env_vars .reduce((obj: any, secret: any) => ({ ...obj, - [secret.name]: secret + [secret.name]: secret, }), {}); // add secrets @@ -1445,8 +1445,8 @@ const syncSecretsTravisCI = async ({ { env_var: { name: key, - value: secrets[key] - } + value: secrets[key], + }, }, { headers: { @@ -1465,7 +1465,7 @@ const syncSecretsTravisCI = async ({ env_var: { name: key, value: secrets[key], - } + }, }, { headers: { @@ -1533,10 +1533,10 @@ const syncSecretsGitLab = async ({ allEnvVariables = [...allEnvVariables, ...response.data]; const linkHeader = response.headers.link; - const nextLink = linkHeader?.split(',').find((part: string) => part.includes('rel="next"')); + const nextLink = linkHeader?.split(",").find((part: string) => part.includes('rel="next"')); if (nextLink) { - url = nextLink.trim().split(';')[0].slice(1, -1); + url = nextLink.trim().split(";")[0].slice(1, -1); } else { url = null; } @@ -1561,7 +1561,7 @@ const syncSecretsGitLab = async ({ protected: false, masked: false, raw: false, - environment_scope: integration.targetEnvironment + environment_scope: integration.targetEnvironment, }, { headers: { @@ -1578,7 +1578,7 @@ const syncSecretsGitLab = async ({ `${INTEGRATION_GITLAB_API_URL}/v4/projects/${integration?.appId}/variables/${existingSecret.key}?filter[environment_scope]=${integration.targetEnvironment}`, { ...existingSecret, - value: secrets[existingSecret.key] + value: secrets[existingSecret.key], }, { headers: { @@ -1618,7 +1618,7 @@ const syncSecretsGitLab = async ({ const syncSecretsSupabase = async ({ integration, secrets, - accessToken + accessToken, }: { integration: IIntegration; secrets: any; @@ -1629,8 +1629,8 @@ const syncSecretsSupabase = async ({ { headers: { Authorization: `Bearer ${accessToken}`, - 'Accept-Encoding': 'application/json' - } + "Accept-Encoding": "application/json", + }, } ); @@ -1639,7 +1639,7 @@ const syncSecretsSupabase = async ({ (key) => { return { name: key, - value: secrets[key] + value: secrets[key], }; } ); @@ -1650,8 +1650,8 @@ const syncSecretsSupabase = async ({ { headers: { Authorization: `Bearer ${accessToken}`, - 'Accept-Encoding': 'application/json' - } + "Accept-Encoding": "application/json", + }, } ); @@ -1667,10 +1667,10 @@ const syncSecretsSupabase = async ({ { headers: { Authorization: `Bearer ${accessToken}`, - 'Content-Type': 'application/json', - 'Accept-Encoding': 'application/json' + "Content-Type": "application/json", + "Accept-Encoding": "application/json", }, - data: secretsToDelete + data: secretsToDelete, } ); }; @@ -1700,7 +1700,7 @@ const syncSecretsCheckly = async ({ headers: { "Authorization": `Bearer ${accessToken}`, "Accept-Encoding": "application/json", - "X-Checkly-Account": integration.appId + "X-Checkly-Account": integration.appId, }, } ) @@ -1708,7 +1708,7 @@ const syncSecretsCheckly = async ({ .data .reduce((obj: any, secret: any) => ({ ...obj, - [secret.key]: secret.value + [secret.key]: secret.value, }), {}); // add secrets @@ -1721,14 +1721,14 @@ const syncSecretsCheckly = async ({ `${INTEGRATION_CHECKLY_API_URL}/v1/variables`, { key, - value: secrets[key] + value: secrets[key], }, { headers: { "Authorization": `Bearer ${accessToken}`, "Accept": "application/json", "Content-Type": "application/json", - "X-Checkly-Account": integration.appId + "X-Checkly-Account": integration.appId, }, } ); @@ -1740,14 +1740,14 @@ const syncSecretsCheckly = async ({ await standardRequest.put( `${INTEGRATION_CHECKLY_API_URL}/v1/variables/${key}`, { - value: secrets[key] + value: secrets[key], }, { headers: { "Authorization": `Bearer ${accessToken}`, "Content-Type": "application/json", "Accept": "application/json", - "X-Checkly-Account": integration.appId + "X-Checkly-Account": integration.appId, }, } ); @@ -1764,7 +1764,7 @@ const syncSecretsCheckly = async ({ headers: { "Authorization": `Bearer ${accessToken}`, "Accept": "application/json", - "X-Checkly-Account": integration.appId + "X-Checkly-Account": integration.appId, }, } ); @@ -1805,12 +1805,12 @@ const syncSecretsHashiCorpVault = async ({ `${integrationAuth.url}/v1/auth/approle/login`, { "role_id": accessId, - "secret_id": accessToken + "secret_id": accessToken, }, { headers: { - "X-Vault-Namespace": integrationAuth.namespace - } + "X-Vault-Namespace": integrationAuth.namespace, + }, } ); @@ -1819,7 +1819,7 @@ const syncSecretsHashiCorpVault = async ({ await standardRequest.post( `${integrationAuth.url}/v1/${integration.app}/data/${integration.path}`, { - data: secrets + data: secrets, }, { headers: { @@ -1827,7 +1827,7 @@ const syncSecretsHashiCorpVault = async ({ "Accept": "application/json", "Content-Type": "application/json", "X-Vault-Token": clientToken, - "X-Vault-Namespace": integrationAuth.namespace + "X-Vault-Namespace": integrationAuth.namespace, }, } ); diff --git a/backend/src/integrations/teams.ts b/backend/src/integrations/teams.ts index 74fc0ca866..3b0564322b 100644 --- a/backend/src/integrations/teams.ts +++ b/backend/src/integrations/teams.ts @@ -1,11 +1,11 @@ import { - IIntegrationAuth -} from '../models'; + IIntegrationAuth, +} from "../models"; import { INTEGRATION_GITLAB, - INTEGRATION_GITLAB_API_URL -} from '../variables'; -import { standardRequest } from '../config/request'; + INTEGRATION_GITLAB_API_URL, +} from "../variables"; +import { standardRequest } from "../config/request"; interface Team { name: string; @@ -23,7 +23,7 @@ interface Team { */ const getTeams = async ({ integrationAuth, - accessToken + accessToken, }: { integrationAuth: IIntegrationAuth; accessToken: string; @@ -34,7 +34,7 @@ const getTeams = async ({ switch (integrationAuth.integration) { case INTEGRATION_GITLAB: teams = await getTeamsGitLab({ - accessToken + accessToken, }); break; } @@ -51,7 +51,7 @@ const getTeams = async ({ * @returns {String} teams.teamId - id of team */ const getTeamsGitLab = async ({ - accessToken + accessToken, }: { accessToken: string; }) => { @@ -61,19 +61,19 @@ const getTeamsGitLab = async ({ { headers: { Authorization: `Bearer ${accessToken}`, - "Accept-Encoding": "application/json" - } + "Accept-Encoding": "application/json", + }, } )).data; teams = res.map((t: any) => ({ name: t.name, - teamId: t.id + teamId: t.id, })); return teams; } export { - getTeams + getTeams, } diff --git a/backend/src/interfaces/middleware/index.ts b/backend/src/interfaces/middleware/index.ts index a368a3be15..3fba92348b 100644 --- a/backend/src/interfaces/middleware/index.ts +++ b/backend/src/interfaces/middleware/index.ts @@ -1,9 +1,9 @@ -import { Types } from 'mongoose'; +import { Types } from "mongoose"; import { - IUser, IServiceAccount, - IServiceTokenData -} from '../../models'; + IServiceTokenData, + IUser, +} from "../../models"; export interface AuthData { authMode: string; diff --git a/backend/src/interfaces/serviceAccounts/dto/index.ts b/backend/src/interfaces/serviceAccounts/dto/index.ts index 52d8d83422..f697781448 100644 --- a/backend/src/interfaces/serviceAccounts/dto/index.ts +++ b/backend/src/interfaces/serviceAccounts/dto/index.ts @@ -1,7 +1,7 @@ -import CreateServiceAccountDto from './CreateServiceAccountDto'; -import AddServiceAccountPermissionDto from './AddServiceAccountPermissionDto'; +import CreateServiceAccountDto from "./CreateServiceAccountDto"; +import AddServiceAccountPermissionDto from "./AddServiceAccountPermissionDto"; export { CreateServiceAccountDto, - AddServiceAccountPermissionDto + AddServiceAccountPermissionDto, } \ No newline at end of file diff --git a/backend/src/interfaces/utils/index.ts b/backend/src/interfaces/utils/index.ts index 7d27c91052..b781a39bb1 100644 --- a/backend/src/interfaces/utils/index.ts +++ b/backend/src/interfaces/utils/index.ts @@ -1 +1 @@ -export * from './crypto'; \ No newline at end of file +export * from "./crypto"; \ No newline at end of file diff --git a/backend/src/middleware/index.ts b/backend/src/middleware/index.ts index 039b8612d7..bc2cbc9697 100644 --- a/backend/src/middleware/index.ts +++ b/backend/src/middleware/index.ts @@ -1,20 +1,20 @@ -import requireAuth from './requireAuth'; -import requireMfaAuth from './requireMfaAuth'; -import requireBotAuth from './requireBotAuth'; -import requireSignupAuth from './requireSignupAuth'; -import requireWorkspaceAuth from './requireWorkspaceAuth'; -import requireMembershipAuth from './requireMembershipAuth'; -import requireMembershipOrgAuth from './requireMembershipOrgAuth'; -import requireOrganizationAuth from './requireOrganizationAuth'; -import requireIntegrationAuth from './requireIntegrationAuth'; -import requireIntegrationAuthorizationAuth from './requireIntegrationAuthorizationAuth'; -import requireServiceTokenAuth from './requireServiceTokenAuth'; -import requireServiceTokenDataAuth from './requireServiceTokenDataAuth'; -import requireServiceAccountAuth from './requireServiceAccountAuth'; -import requireServiceAccountWorkspacePermissionAuth from './requireServiceAccountWorkspacePermissionAuth'; -import requireSecretAuth from './requireSecretAuth'; -import requireSecretsAuth from './requireSecretsAuth'; -import validateRequest from './validateRequest'; +import requireAuth from "./requireAuth"; +import requireMfaAuth from "./requireMfaAuth"; +import requireBotAuth from "./requireBotAuth"; +import requireSignupAuth from "./requireSignupAuth"; +import requireWorkspaceAuth from "./requireWorkspaceAuth"; +import requireMembershipAuth from "./requireMembershipAuth"; +import requireMembershipOrgAuth from "./requireMembershipOrgAuth"; +import requireOrganizationAuth from "./requireOrganizationAuth"; +import requireIntegrationAuth from "./requireIntegrationAuth"; +import requireIntegrationAuthorizationAuth from "./requireIntegrationAuthorizationAuth"; +import requireServiceTokenAuth from "./requireServiceTokenAuth"; +import requireServiceTokenDataAuth from "./requireServiceTokenDataAuth"; +import requireServiceAccountAuth from "./requireServiceAccountAuth"; +import requireServiceAccountWorkspacePermissionAuth from "./requireServiceAccountWorkspacePermissionAuth"; +import requireSecretAuth from "./requireSecretAuth"; +import requireSecretsAuth from "./requireSecretsAuth"; +import validateRequest from "./validateRequest"; export { requireAuth, @@ -33,5 +33,5 @@ export { requireServiceAccountWorkspacePermissionAuth, requireSecretAuth, requireSecretsAuth, - validateRequest + validateRequest, }; diff --git a/backend/src/middleware/requestErrorHandler.ts b/backend/src/middleware/requestErrorHandler.ts index 6aa73954b6..dca6a82ba4 100644 --- a/backend/src/middleware/requestErrorHandler.ts +++ b/backend/src/middleware/requestErrorHandler.ts @@ -1,9 +1,9 @@ -import * as Sentry from '@sentry/node'; -import { ErrorRequestHandler } from 'express'; -import { InternalServerError } from '../utils/errors'; -import { getLogger } from '../utils/logger'; -import RequestError, { LogLevel } from '../utils/requestError'; -import { getNodeEnv } from '../config'; +import * as Sentry from "@sentry/node"; +import { ErrorRequestHandler } from "express"; +import { InternalServerError } from "../utils/errors"; +import { getLogger } from "../utils/logger"; +import RequestError, { LogLevel } from "../utils/requestError"; +import { getNodeEnv } from "../config"; export const requestErrorHandler: ErrorRequestHandler = async ( error: RequestError | Error, @@ -24,7 +24,7 @@ export const requestErrorHandler: ErrorRequestHandler = async ( context: { exception: error.message }, stack: error.stack, }); - (await getLogger('backend-main')).log( + (await getLogger("backend-main")).log( (error).levelName.toLowerCase(), (error).message ); diff --git a/backend/src/middleware/requireAuth.ts b/backend/src/middleware/requireAuth.ts index 22de05f68e..667524afdb 100644 --- a/backend/src/middleware/requireAuth.ts +++ b/backend/src/middleware/requireAuth.ts @@ -1,26 +1,26 @@ -import jwt from 'jsonwebtoken'; -import { Request, Response, NextFunction } from 'express'; +import jwt from "jsonwebtoken"; +import { NextFunction, Request, Response } from "express"; import { - validateAuthMode, - getAuthUserPayload, - getAuthSTDPayload, getAuthAPIKeyPayload, - getAuthSAAKPayload -} from '../helpers/auth'; + getAuthSAAKPayload, + getAuthSTDPayload, + getAuthUserPayload, + validateAuthMode, +} from "../helpers/auth"; import { - IUser, IServiceAccount, - IServiceTokenData -} from '../models'; + IServiceTokenData, + IUser, +} from "../models"; import { + AUTH_MODE_API_KEY, AUTH_MODE_JWT, AUTH_MODE_SERVICE_ACCOUNT, AUTH_MODE_SERVICE_TOKEN, - AUTH_MODE_API_KEY -} from '../variables'; -import { getChannelFromUserAgent } from '../utils/posthog'; +} from "../variables"; +import { getChannelFromUserAgent } from "../utils/posthog"; -declare module 'jsonwebtoken' { +declare module "jsonwebtoken" { export interface UserIDJwtPayload extends jwt.JwtPayload { userId: string; } @@ -47,32 +47,32 @@ const requireAuth = ({ // and return token type [authTokenType] and value [authTokenValue] const { authMode, authTokenValue } = validateAuthMode({ headers: req.headers, - acceptedAuthModes + acceptedAuthModes, }); let authPayload: IUser | IServiceAccount | IServiceTokenData; switch (authMode) { case AUTH_MODE_SERVICE_ACCOUNT: authPayload = await getAuthSAAKPayload({ - authTokenValue + authTokenValue, }); req.serviceAccount = authPayload; break; case AUTH_MODE_SERVICE_TOKEN: authPayload = await getAuthSTDPayload({ - authTokenValue + authTokenValue, }); req.serviceTokenData = authPayload; break; case AUTH_MODE_API_KEY: authPayload = await getAuthAPIKeyPayload({ - authTokenValue + authTokenValue, }); req.user = authPayload; break; default: const { user, tokenVersionId } = await getAuthUserPayload({ - authTokenValue + authTokenValue, }); authPayload = user; req.user = user; @@ -89,10 +89,10 @@ const requireAuth = ({ req.authData = { authMode, authPayload, // User, ServiceAccount, ServiceTokenData - authChannel: getChannelFromUserAgent(req.headers['user-agent']), + authChannel: getChannelFromUserAgent(req.headers["user-agent"]), authIP: req.realIP, - authUserAgent: req.headers['user-agent'] ?? 'other', - tokenVersionId: req.tokenVersionId + authUserAgent: req.headers["user-agent"] ?? "other", + tokenVersionId: req.tokenVersionId, } return next(); diff --git a/backend/src/middleware/requireBotAuth.ts b/backend/src/middleware/requireBotAuth.ts index 2de8217daf..b0dc36956c 100644 --- a/backend/src/middleware/requireBotAuth.ts +++ b/backend/src/middleware/requireBotAuth.ts @@ -1,14 +1,14 @@ -import { Request, Response, NextFunction } from 'express'; -import { Types } from 'mongoose'; -import { validateClientForBot } from '../validation'; +import { NextFunction, Request, Response } from "express"; +import { Types } from "mongoose"; +import { validateClientForBot } from "../validation"; -type req = 'params' | 'body' | 'query'; +type req = "params" | "body" | "query"; const requireBotAuth = ({ acceptedRoles, - locationBotId = 'params' + locationBotId = "params", }: { - acceptedRoles: Array<'admin' | 'member'>; + acceptedRoles: Array<"admin" | "member">; locationBotId?: req; }) => { return async (req: Request, res: Response, next: NextFunction) => { @@ -17,7 +17,7 @@ const requireBotAuth = ({ req.bot = await validateClientForBot({ authData: req.authData, botId: new Types.ObjectId(botId), - acceptedRoles + acceptedRoles, }); next(); diff --git a/backend/src/middleware/requireIntegrationAuth.ts b/backend/src/middleware/requireIntegrationAuth.ts index 94d39a6c17..5adc043534 100644 --- a/backend/src/middleware/requireIntegrationAuth.ts +++ b/backend/src/middleware/requireIntegrationAuth.ts @@ -1,6 +1,6 @@ -import { Request, Response, NextFunction } from 'express'; -import { Types } from 'mongoose'; -import { validateClientForIntegration } from '../validation'; +import { NextFunction, Request, Response } from "express"; +import { Types } from "mongoose"; +import { validateClientForIntegration } from "../validation"; /** * Validate if user on request is a member of workspace with proper roles associated @@ -9,9 +9,9 @@ import { validateClientForIntegration } from '../validation'; * @param {String[]} obj.acceptedRoles - accepted workspace roles */ const requireIntegrationAuth = ({ - acceptedRoles + acceptedRoles, }: { - acceptedRoles: Array<'admin' | 'member'>; + acceptedRoles: Array<"admin" | "member">; }) => { return async (req: Request, res: Response, next: NextFunction) => { const { integrationId } = req.params; @@ -19,7 +19,7 @@ const requireIntegrationAuth = ({ const { integration, accessToken } = await validateClientForIntegration({ authData: req.authData, integrationId: new Types.ObjectId(integrationId), - acceptedRoles + acceptedRoles, }); if (integration) { diff --git a/backend/src/middleware/requireIntegrationAuthorizationAuth.ts b/backend/src/middleware/requireIntegrationAuthorizationAuth.ts index 2ddd540934..ccbe7e8a34 100644 --- a/backend/src/middleware/requireIntegrationAuthorizationAuth.ts +++ b/backend/src/middleware/requireIntegrationAuthorizationAuth.ts @@ -1,8 +1,8 @@ -import { Types } from 'mongoose'; -import { Request, Response, NextFunction } from 'express'; -import { validateClientForIntegrationAuth } from '../validation'; +import { Types } from "mongoose"; +import { NextFunction, Request, Response } from "express"; +import { validateClientForIntegrationAuth } from "../validation"; -type req = 'params' | 'body' | 'query'; +type req = "params" | "body" | "query"; /** * Validate if user on request is a member of workspace with proper roles associated @@ -14,9 +14,9 @@ type req = 'params' | 'body' | 'query'; const requireIntegrationAuthorizationAuth = ({ acceptedRoles, attachAccessToken = true, - location = 'params' + location = "params", }: { - acceptedRoles: Array<'admin' | 'member'>; + acceptedRoles: Array<"admin" | "member">; attachAccessToken?: boolean; location?: req; }) => { @@ -27,7 +27,7 @@ const requireIntegrationAuthorizationAuth = ({ authData: req.authData, integrationAuthId: new Types.ObjectId(integrationAuthId), acceptedRoles, - attachAccessToken + attachAccessToken, }); if (integrationAuth) { diff --git a/backend/src/middleware/requireMembershipAuth.ts b/backend/src/middleware/requireMembershipAuth.ts index e03a6ea123..cc781677b4 100644 --- a/backend/src/middleware/requireMembershipAuth.ts +++ b/backend/src/middleware/requireMembershipAuth.ts @@ -1,8 +1,8 @@ -import { Types } from 'mongoose'; -import { Request, Response, NextFunction } from 'express'; -import { validateClientForMembership } from '../validation'; +import { Types } from "mongoose"; +import { NextFunction, Request, Response } from "express"; +import { validateClientForMembership } from "../validation"; -type req = 'params' | 'body' | 'query'; +type req = "params" | "body" | "query"; /** * Validate membership with id [membershipId] and that user with id @@ -13,9 +13,9 @@ type req = 'params' | 'body' | 'query'; */ const requireMembershipAuth = ({ acceptedRoles, - locationMembershipId = 'params' + locationMembershipId = "params", }: { - acceptedRoles: Array<'admin' | 'member'>; + acceptedRoles: Array<"admin" | "member">; locationMembershipId: req }) => { return async ( @@ -28,7 +28,7 @@ const requireMembershipAuth = ({ req.targetMembership = await validateClientForMembership({ authData: req.authData, membershipId: new Types.ObjectId(membershipId), - acceptedRoles + acceptedRoles, }); return next(); diff --git a/backend/src/middleware/requireMembershipOrgAuth.ts b/backend/src/middleware/requireMembershipOrgAuth.ts index dda90cae89..00bcb6de83 100644 --- a/backend/src/middleware/requireMembershipOrgAuth.ts +++ b/backend/src/middleware/requireMembershipOrgAuth.ts @@ -1,8 +1,8 @@ -import { Types } from 'mongoose'; -import { Request, Response, NextFunction } from 'express'; -import { validateClientForMembershipOrg } from '../validation'; +import { Types } from "mongoose"; +import { NextFunction, Request, Response } from "express"; +import { validateClientForMembershipOrg } from "../validation"; -type req = 'params' | 'body' | 'query'; +type req = "params" | "body" | "query"; /** * Validate (organization) membership id [membershipId] and that user with id @@ -14,10 +14,10 @@ type req = 'params' | 'body' | 'query'; const requireMembershipOrgAuth = ({ acceptedRoles, acceptedStatuses, - locationMembershipOrgId = 'params' + locationMembershipOrgId = "params", }: { - acceptedRoles: Array<'owner' | 'admin' | 'member'>; - acceptedStatuses: Array<'invited' | 'accepted'>; + acceptedRoles: Array<"owner" | "admin" | "member">; + acceptedStatuses: Array<"invited" | "accepted">; locationMembershipOrgId?: req; }) => { return async (req: Request, res: Response, next: NextFunction) => { @@ -27,7 +27,7 @@ const requireMembershipOrgAuth = ({ authData: req.authData, membershipOrgId: new Types.ObjectId(membershipId), acceptedRoles, - acceptedStatuses + acceptedStatuses, }); return next(); diff --git a/backend/src/middleware/requireMfaAuth.ts b/backend/src/middleware/requireMfaAuth.ts index ca0b3434ee..7a7f7db4bb 100644 --- a/backend/src/middleware/requireMfaAuth.ts +++ b/backend/src/middleware/requireMfaAuth.ts @@ -1,10 +1,10 @@ -import jwt from 'jsonwebtoken'; -import { Request, Response, NextFunction } from 'express'; -import { User } from '../models'; -import { BadRequestError, UnauthorizedRequestError } from '../utils/errors'; -import { getJwtMfaSecret } from '../config'; +import jwt from "jsonwebtoken"; +import { NextFunction, Request, Response } from "express"; +import { User } from "../models"; +import { BadRequestError, UnauthorizedRequestError } from "../utils/errors"; +import { getJwtMfaSecret } from "../config"; -declare module 'jsonwebtoken' { +declare module "jsonwebtoken" { export interface UserIDJwtPayload extends jwt.JwtPayload { userId: string; } @@ -20,21 +20,21 @@ const requireMfaAuth = async ( next: NextFunction ) => { // JWT (temporary) authentication middleware for complete signup - const [ AUTH_TOKEN_TYPE, AUTH_TOKEN_VALUE ] = <[string, string]>req.headers['authorization']?.split(' ', 2) ?? [null, null] - if(AUTH_TOKEN_TYPE === null) return next(BadRequestError({message: `Missing Authorization Header in the request header.`})) - if(AUTH_TOKEN_TYPE.toLowerCase() !== 'bearer') return next(BadRequestError({message: `The provided authentication type '${AUTH_TOKEN_TYPE}' is not supported.`})) - if(AUTH_TOKEN_VALUE === null) return next(BadRequestError({message: 'Missing Authorization Body in the request header'})) + const [ AUTH_TOKEN_TYPE, AUTH_TOKEN_VALUE ] = <[string, string]>req.headers["authorization"]?.split(" ", 2) ?? [null, null] + if(AUTH_TOKEN_TYPE === null) return next(BadRequestError({message: "Missing Authorization Header in the request header."})) + if(AUTH_TOKEN_TYPE.toLowerCase() !== "bearer") return next(BadRequestError({message: `The provided authentication type '${AUTH_TOKEN_TYPE}' is not supported.`})) + if(AUTH_TOKEN_VALUE === null) return next(BadRequestError({message: "Missing Authorization Body in the request header"})) const decodedToken = ( jwt.verify(AUTH_TOKEN_VALUE, await getJwtMfaSecret()) ); const user = await User.findOne({ - _id: decodedToken.userId - }).select('+publicKey'); + _id: decodedToken.userId, + }).select("+publicKey"); if (!user) - return next(UnauthorizedRequestError({message: 'Unable to authenticate for User account completion. Try logging in again'})) + return next(UnauthorizedRequestError({message: "Unable to authenticate for User account completion. Try logging in again"})) req.user = user; return next(); diff --git a/backend/src/middleware/requireOrganizationAuth.ts b/backend/src/middleware/requireOrganizationAuth.ts index 5f7ef151dd..f28660d0e9 100644 --- a/backend/src/middleware/requireOrganizationAuth.ts +++ b/backend/src/middleware/requireOrganizationAuth.ts @@ -1,8 +1,8 @@ -import { Request, Response, NextFunction } from 'express'; -import { Types } from 'mongoose'; -import { validateClientForOrganization } from '../validation'; +import { NextFunction, Request, Response } from "express"; +import { Types } from "mongoose"; +import { validateClientForOrganization } from "../validation"; -type req = 'params' | 'body' | 'query'; +type req = "params" | "body" | "query"; /** * Validate if user on request is a member with proper roles for organization @@ -14,10 +14,10 @@ type req = 'params' | 'body' | 'query'; const requireOrganizationAuth = ({ acceptedRoles, acceptedStatuses, - locationOrganizationId = 'params' + locationOrganizationId = "params", }: { - acceptedRoles: Array<'owner' | 'admin' | 'member'>; - acceptedStatuses: Array<'invited' | 'accepted'>; + acceptedRoles: Array<"owner" | "admin" | "member">; + acceptedStatuses: Array<"invited" | "accepted">; locationOrganizationId?: req; }) => { return async (req: Request, res: Response, next: NextFunction) => { @@ -27,7 +27,7 @@ const requireOrganizationAuth = ({ authData: req.authData, organizationId: new Types.ObjectId(organizationId), acceptedRoles, - acceptedStatuses + acceptedStatuses, }); if (organization) { diff --git a/backend/src/middleware/requireSecretAuth.ts b/backend/src/middleware/requireSecretAuth.ts index 4fda73a23f..06ad6019e9 100644 --- a/backend/src/middleware/requireSecretAuth.ts +++ b/backend/src/middleware/requireSecretAuth.ts @@ -1,6 +1,6 @@ -import { Request, Response, NextFunction } from 'express'; -import { Types } from 'mongoose'; -import { validateClientForSecret } from '../validation'; +import { NextFunction, Request, Response } from "express"; +import { Types } from "mongoose"; +import { validateClientForSecret } from "../validation"; // note: used for old /v1/secret and /v2/secret routes. // newer /v2/secrets routes use [requireSecretsAuth] middleware with the exception @@ -14,9 +14,9 @@ import { validateClientForSecret } from '../validation'; */ const requireSecretAuth = ({ acceptedRoles, - requiredPermissions + requiredPermissions, }: { - acceptedRoles: Array<'admin' | 'member'>; + acceptedRoles: Array<"admin" | "member">; requiredPermissions: string[]; }) => { return async (req: Request, res: Response, next: NextFunction) => { @@ -26,7 +26,7 @@ const requireSecretAuth = ({ authData: req.authData, secretId: new Types.ObjectId(secretId), acceptedRoles, - requiredPermissions + requiredPermissions, }); req._secret = secret; diff --git a/backend/src/middleware/requireSecretsAuth.ts b/backend/src/middleware/requireSecretsAuth.ts index f25487b970..3dabdb25c6 100644 --- a/backend/src/middleware/requireSecretsAuth.ts +++ b/backend/src/middleware/requireSecretsAuth.ts @@ -1,10 +1,10 @@ -import { Request, Response, NextFunction } from 'express'; -import { Types } from 'mongoose'; -import { validateClientForSecrets } from '../validation'; +import { NextFunction, Request, Response } from "express"; +import { Types } from "mongoose"; +import { validateClientForSecrets } from "../validation"; const requireSecretsAuth = ({ acceptedRoles, - requiredPermissions = [] + requiredPermissions = [], }: { acceptedRoles: string[]; requiredPermissions?: string[]; @@ -13,18 +13,18 @@ const requireSecretsAuth = ({ let secretIds = []; if (Array.isArray(req.body.secrets)) { secretIds = req.body.secrets.map((s: any) => s.id); - } else if (typeof req.body.secrets === 'object') { + } else if (typeof req.body.secrets === "object") { secretIds = [req.body.secrets.id]; } else if (Array.isArray(req.body.secretIds)) { secretIds = req.body.secretIds; - } else if (typeof req.body.secretIds === 'string') { + } else if (typeof req.body.secretIds === "string") { secretIds = [req.body.secretIds]; } req.secrets = await validateClientForSecrets({ authData: req.authData, secretIds: secretIds.map((secretId: string) => new Types.ObjectId(secretId)), - requiredPermissions + requiredPermissions, }); return next(); diff --git a/backend/src/middleware/requireServiceAccountAuth.ts b/backend/src/middleware/requireServiceAccountAuth.ts index da690c7bb0..f7e423b79a 100644 --- a/backend/src/middleware/requireServiceAccountAuth.ts +++ b/backend/src/middleware/requireServiceAccountAuth.ts @@ -1,14 +1,14 @@ -import { Request, Response, NextFunction } from 'express'; -import { Types } from 'mongoose'; -import { validateClientForServiceAccount } from '../validation'; +import { NextFunction, Request, Response } from "express"; +import { Types } from "mongoose"; +import { validateClientForServiceAccount } from "../validation"; -type req = 'params' | 'body' | 'query'; +type req = "params" | "body" | "query"; const requireServiceAccountAuth = ({ acceptedRoles, acceptedStatuses, - locationServiceAccountId = 'params', - requiredPermissions = [] + locationServiceAccountId = "params", + requiredPermissions = [], }: { acceptedRoles: string[]; acceptedStatuses: string[]; @@ -21,7 +21,7 @@ const requireServiceAccountAuth = ({ req.serviceAccount = await validateClientForServiceAccount({ authData: req.authData, serviceAccountId: new Types.ObjectId(serviceAccountId), - requiredPermissions + requiredPermissions, }); next(); diff --git a/backend/src/middleware/requireServiceAccountWorkspacePermissionAuth.ts b/backend/src/middleware/requireServiceAccountWorkspacePermissionAuth.ts index 0ceb4f598d..535cd20683 100644 --- a/backend/src/middleware/requireServiceAccountWorkspacePermissionAuth.ts +++ b/backend/src/middleware/requireServiceAccountWorkspacePermissionAuth.ts @@ -1,21 +1,21 @@ -import { Request, Response, NextFunction } from 'express'; -import { ServiceAccount, ServiceAccountWorkspacePermission } from '../models'; +import { NextFunction, Request, Response } from "express"; +import { ServiceAccount, ServiceAccountWorkspacePermission } from "../models"; import { - ServiceAccountNotFoundError -} from '../utils/errors'; + ServiceAccountNotFoundError, +} from "../utils/errors"; import { - validateMembershipOrg -} from '../helpers/membershipOrg'; + validateMembershipOrg, +} from "../helpers/membershipOrg"; -type req = 'params' | 'body' | 'query'; +type req = "params" | "body" | "query"; const requireServiceAccountWorkspacePermissionAuth = ({ acceptedRoles, acceptedStatuses, - location = 'params' + location = "params", }: { - acceptedRoles: Array<'owner' | 'admin' | 'member'>; - acceptedStatuses: Array<'invited' | 'accepted'>; + acceptedRoles: Array<"owner" | "admin" | "member">; + acceptedStatuses: Array<"invited" | "accepted">; location?: req; }) => { return async (req: Request, res: Response, next: NextFunction) => { @@ -23,13 +23,13 @@ const requireServiceAccountWorkspacePermissionAuth = ({ const serviceAccountWorkspacePermission = await ServiceAccountWorkspacePermission.findById(serviceAccountWorkspacePermissionId); if (!serviceAccountWorkspacePermission) { - return next(ServiceAccountNotFoundError({ message: 'Failed to locate Service Account workspace permission' })); + return next(ServiceAccountNotFoundError({ message: "Failed to locate Service Account workspace permission" })); } const serviceAccount = await ServiceAccount.findById(serviceAccountWorkspacePermission.serviceAccount); if (!serviceAccount) { - return next(ServiceAccountNotFoundError({ message: 'Failed to locate Service Account' })); + return next(ServiceAccountNotFoundError({ message: "Failed to locate Service Account" })); } if (serviceAccount.user.toString() !== req.user.id.toString()) { @@ -39,7 +39,7 @@ const requireServiceAccountWorkspacePermissionAuth = ({ userId: req.user._id, organizationId: serviceAccount.organization, acceptedRoles, - acceptedStatuses + acceptedStatuses, }); } diff --git a/backend/src/middleware/requireServiceTokenAuth.ts b/backend/src/middleware/requireServiceTokenAuth.ts index 5db0dcda5b..340f03cc06 100644 --- a/backend/src/middleware/requireServiceTokenAuth.ts +++ b/backend/src/middleware/requireServiceTokenAuth.ts @@ -1,11 +1,11 @@ -import jwt from 'jsonwebtoken'; -import { Request, Response, NextFunction } from 'express'; -import { ServiceToken } from '../models'; -import { BadRequestError, UnauthorizedRequestError } from '../utils/errors'; -import { getJwtServiceSecret } from '../config'; +import jwt from "jsonwebtoken"; +import { NextFunction, Request, Response } from "express"; +import { ServiceToken } from "../models"; +import { BadRequestError, UnauthorizedRequestError } from "../utils/errors"; +import { getJwtServiceSecret } from "../config"; // TODO: deprecate -declare module 'jsonwebtoken' { +declare module "jsonwebtoken" { export interface UserIDJwtPayload extends jwt.JwtPayload { userId: string; } @@ -26,23 +26,23 @@ const requireServiceTokenAuth = async ( ) => { // JWT service token middleware - const [ AUTH_TOKEN_TYPE, AUTH_TOKEN_VALUE ] = <[string, string]>req.headers['authorization']?.split(' ', 2) ?? [null, null] - if(AUTH_TOKEN_TYPE === null) return next(BadRequestError({message: `Missing Authorization Header in the request header.`})) + const [ AUTH_TOKEN_TYPE, AUTH_TOKEN_VALUE ] = <[string, string]>req.headers["authorization"]?.split(" ", 2) ?? [null, null] + if(AUTH_TOKEN_TYPE === null) return next(BadRequestError({message: "Missing Authorization Header in the request header."})) //TODO: Determine what is the actual Token Type for Service Token Authentication (ex. Bearer) //if(AUTH_TOKEN_TYPE.toLowerCase() !== 'bearer') return next(UnauthorizedRequestError({message: `The provided authentication type '${AUTH_TOKEN_TYPE}' is not supported.`})) - if(AUTH_TOKEN_VALUE === null) return next(BadRequestError({message: 'Missing Authorization Body in the request header'})) + if(AUTH_TOKEN_VALUE === null) return next(BadRequestError({message: "Missing Authorization Body in the request header"})) const decodedToken = ( jwt.verify(AUTH_TOKEN_VALUE, await getJwtServiceSecret()) ); const serviceToken = await ServiceToken.findOne({ - _id: decodedToken.serviceTokenId + _id: decodedToken.serviceTokenId, }) - .populate('user', '+publicKey') - .select('+encryptedKey +publicKey +nonce'); + .populate("user", "+publicKey") + .select("+encryptedKey +publicKey +nonce"); - if (!serviceToken) return next(UnauthorizedRequestError({message: 'The service token does not match the record in the database'})) + if (!serviceToken) return next(UnauthorizedRequestError({message: "The service token does not match the record in the database"})) req.serviceToken = serviceToken; return next(); diff --git a/backend/src/middleware/requireServiceTokenDataAuth.ts b/backend/src/middleware/requireServiceTokenDataAuth.ts index be93fd799f..df5ca5ef1b 100644 --- a/backend/src/middleware/requireServiceTokenDataAuth.ts +++ b/backend/src/middleware/requireServiceTokenDataAuth.ts @@ -1,14 +1,14 @@ -import { Request, Response, NextFunction } from 'express'; -import { Types } from 'mongoose'; -import { validateClientForServiceTokenData } from '../validation'; +import { NextFunction, Request, Response } from "express"; +import { Types } from "mongoose"; +import { validateClientForServiceTokenData } from "../validation"; -type req = 'params' | 'body' | 'query'; +type req = "params" | "body" | "query"; const requireServiceTokenDataAuth = ({ acceptedRoles, - location = 'params' + location = "params", }: { - acceptedRoles: Array<'admin' | 'member'>; + acceptedRoles: Array<"admin" | "member">; location?: req; }) => { return async (req: Request, res: Response, next: NextFunction) => { @@ -17,7 +17,7 @@ const requireServiceTokenDataAuth = ({ req.serviceTokenData = await validateClientForServiceTokenData({ authData: req.authData, serviceTokenDataId: new Types.ObjectId(serviceTokenDataId), - acceptedRoles + acceptedRoles, }); next(); diff --git a/backend/src/middleware/requireSignupAuth.ts b/backend/src/middleware/requireSignupAuth.ts index 6a0fd0b6ee..3c5c48d126 100644 --- a/backend/src/middleware/requireSignupAuth.ts +++ b/backend/src/middleware/requireSignupAuth.ts @@ -1,10 +1,10 @@ -import jwt from 'jsonwebtoken'; -import { Request, Response, NextFunction } from 'express'; -import { User } from '../models'; -import { BadRequestError, UnauthorizedRequestError } from '../utils/errors'; -import { getJwtSignupSecret } from '../config'; +import jwt from "jsonwebtoken"; +import { NextFunction, Request, Response } from "express"; +import { User } from "../models"; +import { BadRequestError, UnauthorizedRequestError } from "../utils/errors"; +import { getJwtSignupSecret } from "../config"; -declare module 'jsonwebtoken' { +declare module "jsonwebtoken" { export interface UserIDJwtPayload extends jwt.JwtPayload { userId: string; } @@ -21,21 +21,21 @@ const requireSignupAuth = async ( ) => { // JWT (temporary) authentication middleware for complete signup - const [ AUTH_TOKEN_TYPE, AUTH_TOKEN_VALUE ] = <[string, string]>req.headers['authorization']?.split(' ', 2) ?? [null, null] - if(AUTH_TOKEN_TYPE === null) return next(BadRequestError({message: `Missing Authorization Header in the request header.`})) - if(AUTH_TOKEN_TYPE.toLowerCase() !== 'bearer') return next(BadRequestError({message: `The provided authentication type '${AUTH_TOKEN_TYPE}' is not supported.`})) - if(AUTH_TOKEN_VALUE === null) return next(BadRequestError({message: 'Missing Authorization Body in the request header'})) + const [ AUTH_TOKEN_TYPE, AUTH_TOKEN_VALUE ] = <[string, string]>req.headers["authorization"]?.split(" ", 2) ?? [null, null] + if(AUTH_TOKEN_TYPE === null) return next(BadRequestError({message: "Missing Authorization Header in the request header."})) + if(AUTH_TOKEN_TYPE.toLowerCase() !== "bearer") return next(BadRequestError({message: `The provided authentication type '${AUTH_TOKEN_TYPE}' is not supported.`})) + if(AUTH_TOKEN_VALUE === null) return next(BadRequestError({message: "Missing Authorization Body in the request header"})) const decodedToken = ( jwt.verify(AUTH_TOKEN_VALUE, await getJwtSignupSecret()) ); const user = await User.findOne({ - _id: decodedToken.userId - }).select('+publicKey'); + _id: decodedToken.userId, + }).select("+publicKey"); if (!user) - return next(UnauthorizedRequestError({message: 'Unable to authenticate for User account completion. Try logging in again'})) + return next(UnauthorizedRequestError({message: "Unable to authenticate for User account completion. Try logging in again"})) req.user = user; return next(); diff --git a/backend/src/middleware/requireWorkspaceAuth.ts b/backend/src/middleware/requireWorkspaceAuth.ts index 9833e6e566..197995a65e 100644 --- a/backend/src/middleware/requireWorkspaceAuth.ts +++ b/backend/src/middleware/requireWorkspaceAuth.ts @@ -1,8 +1,8 @@ -import { Request, Response, NextFunction } from 'express'; -import { Types } from 'mongoose'; -import { validateClientForWorkspace } from '../validation'; +import { NextFunction, Request, Response } from "express"; +import { Types } from "mongoose"; +import { validateClientForWorkspace } from "../validation"; -type req = 'params' | 'body' | 'query'; +type req = "params" | "body" | "query"; /** * Validate if user on request is a member with proper roles for workspace @@ -17,9 +17,9 @@ const requireWorkspaceAuth = ({ locationEnvironment = undefined, requiredPermissions = [], requireBlindIndicesEnabled = false, - requireE2EEOff = false + requireE2EEOff = false, }: { - acceptedRoles: Array<'admin' | 'member'>; + acceptedRoles: Array<"admin" | "member">; locationWorkspaceId: req; locationEnvironment?: req | undefined; requiredPermissions?: string[]; @@ -38,7 +38,7 @@ const requireWorkspaceAuth = ({ acceptedRoles, requiredPermissions, requireBlindIndicesEnabled, - requireE2EEOff + requireE2EEOff, }); if (membership) { diff --git a/backend/src/middleware/validateRequest.ts b/backend/src/middleware/validateRequest.ts index 1b03647666..56ea2653cc 100644 --- a/backend/src/middleware/validateRequest.ts +++ b/backend/src/middleware/validateRequest.ts @@ -1,6 +1,6 @@ -import { Request, Response, NextFunction } from 'express'; -import { validationResult } from 'express-validator'; -import { BadRequestError, UnauthorizedRequestError, ValidationError } from '../utils/errors'; +import { NextFunction, Request, Response } from "express"; +import { validationResult } from "express-validator"; +import { UnauthorizedRequestError, ValidationError } from "../utils/errors"; /** * Validate intended inputs on [req] via express-validator @@ -20,7 +20,7 @@ const validate = (req: Request, res: Response, next: NextFunction) => { return next(); } catch (err) { - return next(UnauthorizedRequestError({ message: 'Unauthenticated requests are not allowed. Try logging in' })) + return next(UnauthorizedRequestError({ message: "Unauthenticated requests are not allowed. Try logging in" })) } }; diff --git a/backend/src/models/apiKeyData.ts b/backend/src/models/apiKeyData.ts index 1b6831730d..622e62be17 100644 --- a/backend/src/models/apiKeyData.ts +++ b/backend/src/models/apiKeyData.ts @@ -1,4 +1,4 @@ -import { Schema, model, Types } from 'mongoose'; +import { Schema, Types, model } from "mongoose"; export interface IAPIKeyData { name: string; @@ -12,30 +12,30 @@ const apiKeyDataSchema = new Schema( { name: { type: String, - required: true + required: true, }, user: { type: Schema.Types.ObjectId, - ref: 'User', - required: true + ref: "User", + required: true, }, lastUsed: { - type: Date + type: Date, }, expiresAt: { - type: Date + type: Date, }, secretHash: { type: String, required: true, - select: false - } + select: false, + }, }, { - timestamps: true + timestamps: true, } ); -const APIKeyData = model('APIKeyData', apiKeyDataSchema); +const APIKeyData = model("APIKeyData", apiKeyDataSchema); export default APIKeyData; diff --git a/backend/src/models/backupPrivateKey.ts b/backend/src/models/backupPrivateKey.ts index 09bcbb5885..01f0dae218 100644 --- a/backend/src/models/backupPrivateKey.ts +++ b/backend/src/models/backupPrivateKey.ts @@ -1,9 +1,9 @@ -import { Schema, model, Types } from 'mongoose'; +import { Schema, Types, model } from "mongoose"; import { ALGORITHM_AES_256_GCM, + ENCODING_SCHEME_BASE64, ENCODING_SCHEME_UTF8, - ENCODING_SCHEME_BASE64 -} from '../variables'; +} from "../variables"; export interface IBackupPrivateKey { _id: Types.ObjectId; @@ -13,7 +13,7 @@ export interface IBackupPrivateKey { tag: string; salt: string; algorithm: string; - keyEncoding: 'base64' | 'utf8'; + keyEncoding: "base64" | "utf8"; verifier: string; } @@ -21,55 +21,55 @@ const backupPrivateKeySchema = new Schema( { user: { type: Schema.Types.ObjectId, - ref: 'User', - required: true + ref: "User", + required: true, }, encryptedPrivateKey: { type: String, select: false, - required: true + required: true, }, iv: { type: String, select: false, - required: true + required: true, }, tag: { type: String, select: false, - required: true + required: true, }, algorithm: { // the encryption algorithm used type: String, enum: [ALGORITHM_AES_256_GCM], - required: true + required: true, }, keyEncoding: { type: String, enum: [ ENCODING_SCHEME_UTF8, - ENCODING_SCHEME_BASE64 + ENCODING_SCHEME_BASE64, ], - required: true + required: true, }, salt: { type: String, select: false, - required: true + required: true, }, verifier: { type: String, select: false, - required: true - } + required: true, + }, }, { - timestamps: true + timestamps: true, } ); const BackupPrivateKey = model( - 'BackupPrivateKey', + "BackupPrivateKey", backupPrivateKeySchema ); diff --git a/backend/src/models/bot.ts b/backend/src/models/bot.ts index 5755bfd8e6..96107a2317 100644 --- a/backend/src/models/bot.ts +++ b/backend/src/models/bot.ts @@ -1,10 +1,9 @@ -import { Schema, model, Types } from 'mongoose'; +import { Schema, Types, model } from "mongoose"; import { ALGORITHM_AES_256_GCM, + ENCODING_SCHEME_BASE64, ENCODING_SCHEME_UTF8, - ENCODING_SCHEME_HEX, - ENCODING_SCHEME_BASE64 -} from '../variables'; +} from "../variables"; export interface IBot { _id: Types.ObjectId; @@ -15,66 +14,66 @@ export interface IBot { encryptedPrivateKey: string; iv: string; tag: string; - algorithm: 'aes-256-gcm'; - keyEncoding: 'base64' | 'utf8'; + algorithm: "aes-256-gcm"; + keyEncoding: "base64" | "utf8"; } const botSchema = new Schema( { name: { type: String, - required: true + required: true, }, workspace: { type: Schema.Types.ObjectId, - ref: 'Workspace', - required: true + ref: "Workspace", + required: true, }, isActive: { type: Boolean, required: true, - default: false + default: false, }, publicKey: { type: String, - required: true + required: true, }, encryptedPrivateKey: { type: String, required: true, - select: false + select: false, }, iv: { type: String, required: true, - select: false + select: false, }, tag: { type: String, required: true, - select: false + select: false, }, algorithm: { // the encryption algorithm used type: String, enum: [ALGORITHM_AES_256_GCM], required: true, - select: false + select: false, }, keyEncoding: { type: String, enum: [ ENCODING_SCHEME_UTF8, - ENCODING_SCHEME_BASE64 + ENCODING_SCHEME_BASE64, ], required: true, - select: false - } + select: false, + }, }, { - timestamps: true + timestamps: true, } ); -const Bot = model('Bot', botSchema); +const Bot = model("Bot", botSchema); export default Bot; diff --git a/backend/src/models/botKey.ts b/backend/src/models/botKey.ts index 79555cd530..b7be364dd9 100644 --- a/backend/src/models/botKey.ts +++ b/backend/src/models/botKey.ts @@ -1,4 +1,4 @@ -import { Schema, model, Types } from 'mongoose'; +import { Schema, Types, model } from "mongoose"; export interface IBotKey { _id: Types.ObjectId; @@ -13,33 +13,33 @@ const botKeySchema = new Schema( { encryptedKey: { type: String, - required: true + required: true, }, nonce: { type: String, - required: true + required: true, }, sender: { type: Schema.Types.ObjectId, - ref: 'User', - required: true + ref: "User", + required: true, }, bot: { type: Schema.Types.ObjectId, - ref: 'Bot', - required: true + ref: "Bot", + required: true, }, workspace: { type: Schema.Types.ObjectId, - ref: 'Workspace', - required: true - } + ref: "Workspace", + required: true, + }, }, { - timestamps: true + timestamps: true, } ); -const BotKey = model('BotKey', botKeySchema); +const BotKey = model("BotKey", botKeySchema); export default BotKey; diff --git a/backend/src/models/folder.ts b/backend/src/models/folder.ts index ac03582873..46f532c7d7 100644 --- a/backend/src/models/folder.ts +++ b/backend/src/models/folder.ts @@ -1,4 +1,4 @@ -import { Schema, model, Types } from "mongoose"; +import { Schema, Types, model } from "mongoose"; export type TFolderRootSchema = { _id: Types.ObjectId; diff --git a/backend/src/models/incidentContactOrg.ts b/backend/src/models/incidentContactOrg.ts index e1a969e110..16e5e4f025 100644 --- a/backend/src/models/incidentContactOrg.ts +++ b/backend/src/models/incidentContactOrg.ts @@ -1,4 +1,4 @@ -import { Schema, model, Types } from 'mongoose'; +import { Schema, Types, model } from "mongoose"; export interface IIncidentContactOrg { _id: Types.ObjectId; @@ -10,21 +10,21 @@ const incidentContactOrgSchema = new Schema( { email: { type: String, - required: true + required: true, }, organization: { type: Schema.Types.ObjectId, - ref: 'Organization', - required: true - } + ref: "Organization", + required: true, + }, }, { - timestamps: true + timestamps: true, } ); const IncidentContactOrg = model( - 'IncidentContactOrg', + "IncidentContactOrg", incidentContactOrgSchema ); diff --git a/backend/src/models/index.ts b/backend/src/models/index.ts index cb4ee672af..bf997811ae 100644 --- a/backend/src/models/index.ts +++ b/backend/src/models/index.ts @@ -1,28 +1,28 @@ -import BackupPrivateKey, { IBackupPrivateKey } from './backupPrivateKey'; -import Bot, { IBot } from './bot'; -import BotKey, { IBotKey } from './botKey'; -import IncidentContactOrg, { IIncidentContactOrg } from './incidentContactOrg'; -import Integration, { IIntegration } from './integration'; -import IntegrationAuth, { IIntegrationAuth } from './integrationAuth'; -import Key, { IKey } from './key'; -import Membership, { IMembership } from './membership'; -import MembershipOrg, { IMembershipOrg } from './membershipOrg'; -import Organization, { IOrganization } from './organization'; -import Secret, { ISecret } from './secret'; -import SecretBlindIndexData, { ISecretBlindIndexData } from './secretBlindIndexData'; -import ServiceToken, { IServiceToken } from './serviceToken'; -import ServiceAccount, { IServiceAccount } from './serviceAccount'; // new -import ServiceAccountKey, { IServiceAccountKey } from './serviceAccountKey'; // new -import ServiceAccountOrganizationPermission, { IServiceAccountOrganizationPermission } from './serviceAccountOrganizationPermission'; // new -import ServiceAccountWorkspacePermission, { IServiceAccountWorkspacePermission } from './serviceAccountWorkspacePermission'; // new -import TokenData, { ITokenData } from './tokenData'; -import User,{ AuthProvider, IUser } from './user'; -import UserAction, { IUserAction } from './userAction'; -import Workspace, { IWorkspace } from './workspace'; -import ServiceTokenData, { IServiceTokenData } from './serviceTokenData'; -import APIKeyData, { IAPIKeyData } from './apiKeyData'; -import LoginSRPDetail, { ILoginSRPDetail } from './loginSRPDetail'; -import TokenVersion, { ITokenVersion } from './tokenVersion'; +import BackupPrivateKey, { IBackupPrivateKey } from "./backupPrivateKey"; +import Bot, { IBot } from "./bot"; +import BotKey, { IBotKey } from "./botKey"; +import IncidentContactOrg, { IIncidentContactOrg } from "./incidentContactOrg"; +import Integration, { IIntegration } from "./integration"; +import IntegrationAuth, { IIntegrationAuth } from "./integrationAuth"; +import Key, { IKey } from "./key"; +import Membership, { IMembership } from "./membership"; +import MembershipOrg, { IMembershipOrg } from "./membershipOrg"; +import Organization, { IOrganization } from "./organization"; +import Secret, { ISecret } from "./secret"; +import SecretBlindIndexData, { ISecretBlindIndexData } from "./secretBlindIndexData"; +import ServiceToken, { IServiceToken } from "./serviceToken"; +import ServiceAccount, { IServiceAccount } from "./serviceAccount"; // new +import ServiceAccountKey, { IServiceAccountKey } from "./serviceAccountKey"; // new +import ServiceAccountOrganizationPermission, { IServiceAccountOrganizationPermission } from "./serviceAccountOrganizationPermission"; // new +import ServiceAccountWorkspacePermission, { IServiceAccountWorkspacePermission } from "./serviceAccountWorkspacePermission"; // new +import TokenData, { ITokenData } from "./tokenData"; +import User,{ AuthProvider, IUser } from "./user"; +import UserAction, { IUserAction } from "./userAction"; +import Workspace, { IWorkspace } from "./workspace"; +import ServiceTokenData, { IServiceTokenData } from "./serviceTokenData"; +import APIKeyData, { IAPIKeyData } from "./apiKeyData"; +import LoginSRPDetail, { ILoginSRPDetail } from "./loginSRPDetail"; +import TokenVersion, { ITokenVersion } from "./tokenVersion"; export { AuthProvider, @@ -75,5 +75,5 @@ export { LoginSRPDetail, ILoginSRPDetail, TokenVersion, - ITokenVersion + ITokenVersion, }; diff --git a/backend/src/models/integration.ts b/backend/src/models/integration.ts index c23cf69f18..87281b5cca 100644 --- a/backend/src/models/integration.ts +++ b/backend/src/models/integration.ts @@ -1,21 +1,21 @@ -import { Schema, model, Types } from "mongoose"; +import { Schema, Types, model } from "mongoose"; import { - INTEGRATION_AZURE_KEY_VAULT, INTEGRATION_AWS_PARAMETER_STORE, INTEGRATION_AWS_SECRET_MANAGER, - INTEGRATION_HEROKU, - INTEGRATION_VERCEL, - INTEGRATION_NETLIFY, + INTEGRATION_AZURE_KEY_VAULT, + INTEGRATION_CHECKLY, + INTEGRATION_CIRCLECI, + INTEGRATION_FLYIO, INTEGRATION_GITHUB, INTEGRATION_GITLAB, - INTEGRATION_RENDER, - INTEGRATION_RAILWAY, - INTEGRATION_FLYIO, - INTEGRATION_CIRCLECI, - INTEGRATION_TRAVISCI, - INTEGRATION_SUPABASE, - INTEGRATION_CHECKLY, INTEGRATION_HASHICORP_VAULT, + INTEGRATION_HEROKU, + INTEGRATION_NETLIFY, + INTEGRATION_RAILWAY, + INTEGRATION_RENDER, + INTEGRATION_SUPABASE, + INTEGRATION_TRAVISCI, + INTEGRATION_VERCEL, } from "../variables"; export interface IIntegration { diff --git a/backend/src/models/integrationAuth.ts b/backend/src/models/integrationAuth.ts index cc28c9fd66..9f5293bb5b 100644 --- a/backend/src/models/integrationAuth.ts +++ b/backend/src/models/integrationAuth.ts @@ -1,29 +1,29 @@ -import { Schema, model, Types, Document } from "mongoose"; +import { Document, Schema, Types, model } from "mongoose"; import { - INTEGRATION_AZURE_KEY_VAULT, + ALGORITHM_AES_256_GCM, + ENCODING_SCHEME_BASE64, + ENCODING_SCHEME_UTF8, INTEGRATION_AWS_PARAMETER_STORE, INTEGRATION_AWS_SECRET_MANAGER, - INTEGRATION_HEROKU, - INTEGRATION_VERCEL, - INTEGRATION_NETLIFY, + INTEGRATION_AZURE_KEY_VAULT, + INTEGRATION_CIRCLECI, + INTEGRATION_FLYIO, INTEGRATION_GITHUB, INTEGRATION_GITLAB, - INTEGRATION_RENDER, - INTEGRATION_RAILWAY, - INTEGRATION_FLYIO, - INTEGRATION_CIRCLECI, - INTEGRATION_TRAVISCI, - INTEGRATION_SUPABASE, INTEGRATION_HASHICORP_VAULT, - ALGORITHM_AES_256_GCM, - ENCODING_SCHEME_UTF8, - ENCODING_SCHEME_BASE64 + INTEGRATION_HEROKU, + INTEGRATION_NETLIFY, + INTEGRATION_RAILWAY, + INTEGRATION_RENDER, + INTEGRATION_SUPABASE, + INTEGRATION_TRAVISCI, + INTEGRATION_VERCEL, } from "../variables"; export interface IIntegrationAuth extends Document { _id: Types.ObjectId; workspace: Types.ObjectId; - integration: 'heroku' | 'vercel' | 'netlify' | 'github' | 'gitlab' | 'render' | 'railway' | 'flyio' | 'azure-key-vault' | 'circleci' | 'travisci' | 'supabase' | 'aws-parameter-store' | 'aws-secret-manager' | 'checkly'; + integration: "heroku" | "vercel" | "netlify" | "github" | "gitlab" | "render" | "railway" | "flyio" | "azure-key-vault" | "circleci" | "travisci" | "supabase" | "aws-parameter-store" | "aws-secret-manager" | "checkly"; teamId: string; accountId: string; url: string; @@ -37,8 +37,8 @@ export interface IIntegrationAuth extends Document { accessCiphertext?: string; accessIV?: string; accessTag?: string; - algorithm?: 'aes-256-gcm'; - keyEncoding?: 'utf8' | 'base64'; + algorithm?: "aes-256-gcm"; + keyEncoding?: "utf8" | "base64"; accessExpiresAt?: Date; } @@ -66,7 +66,7 @@ const integrationAuthSchema = new Schema( INTEGRATION_CIRCLECI, INTEGRATION_TRAVISCI, INTEGRATION_SUPABASE, - INTEGRATION_HASHICORP_VAULT + INTEGRATION_HASHICORP_VAULT, ], required: true, }, @@ -76,11 +76,11 @@ const integrationAuthSchema = new Schema( }, url: { // for any self-hosted integrations (e.g. self-hosted hashicorp-vault) - type: String + type: String, }, namespace: { // hashicorp-vault-specific integration param - type: String + type: String, }, accountId: { // netlify-specific integration param @@ -100,15 +100,15 @@ const integrationAuthSchema = new Schema( }, accessIdCiphertext: { type: String, - select: false + select: false, }, accessIdIV: { type: String, - select: false + select: false, }, accessIdTag: { type: String, - select: false + select: false, }, accessCiphertext: { type: String, @@ -129,16 +129,16 @@ const integrationAuthSchema = new Schema( algorithm: { // the encryption algorithm used type: String, enum: [ALGORITHM_AES_256_GCM], - required: true + required: true, }, keyEncoding: { type: String, enum: [ ENCODING_SCHEME_UTF8, - ENCODING_SCHEME_BASE64 + ENCODING_SCHEME_BASE64, ], - required: true - } + required: true, + }, }, { timestamps: true, diff --git a/backend/src/models/key.ts b/backend/src/models/key.ts index cd3d3fdd5f..faa37cd869 100644 --- a/backend/src/models/key.ts +++ b/backend/src/models/key.ts @@ -1,4 +1,4 @@ -import { Schema, model, Types } from 'mongoose'; +import { Schema, Types, model } from "mongoose"; export interface IKey { _id: Types.ObjectId; @@ -13,33 +13,33 @@ const keySchema = new Schema( { encryptedKey: { type: String, - required: true + required: true, }, nonce: { type: String, - required: true + required: true, }, sender: { type: Schema.Types.ObjectId, - ref: 'User', - required: true + ref: "User", + required: true, }, receiver: { type: Schema.Types.ObjectId, - ref: 'User', - required: true + ref: "User", + required: true, }, workspace: { type: Schema.Types.ObjectId, - ref: 'Workspace', - required: true - } + ref: "Workspace", + required: true, + }, }, { - timestamps: true + timestamps: true, } ); -const Key = model('Key', keySchema); +const Key = model("Key", keySchema); export default Key; diff --git a/backend/src/models/loginSRPDetail.ts b/backend/src/models/loginSRPDetail.ts index dde59233d0..8e9e121c51 100644 --- a/backend/src/models/loginSRPDetail.ts +++ b/backend/src/models/loginSRPDetail.ts @@ -1,4 +1,4 @@ -import mongoose, { Schema, model, Types } from 'mongoose'; +import mongoose, { Schema, Types, model } from "mongoose"; export interface ILoginSRPDetail { _id: Types.ObjectId; @@ -13,17 +13,17 @@ const loginSRPDetailSchema = new Schema( { clientPublicKey: { type: String, - required: true + required: true, }, email: { type: String, - unique: true + unique: true, }, serverBInt: { type: mongoose.Schema.Types.Buffer }, - expireAt: { type: Date } + expireAt: { type: Date }, } ); -const LoginSRPDetail = model('LoginSRPDetail', loginSRPDetailSchema); +const LoginSRPDetail = model("LoginSRPDetail", loginSRPDetailSchema); export default LoginSRPDetail; diff --git a/backend/src/models/membership.ts b/backend/src/models/membership.ts index 55b8f2048d..0fca743b4c 100644 --- a/backend/src/models/membership.ts +++ b/backend/src/models/membership.ts @@ -1,5 +1,5 @@ -import { Schema, model, Types } from 'mongoose'; -import { ADMIN, MEMBER } from '../variables'; +import { Schema, Types, model } from "mongoose"; +import { ADMIN, MEMBER } from "../variables"; export interface IMembershipPermission { environmentSlug: string, @@ -11,7 +11,7 @@ export interface IMembership { user: Types.ObjectId; inviteEmail?: string; workspace: Types.ObjectId; - role: 'admin' | 'member'; + role: "admin" | "member"; deniedPermissions: IMembershipPermission[] } @@ -19,15 +19,15 @@ const membershipSchema = new Schema( { user: { type: Schema.Types.ObjectId, - ref: 'User' + ref: "User", }, inviteEmail: { - type: String + type: String, }, workspace: { type: Schema.Types.ObjectId, - ref: 'Workspace', - required: true + ref: "Workspace", + required: true, }, deniedPermissions: { type: [ @@ -35,23 +35,23 @@ const membershipSchema = new Schema( environmentSlug: String, ability: { type: String, - enum: ['read', 'write'] + enum: ["read", "write"], }, }, ], - default: [] + default: [], }, role: { type: String, enum: [ADMIN, MEMBER], - required: true - } + required: true, + }, }, { - timestamps: true + timestamps: true, } ); -const Membership = model('Membership', membershipSchema); +const Membership = model("Membership", membershipSchema); export default Membership; diff --git a/backend/src/models/membershipOrg.ts b/backend/src/models/membershipOrg.ts index 540a4451b1..74a09b8050 100644 --- a/backend/src/models/membershipOrg.ts +++ b/backend/src/models/membershipOrg.ts @@ -1,46 +1,46 @@ -import { Schema, model, Types, Document } from 'mongoose'; -import { OWNER, ADMIN, MEMBER, INVITED, ACCEPTED } from '../variables'; +import { Document, Schema, Types, model } from "mongoose"; +import { ACCEPTED, ADMIN, INVITED, MEMBER, OWNER } from "../variables"; export interface IMembershipOrg extends Document { _id: Types.ObjectId; user: Types.ObjectId; inviteEmail: string; organization: Types.ObjectId; - role: 'owner' | 'admin' | 'member'; - status: 'invited' | 'accepted'; + role: "owner" | "admin" | "member"; + status: "invited" | "accepted"; } const membershipOrgSchema = new Schema( { user: { type: Schema.Types.ObjectId, - ref: 'User' + ref: "User", }, inviteEmail: { - type: String + type: String, }, organization: { type: Schema.Types.ObjectId, - ref: 'Organization' + ref: "Organization", }, role: { type: String, enum: [OWNER, ADMIN, MEMBER], - required: true + required: true, }, status: { type: String, enum: [INVITED, ACCEPTED], - required: true - } + required: true, + }, }, { - timestamps: true + timestamps: true, } ); const MembershipOrg = model( - 'MembershipOrg', + "MembershipOrg", membershipOrgSchema ); diff --git a/backend/src/models/organization.ts b/backend/src/models/organization.ts index a39d42cd0a..bafcc05f8a 100644 --- a/backend/src/models/organization.ts +++ b/backend/src/models/organization.ts @@ -1,4 +1,4 @@ -import { Schema, model, Types } from 'mongoose'; +import { Schema, Types, model } from "mongoose"; export interface IOrganization { _id: Types.ObjectId; @@ -10,17 +10,17 @@ const organizationSchema = new Schema( { name: { type: String, - required: true + required: true, }, customerId: { - type: String - } + type: String, + }, }, { - timestamps: true + timestamps: true, } ); -const Organization = model('Organization', organizationSchema); +const Organization = model("Organization", organizationSchema); export default Organization; diff --git a/backend/src/models/secret.ts b/backend/src/models/secret.ts index ff34d99b1a..34a4d75013 100644 --- a/backend/src/models/secret.ts +++ b/backend/src/models/secret.ts @@ -1,10 +1,10 @@ -import { Schema, model, Types } from "mongoose"; +import { Schema, Types, model } from "mongoose"; import { - SECRET_SHARED, - SECRET_PERSONAL, ALGORITHM_AES_256_GCM, - ENCODING_SCHEME_UTF8, ENCODING_SCHEME_BASE64, + ENCODING_SCHEME_UTF8, + SECRET_PERSONAL, + SECRET_SHARED, } from "../variables"; export interface ISecret { diff --git a/backend/src/models/secretApprovalRequest.ts b/backend/src/models/secretApprovalRequest.ts index 9fa897e256..008274dd95 100644 --- a/backend/src/models/secretApprovalRequest.ts +++ b/backend/src/models/secretApprovalRequest.ts @@ -1,5 +1,5 @@ -import mongoose, { Schema, model } from 'mongoose'; -import Secret, { ISecret } from './secret'; +import mongoose, { Schema, model } from "mongoose"; +import Secret, { ISecret } from "./secret"; interface ISecretApprovalRequest { secret: mongoose.Types.ObjectId; @@ -18,66 +18,66 @@ interface IApprover { } export enum ApprovalStatus { - PENDING = 'pending', - APPROVED = 'approved', - REJECTED = 'rejected' + PENDING = "pending", + APPROVED = "approved", + REJECTED = "rejected" } export enum RequestType { - UPDATE = 'update', - DELETE = 'delete', - CREATE = 'create' + UPDATE = "update", + DELETE = "delete", + CREATE = "create" } const approverSchema = new mongoose.Schema({ user: { type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true + ref: "User", + required: true, }, status: { type: String, enum: [ApprovalStatus], - default: ApprovalStatus.PENDING - } + default: ApprovalStatus.PENDING, + }, }); const secretApprovalRequestSchema = new Schema( { secret: { type: mongoose.Schema.Types.ObjectId, - ref: 'Secret' + ref: "Secret", }, requestedChanges: Secret, requestedBy: { type: mongoose.Schema.Types.ObjectId, - ref: 'User' + ref: "User", }, approvers: [approverSchema], status: { type: String, enum: ApprovalStatus, - default: ApprovalStatus.PENDING + default: ApprovalStatus.PENDING, }, timestamp: { type: Date, - default: Date.now + default: Date.now, }, requestType: { type: String, enum: RequestType, - required: true + required: true, }, requestId: { type: String, - required: false - } + required: false, + }, }, { - timestamps: true + timestamps: true, } ); -const SecretApprovalRequest = model('SecretApprovalRequest', secretApprovalRequestSchema); +const SecretApprovalRequest = model("SecretApprovalRequest", secretApprovalRequestSchema); export default SecretApprovalRequest; diff --git a/backend/src/models/secretBlindIndexData.ts b/backend/src/models/secretBlindIndexData.ts index 885faaff60..ca277d19e3 100644 --- a/backend/src/models/secretBlindIndexData.ts +++ b/backend/src/models/secretBlindIndexData.ts @@ -1,9 +1,9 @@ -import { Schema, model, Types, Document } from 'mongoose'; +import { Document, Schema, Types, model } from "mongoose"; import { ALGORITHM_AES_256_GCM, + ENCODING_SCHEME_BASE64, ENCODING_SCHEME_UTF8, - ENCODING_SCHEME_BASE64 -} from '../variables'; +} from "../variables"; export interface ISecretBlindIndexData extends Document { _id: Types.ObjectId; @@ -11,48 +11,48 @@ export interface ISecretBlindIndexData extends Document { encryptedSaltCiphertext: string; saltIV: string; saltTag: string; - algorithm: 'aes-256-gcm'; - keyEncoding: 'base64' | 'utf8' + algorithm: "aes-256-gcm"; + keyEncoding: "base64" | "utf8" } const secretBlindIndexDataSchema = new Schema( { workspace: { type: Schema.Types.ObjectId, - ref: 'Workspace', - required: true + ref: "Workspace", + required: true, }, encryptedSaltCiphertext: { // TODO: make these select: false type: String, - required: true + required: true, }, saltIV: { type: String, - required: true + required: true, }, saltTag: { type: String, - required: true + required: true, }, algorithm: { type: String, enum: [ALGORITHM_AES_256_GCM], required: true, - select: false + select: false, }, keyEncoding: { type: String, enum: [ ENCODING_SCHEME_UTF8, - ENCODING_SCHEME_BASE64 + ENCODING_SCHEME_BASE64, ], required: true, - select: false - } + select: false, + }, } ); -const SecretBlindIndexData = model('SecretBlindIndexData', secretBlindIndexDataSchema); +const SecretBlindIndexData = model("SecretBlindIndexData", secretBlindIndexDataSchema); export default SecretBlindIndexData; \ No newline at end of file diff --git a/backend/src/models/serviceAccount.ts b/backend/src/models/serviceAccount.ts index 9ff9dcb031..090d55c214 100644 --- a/backend/src/models/serviceAccount.ts +++ b/backend/src/models/serviceAccount.ts @@ -1,4 +1,4 @@ -import { Schema, model, Types, Document } from 'mongoose'; +import { Document, Schema, Types, model } from "mongoose"; export interface IServiceAccount extends Document { _id: Types.ObjectId; @@ -15,39 +15,39 @@ const serviceAccountSchema = new Schema( { name: { type: String, - required: true + required: true, }, organization: { type: Schema.Types.ObjectId, - ref: 'Organization', - required: true + ref: "Organization", + required: true, }, user: { // user who created the service account type: Schema.Types.ObjectId, - ref: 'User', - required: true + ref: "User", + required: true, }, publicKey: { type: String, - required: true + required: true, }, lastUsed: { - type: Date + type: Date, }, expiresAt: { - type: Date + type: Date, }, secretHash: { type: String, required: true, - select: false - } + select: false, + }, }, { - timestamps: true + timestamps: true, } ); -const ServiceAccount = model('ServiceAccount', serviceAccountSchema); +const ServiceAccount = model("ServiceAccount", serviceAccountSchema); export default ServiceAccount; \ No newline at end of file diff --git a/backend/src/models/serviceAccountKey.ts b/backend/src/models/serviceAccountKey.ts index 637ac188b0..d442dcb082 100644 --- a/backend/src/models/serviceAccountKey.ts +++ b/backend/src/models/serviceAccountKey.ts @@ -1,4 +1,4 @@ -import { Schema, model, Types } from 'mongoose'; +import { Schema, Types, model } from "mongoose"; export interface IServiceAccountKey { _id: Types.ObjectId; @@ -13,32 +13,32 @@ const serviceAccountKeySchema = new Schema( { encryptedKey: { type: String, - required: true + required: true, }, nonce: { type: String, - required: true + required: true, }, sender: { type: Schema.Types.ObjectId, - required: true + required: true, }, serviceAccount: { type: Schema.Types.ObjectId, - ref: 'ServiceAccount', - required: true + ref: "ServiceAccount", + required: true, }, workspace: { type: Schema.Types.ObjectId, - ref: 'Workspace', - required: true - } + ref: "Workspace", + required: true, + }, }, { - timestamps: true + timestamps: true, } ); -const ServiceAccountKey = model('ServiceAccountKey', serviceAccountKeySchema); +const ServiceAccountKey = model("ServiceAccountKey", serviceAccountKeySchema); export default ServiceAccountKey; diff --git a/backend/src/models/serviceAccountOrganizationPermission.ts b/backend/src/models/serviceAccountOrganizationPermission.ts index 6454bc6a0b..4519bd8322 100644 --- a/backend/src/models/serviceAccountOrganizationPermission.ts +++ b/backend/src/models/serviceAccountOrganizationPermission.ts @@ -1,4 +1,4 @@ -import { Schema, model, Types, Document } from 'mongoose'; +import { Document, Schema, Types, model } from "mongoose"; export interface IServiceAccountOrganizationPermission extends Document { _id: Types.ObjectId; @@ -9,15 +9,15 @@ const serviceAccountOrganizationPermissionSchema = new Schema('ServiceAccountOrganizationPermission', serviceAccountOrganizationPermissionSchema); +const ServiceAccountOrganizationPermission = model("ServiceAccountOrganizationPermission", serviceAccountOrganizationPermissionSchema); export default ServiceAccountOrganizationPermission; \ No newline at end of file diff --git a/backend/src/models/serviceAccountWorkspacePermission.ts b/backend/src/models/serviceAccountWorkspacePermission.ts index 01e4c4ba6b..5814923e57 100644 --- a/backend/src/models/serviceAccountWorkspacePermission.ts +++ b/backend/src/models/serviceAccountWorkspacePermission.ts @@ -1,4 +1,4 @@ -import { Schema, model, Types, Document } from 'mongoose'; +import { Document, Schema, Types, model } from "mongoose"; export interface IServiceAccountWorkspacePermission extends Document { _id: Types.ObjectId; @@ -13,32 +13,32 @@ const serviceAccountWorkspacePermissionSchema = new Schema('ServiceAccountWorkspacePermission', serviceAccountWorkspacePermissionSchema); +const ServiceAccountWorkspacePermission = model("ServiceAccountWorkspacePermission", serviceAccountWorkspacePermissionSchema); export default ServiceAccountWorkspacePermission; \ No newline at end of file diff --git a/backend/src/models/serviceToken.ts b/backend/src/models/serviceToken.ts index 9d91b076ea..ce5fa3c9be 100644 --- a/backend/src/models/serviceToken.ts +++ b/backend/src/models/serviceToken.ts @@ -1,4 +1,4 @@ -import { Schema, model, Types } from 'mongoose'; +import { Schema, Types, model } from "mongoose"; export interface IServiceToken { _id: Types.ObjectId; name: string; @@ -15,47 +15,47 @@ const serviceTokenSchema = new Schema( { name: { type: String, - required: true + required: true, }, user: { // token issuer type: Schema.Types.ObjectId, - ref: 'User', - required: true + ref: "User", + required: true, }, workspace: { type: Schema.Types.ObjectId, - ref: 'Workspace', - required: true + ref: "Workspace", + required: true, }, environment: { type: String, - required: true + required: true, }, expiresAt: { - type: Date + type: Date, }, publicKey: { type: String, required: true, - select: true + select: true, }, encryptedKey: { type: String, required: true, - select: true + select: true, }, nonce: { type: String, required: true, - select: true - } + select: true, + }, }, { - timestamps: true + timestamps: true, } ); -const ServiceToken = model('ServiceToken', serviceTokenSchema); +const ServiceToken = model("ServiceToken", serviceTokenSchema); export default ServiceToken; diff --git a/backend/src/models/serviceTokenData.ts b/backend/src/models/serviceTokenData.ts index 3587a7ff4e..57528a4e94 100644 --- a/backend/src/models/serviceTokenData.ts +++ b/backend/src/models/serviceTokenData.ts @@ -1,4 +1,4 @@ -import { Schema, model, Types, Document } from "mongoose"; +import { Document, Schema, Types, model } from "mongoose"; export interface IServiceTokenData extends Document { _id: Types.ObjectId; diff --git a/backend/src/models/tag.ts b/backend/src/models/tag.ts index 6b02c8b1bc..53bf085d3a 100644 --- a/backend/src/models/tag.ts +++ b/backend/src/models/tag.ts @@ -1,4 +1,4 @@ -import { Schema, model, Types } from 'mongoose'; +import { Schema, Types, model } from "mongoose"; export interface ITag { _id: Types.ObjectId; @@ -22,28 +22,28 @@ const tagSchema = new Schema( lowercase: true, validate: [ function (value: any) { - return value.indexOf(' ') === -1; + return value.indexOf(" ") === -1; }, - 'slug cannot contain spaces' - ] + "slug cannot contain spaces", + ], }, user: { type: Schema.Types.ObjectId, - ref: 'User' + ref: "User", }, workspace: { type: Schema.Types.ObjectId, - ref: 'Workspace' + ref: "Workspace", }, }, { - timestamps: true + timestamps: true, } ); tagSchema.index({ slug: 1, workspace: 1 }, { unique: true }) tagSchema.index({ workspace: 1 }) -const Tag = model('Tag', tagSchema); +const Tag = model("Tag", tagSchema); export default Tag; diff --git a/backend/src/models/token.ts b/backend/src/models/token.ts index e6f485f55c..ab0a69c9e0 100644 --- a/backend/src/models/token.ts +++ b/backend/src/models/token.ts @@ -1,4 +1,4 @@ -import { Schema, model } from 'mongoose'; +import { Schema, model } from "mongoose"; export interface IToken { email: string; @@ -10,23 +10,23 @@ export interface IToken { const tokenSchema = new Schema({ email: { type: String, - required: true + required: true, }, token: { type: String, - required: true + required: true, }, createdAt: { type: Date, - default: Date.now + default: Date.now, }, ttl: { type: Number, - } + }, }); tokenSchema.index({ email: 1 }); -const Token = model('Token', tokenSchema); +const Token = model("Token", tokenSchema); export default Token; diff --git a/backend/src/models/tokenData.ts b/backend/src/models/tokenData.ts index 8856a36770..615c9019d8 100644 --- a/backend/src/models/tokenData.ts +++ b/backend/src/models/tokenData.ts @@ -1,4 +1,4 @@ -import { Schema, Types, model } from 'mongoose'; +import { Schema, Types, model } from "mongoose"; export interface ITokenData { type: string; @@ -16,40 +16,40 @@ const tokenDataSchema = new Schema({ type: { type: String, enum: [ - 'emailConfirmation', - 'emailMfa', - 'organizationInvitation', - 'passwordReset' + "emailConfirmation", + "emailMfa", + "organizationInvitation", + "passwordReset", ], - required: true + required: true, }, email: { - type: String + type: String, }, phoneNumber: { - type: String + type: String, }, organization: { // organizationInvitation-specific field type: Schema.Types.ObjectId, - ref: 'Organization' + ref: "Organization", }, tokenHash: { type: String, select: false, - required: true + required: true, }, triesLeft: { - type: Number + type: Number, }, expiresAt: { type: Date, expires: 0, - required: true - } + required: true, + }, }, { - timestamps: true + timestamps: true, }); -const TokenData = model('TokenData', tokenDataSchema); +const TokenData = model("TokenData", tokenDataSchema); export default TokenData; diff --git a/backend/src/models/tokenVersion.ts b/backend/src/models/tokenVersion.ts index 890c0a2723..1103fc3169 100644 --- a/backend/src/models/tokenVersion.ts +++ b/backend/src/models/tokenVersion.ts @@ -1,4 +1,4 @@ -import { Schema, model, Types, Document } from 'mongoose'; +import { Document, Schema, Types, model } from "mongoose"; export interface ITokenVersion extends Document { user: Types.ObjectId; @@ -13,35 +13,35 @@ const tokenVersionSchema = new Schema( { user: { type: Schema.Types.ObjectId, - ref: 'User', - required: true + ref: "User", + required: true, }, ip: { type: String, - required: true + required: true, }, userAgent: { type: String, - required: true + required: true, }, refreshVersion: { type: Number, - required: true + required: true, }, accessVersion: { type: Number, - required: true + required: true, }, lastUsed: { type: Date, - required: true - } + required: true, + }, }, { - timestamps: true + timestamps: true, } ); -const TokenVersion = model('TokenVersion', tokenVersionSchema); +const TokenVersion = model("TokenVersion", tokenVersionSchema); export default TokenVersion; \ No newline at end of file diff --git a/backend/src/models/user.ts b/backend/src/models/user.ts index 1c12720f82..b5f0027ca1 100644 --- a/backend/src/models/user.ts +++ b/backend/src/models/user.ts @@ -1,7 +1,7 @@ -import { Schema, model, Types, Document } from 'mongoose'; +import { Document, Schema, Types, model } from "mongoose"; export enum AuthProvider { - GOOGLE = 'google', + GOOGLE = "google", } export interface IUser extends Document { @@ -44,73 +44,73 @@ const userSchema = new Schema( unique: true, }, firstName: { - type: String + type: String, }, lastName: { - type: String + type: String, }, encryptionVersion: { type: Number, select: false, - default: 1 // to resolve backward-compatibility issues + default: 1, // to resolve backward-compatibility issues }, protectedKey: { // introduced as part of encryption version 2 type: String, - select: false + select: false, }, protectedKeyIV: { // introduced as part of encryption version 2 type: String, - select: false + select: false, }, protectedKeyTag: { // introduced as part of encryption version 2 type: String, - select: false + select: false, }, publicKey: { type: String, - select: false + select: false, }, encryptedPrivateKey: { type: String, - select: false + select: false, }, iv: { // iv of [encryptedPrivateKey] type: String, - select: false + select: false, }, tag: { // tag of [encryptedPrivateKey] type: String, - select: false + select: false, }, salt: { type: String, - select: false + select: false, }, verifier: { type: String, - select: false + select: false, }, isMfaEnabled: { type: Boolean, - default: false + default: false, }, mfaMethods: [{ - type: String + type: String, }], devices: { type: [{ ip: String, - userAgent: String + userAgent: String, }], default: [], - select: false - } + select: false, + }, }, { - timestamps: true + timestamps: true, } ); -const User = model('User', userSchema); +const User = model("User", userSchema); export default User; diff --git a/backend/src/models/userAction.ts b/backend/src/models/userAction.ts index a2c69d46cf..11eda05e86 100644 --- a/backend/src/models/userAction.ts +++ b/backend/src/models/userAction.ts @@ -1,4 +1,4 @@ -import { Schema, model, Types } from 'mongoose'; +import { Schema, Types, model } from "mongoose"; export interface IUserAction { _id: Types.ObjectId; @@ -10,19 +10,19 @@ const userActionSchema = new Schema( { user: { type: Schema.Types.ObjectId, - ref: 'User', - required: true + ref: "User", + required: true, }, action: { type: String, - required: true - } + required: true, + }, }, { - timestamps: true + timestamps: true, } ); -const UserAction = model('UserAction', userActionSchema); +const UserAction = model("UserAction", userActionSchema); export default UserAction; diff --git a/backend/src/models/workspace.ts b/backend/src/models/workspace.ts index ebd55d8026..b3dd28b00a 100644 --- a/backend/src/models/workspace.ts +++ b/backend/src/models/workspace.ts @@ -1,4 +1,4 @@ -import { Schema, model, Types } from 'mongoose'; +import { Schema, Types, model } from "mongoose"; export interface IWorkspace { _id: Types.ObjectId; @@ -14,7 +14,7 @@ export interface IWorkspace { const workspaceSchema = new Schema({ name: { type: String, - required: true + required: true, }, autoCapitalization: { type: Boolean, @@ -22,8 +22,8 @@ const workspaceSchema = new Schema({ }, organization: { type: Schema.Types.ObjectId, - ref: 'Organization', - required: true + ref: "Organization", + required: true, }, environments: { type: [ @@ -35,20 +35,20 @@ const workspaceSchema = new Schema({ default: [ { name: "Development", - slug: "dev" + slug: "dev", }, { name: "Staging", - slug: "staging" + slug: "staging", }, { name: "Production", - slug: "prod" - } + slug: "prod", + }, ], }, }); -const Workspace = model('Workspace', workspaceSchema); +const Workspace = model("Workspace", workspaceSchema); export default Workspace; \ No newline at end of file diff --git a/backend/src/routes/status/index.ts b/backend/src/routes/status/index.ts index d3c694b92e..6f3be6271a 100644 --- a/backend/src/routes/status/index.ts +++ b/backend/src/routes/status/index.ts @@ -1,5 +1,5 @@ -import healthCheck from './status'; +import healthCheck from "./status"; export { - healthCheck + healthCheck, } \ No newline at end of file diff --git a/backend/src/routes/status/status.ts b/backend/src/routes/status/status.ts index 91d0c9e854..0af4bb5c2c 100644 --- a/backend/src/routes/status/status.ts +++ b/backend/src/routes/status/status.ts @@ -1,15 +1,15 @@ -import express, { Request, Response } from 'express'; -import { getSmtpConfigured } from '../../config'; +import express, { Request, Response } from "express"; +import { getSmtpConfigured } from "../../config"; const router = express.Router(); router.get( - '/status', + "/status", async (req: Request, res: Response) => { res.status(200).json({ date: new Date(), - message: 'Ok', - emailConfigured: await getSmtpConfigured() + message: "Ok", + emailConfigured: await getSmtpConfigured(), }) } ); diff --git a/backend/src/routes/v1/auth.ts b/backend/src/routes/v1/auth.ts index ed86a236db..fcf9869cc4 100644 --- a/backend/src/routes/v1/auth.ts +++ b/backend/src/routes/v1/auth.ts @@ -1,75 +1,75 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); -import { body } from 'express-validator'; -import passport from 'passport'; -import { requireAuth, validateRequest } from '../../middleware'; -import { authController } from '../../controllers/v1'; -import { authLimiter } from '../../helpers/rateLimiter'; -import { AUTH_MODE_JWT } from '../../variables'; +import { body } from "express-validator"; +import passport from "passport"; +import { requireAuth, validateRequest } from "../../middleware"; +import { authController } from "../../controllers/v1"; +import { authLimiter } from "../../helpers/rateLimiter"; +import { AUTH_MODE_JWT } from "../../variables"; -router.post('/token', validateRequest, authController.getNewToken); +router.post("/token", validateRequest, authController.getNewToken); router.post( // deprecated (moved to api/v2/auth/login1) - '/login1', + "/login1", authLimiter, - body('email').exists().trim().notEmpty(), - body('clientPublicKey').exists().trim().notEmpty(), + body("email").exists().trim().notEmpty(), + body("clientPublicKey").exists().trim().notEmpty(), validateRequest, authController.login1 ); router.post( // deprecated (moved to api/v2/auth/login2) - '/login2', + "/login2", authLimiter, - body('email').exists().trim().notEmpty(), - body('clientProof').exists().trim().notEmpty(), + body("email").exists().trim().notEmpty(), + body("clientProof").exists().trim().notEmpty(), validateRequest, authController.login2 ); router.post( - '/logout', + "/logout", authLimiter, requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), authController.logout ); router.post( - '/checkAuth', + "/checkAuth", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), authController.checkAuth ); router.get( - '/redirect/google', + "/redirect/google", authLimiter, - passport.authenticate('google', { - scope: ['profile', 'email'], + passport.authenticate("google", { + scope: ["profile", "email"], session: false, }), ); router.get( - '/callback/google', - passport.authenticate('google', { failureRedirect: '/login/provider/error', session: false }), + "/callback/google", + passport.authenticate("google", { failureRedirect: "/login/provider/error", session: false }), authController.handleAuthProviderCallback, ); router.get( - '/common-passwords', + "/common-passwords", authLimiter, authController.getCommonPasswords ); router.delete( - '/sessions', + "/sessions", authLimiter, requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), authController.revokeAllSessions ); diff --git a/backend/src/routes/v1/bot.ts b/backend/src/routes/v1/bot.ts index 83e126dc40..0eafecad0e 100644 --- a/backend/src/routes/v1/bot.ts +++ b/backend/src/routes/v1/bot.ts @@ -1,39 +1,39 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); -import { body, param } from 'express-validator'; +import { body, param } from "express-validator"; import { requireAuth, requireBotAuth, requireWorkspaceAuth, - validateRequest -} from '../../middleware'; -import { botController } from '../../controllers/v1'; -import { ADMIN, MEMBER, AUTH_MODE_JWT } from '../../variables'; + validateRequest, +} from "../../middleware"; +import { botController } from "../../controllers/v1"; +import { ADMIN, AUTH_MODE_JWT, MEMBER } from "../../variables"; router.get( - '/:workspaceId', + "/:workspaceId", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - param('workspaceId').exists().trim().notEmpty(), + param("workspaceId").exists().trim().notEmpty(), validateRequest, botController.getBotByWorkspaceId ); router.patch( - '/:botId/active', + "/:botId/active", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireBotAuth({ - acceptedRoles: [ADMIN, MEMBER] + acceptedRoles: [ADMIN, MEMBER], }), - body('isActive').exists().isBoolean(), - body('botKey'), + body("isActive").exists().isBoolean(), + body("botKey"), validateRequest, botController.setBotActiveState ); diff --git a/backend/src/routes/v1/index.ts b/backend/src/routes/v1/index.ts index 62ff08b148..7efc36a953 100644 --- a/backend/src/routes/v1/index.ts +++ b/backend/src/routes/v1/index.ts @@ -1,21 +1,21 @@ -import signup from './signup'; -import bot from './bot'; -import auth from './auth'; -import user from './user'; -import userAction from './userAction'; -import organization from './organization'; -import workspace from './workspace'; -import membershipOrg from './membershipOrg'; -import membership from './membership'; -import key from './key'; -import inviteOrg from './inviteOrg'; -import secret from './secret'; -import serviceToken from './serviceToken'; -import password from './password'; -import stripe from './stripe'; -import integration from './integration'; -import integrationAuth from './integrationAuth'; -import secretsFolder from './secretsFolder'; +import signup from "./signup"; +import bot from "./bot"; +import auth from "./auth"; +import user from "./user"; +import userAction from "./userAction"; +import organization from "./organization"; +import workspace from "./workspace"; +import membershipOrg from "./membershipOrg"; +import membership from "./membership"; +import key from "./key"; +import inviteOrg from "./inviteOrg"; +import secret from "./secret"; +import serviceToken from "./serviceToken"; +import password from "./password"; +import stripe from "./stripe"; +import integration from "./integration"; +import integrationAuth from "./integrationAuth"; +import secretsFolder from "./secretsFolder"; export { signup, @@ -35,5 +35,5 @@ export { stripe, integration, integrationAuth, - secretsFolder + secretsFolder, }; diff --git a/backend/src/routes/v1/integration.ts b/backend/src/routes/v1/integration.ts index c4ba329c0c..1820f4bb82 100644 --- a/backend/src/routes/v1/integration.ts +++ b/backend/src/routes/v1/integration.ts @@ -8,9 +8,9 @@ import { } from "../../middleware"; import { ADMIN, - MEMBER, - AUTH_MODE_JWT, AUTH_MODE_API_KEY, + AUTH_MODE_JWT, + MEMBER, } from "../../variables"; import { body, param } from "express-validator"; import { integrationController } from "../../controllers/v1"; diff --git a/backend/src/routes/v1/integrationAuth.ts b/backend/src/routes/v1/integrationAuth.ts index f8fe15a4ba..28fa65af80 100644 --- a/backend/src/routes/v1/integrationAuth.ts +++ b/backend/src/routes/v1/integrationAuth.ts @@ -1,156 +1,156 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); -import { body, param, query } from 'express-validator'; +import { body, param, query } from "express-validator"; import { requireAuth, - requireWorkspaceAuth, requireIntegrationAuthorizationAuth, - validateRequest -} from '../../middleware'; + requireWorkspaceAuth, + validateRequest, +} from "../../middleware"; import { ADMIN, - MEMBER, + AUTH_MODE_API_KEY, AUTH_MODE_JWT, - AUTH_MODE_API_KEY -} from '../../variables'; -import { integrationAuthController } from '../../controllers/v1'; + MEMBER, +} from "../../variables"; +import { integrationAuthController } from "../../controllers/v1"; router.get( - '/integration-options', + "/integration-options", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), integrationAuthController.getIntegrationOptions ); router.get( - '/:integrationAuthId', + "/:integrationAuthId", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireIntegrationAuthorizationAuth({ - acceptedRoles: [ADMIN, MEMBER] + acceptedRoles: [ADMIN, MEMBER], }), - param('integrationAuthId'), + param("integrationAuthId"), validateRequest, integrationAuthController.getIntegrationAuth ); router.post( - '/oauth-token', + "/oauth-token", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'body' + locationWorkspaceId: "body", }), - body('workspaceId').exists().trim().notEmpty(), - body('code').exists().trim().notEmpty(), - body('integration').exists().trim().notEmpty(), + body("workspaceId").exists().trim().notEmpty(), + body("code").exists().trim().notEmpty(), + body("integration").exists().trim().notEmpty(), validateRequest, integrationAuthController.oAuthExchange ); router.post( - '/access-token', - body('workspaceId').exists().trim().notEmpty(), - body('accessId').trim(), - body('accessToken').exists().trim().notEmpty(), - body('url').trim(), - body('namespace').trim(), - body('integration').exists().trim().notEmpty(), + "/access-token", + body("workspaceId").exists().trim().notEmpty(), + body("accessId").trim(), + body("accessToken").exists().trim().notEmpty(), + body("url").trim(), + body("namespace").trim(), + body("integration").exists().trim().notEmpty(), validateRequest, requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY] + acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'body' + locationWorkspaceId: "body", }), integrationAuthController.saveIntegrationAccessToken ); router.get( - '/:integrationAuthId/apps', + "/:integrationAuthId/apps", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireIntegrationAuthorizationAuth({ - acceptedRoles: [ADMIN, MEMBER] + acceptedRoles: [ADMIN, MEMBER], }), - param('integrationAuthId'), - query('teamId'), + param("integrationAuthId"), + query("teamId"), validateRequest, integrationAuthController.getIntegrationAuthApps ); router.get( - '/:integrationAuthId/teams', + "/:integrationAuthId/teams", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireIntegrationAuthorizationAuth({ - acceptedRoles: [ADMIN, MEMBER] + acceptedRoles: [ADMIN, MEMBER], }), - param('integrationAuthId'), + param("integrationAuthId"), validateRequest, integrationAuthController.getIntegrationAuthTeams ); router.get( - '/:integrationAuthId/vercel/branches', + "/:integrationAuthId/vercel/branches", requireAuth({ - acceptedAuthModes: ['jwt'] + acceptedAuthModes: ["jwt"], }), requireIntegrationAuthorizationAuth({ - acceptedRoles: [ADMIN, MEMBER] + acceptedRoles: [ADMIN, MEMBER], }), - param('integrationAuthId').exists().isString(), - query('appId').exists().isString(), - query('teamId').optional().isString(), + param("integrationAuthId").exists().isString(), + query("appId").exists().isString(), + query("teamId").optional().isString(), validateRequest, integrationAuthController.getIntegrationAuthVercelBranches ); router.get( - '/:integrationAuthId/railway/environments', + "/:integrationAuthId/railway/environments", requireAuth({ - acceptedAuthModes: ['jwt'] + acceptedAuthModes: ["jwt"], }), requireIntegrationAuthorizationAuth({ - acceptedRoles: [ADMIN, MEMBER] + acceptedRoles: [ADMIN, MEMBER], }), - param('integrationAuthId').exists().isString(), - query('appId').exists().isString(), + param("integrationAuthId").exists().isString(), + query("appId").exists().isString(), validateRequest, integrationAuthController.getIntegrationAuthRailwayEnvironments ); router.get( - '/:integrationAuthId/railway/services', + "/:integrationAuthId/railway/services", requireAuth({ - acceptedAuthModes: ['jwt'] + acceptedAuthModes: ["jwt"], }), requireIntegrationAuthorizationAuth({ - acceptedRoles: [ADMIN, MEMBER] + acceptedRoles: [ADMIN, MEMBER], }), - param('integrationAuthId').exists().isString(), - query('appId').exists().isString(), + param("integrationAuthId").exists().isString(), + query("appId").exists().isString(), validateRequest, integrationAuthController.getIntegrationAuthRailwayServices ); router.delete( - '/:integrationAuthId', + "/:integrationAuthId", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireIntegrationAuthorizationAuth({ acceptedRoles: [ADMIN, MEMBER], - attachAccessToken: false + attachAccessToken: false, }), - param('integrationAuthId'), + param("integrationAuthId"), validateRequest, integrationAuthController.deleteIntegrationAuth ); diff --git a/backend/src/routes/v1/inviteOrg.ts b/backend/src/routes/v1/inviteOrg.ts index 9b4889bc93..edcb34c870 100644 --- a/backend/src/routes/v1/inviteOrg.ts +++ b/backend/src/routes/v1/inviteOrg.ts @@ -1,26 +1,26 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); -import { body } from 'express-validator'; -import { requireAuth, validateRequest } from '../../middleware'; -import { membershipOrgController } from '../../controllers/v1'; -import { AUTH_MODE_JWT } from '../../variables'; +import { body } from "express-validator"; +import { requireAuth, validateRequest } from "../../middleware"; +import { membershipOrgController } from "../../controllers/v1"; +import { AUTH_MODE_JWT } from "../../variables"; router.post( - '/signup', + "/signup", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), - body('inviteeEmail').exists().trim().notEmpty().isEmail(), - body('organizationId').exists().trim().notEmpty(), + body("inviteeEmail").exists().trim().notEmpty().isEmail(), + body("organizationId").exists().trim().notEmpty(), validateRequest, membershipOrgController.inviteUserToOrganization ); router.post( - '/verify', - body('email').exists().trim().notEmpty(), - body('organizationId').exists().trim().notEmpty(), - body('code').exists().trim().notEmpty(), + "/verify", + body("email").exists().trim().notEmpty(), + body("organizationId").exists().trim().notEmpty(), + body("code").exists().trim().notEmpty(), validateRequest, membershipOrgController.verifyUserToOrganization ); diff --git a/backend/src/routes/v1/key.ts b/backend/src/routes/v1/key.ts index be99c9c172..fbd6e3eca4 100644 --- a/backend/src/routes/v1/key.ts +++ b/backend/src/routes/v1/key.ts @@ -1,39 +1,39 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); import { requireAuth, requireWorkspaceAuth, - validateRequest -} from '../../middleware'; -import { body, param } from 'express-validator'; -import { ADMIN, MEMBER, AUTH_MODE_JWT } from '../../variables'; -import { keyController } from '../../controllers/v1'; + validateRequest, +} from "../../middleware"; +import { body, param } from "express-validator"; +import { ADMIN, AUTH_MODE_JWT, MEMBER } from "../../variables"; +import { keyController } from "../../controllers/v1"; router.post( - '/:workspaceId', + "/:workspaceId", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - param('workspaceId').exists().trim(), - body('key').exists(), + param("workspaceId").exists().trim(), + body("key").exists(), validateRequest, keyController.uploadKey ); router.get( - '/:workspaceId/latest', + "/:workspaceId/latest", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - param('workspaceId'), + param("workspaceId"), validateRequest, keyController.getLatestKey ); diff --git a/backend/src/routes/v1/membership.ts b/backend/src/routes/v1/membership.ts index e830bd06d0..4282137686 100644 --- a/backend/src/routes/v1/membership.ts +++ b/backend/src/routes/v1/membership.ts @@ -1,50 +1,50 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); -import { body, param } from 'express-validator'; -import { requireAuth, validateRequest } from '../../middleware'; -import { membershipController } from '../../controllers/v1'; -import { membershipController as EEMembershipControllers } from '../../ee/controllers/v1'; -import { AUTH_MODE_JWT } from '../../variables'; +import { body, param } from "express-validator"; +import { requireAuth, validateRequest } from "../../middleware"; +import { membershipController } from "../../controllers/v1"; +import { membershipController as EEMembershipControllers } from "../../ee/controllers/v1"; +import { AUTH_MODE_JWT } from "../../variables"; // note: ALL DEPRECIATED (moved to api/v2/workspace/:workspaceId/memberships/:membershipId) router.get( // used for old CLI (deprecate) - '/:workspaceId/connect', + "/:workspaceId/connect", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), - param('workspaceId').exists().trim(), + param("workspaceId").exists().trim(), validateRequest, membershipController.validateMembership ); router.delete( - '/:membershipId', + "/:membershipId", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), - param('membershipId').exists().trim(), + param("membershipId").exists().trim(), validateRequest, membershipController.deleteMembership ); router.post( - '/:membershipId/change-role', + "/:membershipId/change-role", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), - body('role').exists().trim(), + body("role").exists().trim(), validateRequest, membershipController.changeMembershipRole ); router.post( - '/:membershipId/deny-permissions', + "/:membershipId/deny-permissions", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), - param('membershipId').isMongoId().exists().trim(), - body('permissions').isArray().exists(), + param("membershipId").isMongoId().exists().trim(), + body("permissions").isArray().exists(), validateRequest, EEMembershipControllers.denyMembershipPermissions ); diff --git a/backend/src/routes/v1/membershipOrg.ts b/backend/src/routes/v1/membershipOrg.ts index 2863c53fbb..6b3c7d2e85 100644 --- a/backend/src/routes/v1/membershipOrg.ts +++ b/backend/src/routes/v1/membershipOrg.ts @@ -1,27 +1,27 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); -import { param } from 'express-validator'; -import { requireAuth, validateRequest } from '../../middleware'; -import { membershipOrgController } from '../../controllers/v1'; -import { AUTH_MODE_JWT } from '../../variables'; +import { param } from "express-validator"; +import { requireAuth, validateRequest } from "../../middleware"; +import { membershipOrgController } from "../../controllers/v1"; +import { AUTH_MODE_JWT } from "../../variables"; router.post( // TODO - '/membershipOrg/:membershipOrgId/change-role', + "/membershipOrg/:membershipOrgId/change-role", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), - param('membershipOrgId'), + param("membershipOrgId"), validateRequest, membershipOrgController.changeMembershipOrgRole ); router.delete( - '/:membershipOrgId', + "/:membershipOrgId", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), - param('membershipOrgId').exists().trim(), + param("membershipOrgId").exists().trim(), validateRequest, membershipOrgController.deleteMembershipOrg ); diff --git a/backend/src/routes/v1/organization.ts b/backend/src/routes/v1/organization.ts index dded53f3a3..7cfd0e3fa2 100644 --- a/backend/src/routes/v1/organization.ts +++ b/backend/src/routes/v1/organization.ts @@ -1,177 +1,177 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); -import { body, param } from 'express-validator'; +import { body, param } from "express-validator"; import { requireAuth, requireOrganizationAuth, - validateRequest -} from '../../middleware'; + validateRequest, +} from "../../middleware"; import { - OWNER, + ACCEPTED, ADMIN, - MEMBER, - ACCEPTED, - AUTH_MODE_JWT -} from '../../variables'; -import { organizationController } from '../../controllers/v1'; + AUTH_MODE_JWT, + MEMBER, + OWNER, +} from "../../variables"; +import { organizationController } from "../../controllers/v1"; router.get( // deprecated (moved to api/v2/users/me/organizations) - '/', + "/", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), organizationController.getOrganizations ); router.post( // not used on frontend - '/', + "/", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), - body('organizationName').exists().trim().notEmpty(), + body("organizationName").exists().trim().notEmpty(), validateRequest, organizationController.createOrganization ); router.get( - '/:organizationId', + "/:organizationId", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireOrganizationAuth({ acceptedRoles: [OWNER, ADMIN, MEMBER], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), - param('organizationId').exists().trim(), + param("organizationId").exists().trim(), validateRequest, organizationController.getOrganization ); router.get( // deprecated (moved to api/v2/organizations/:organizationId/memberships) - '/:organizationId/users', + "/:organizationId/users", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireOrganizationAuth({ acceptedRoles: [OWNER, ADMIN, MEMBER], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), - param('organizationId').exists().trim(), + param("organizationId").exists().trim(), validateRequest, organizationController.getOrganizationMembers ); router.get( - '/:organizationId/my-workspaces', // deprecated (moved to api/v2/organizations/:organizationId/workspaces) + "/:organizationId/my-workspaces", // deprecated (moved to api/v2/organizations/:organizationId/workspaces) requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireOrganizationAuth({ acceptedRoles: [OWNER, ADMIN, MEMBER], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), - param('organizationId').exists().trim(), + param("organizationId").exists().trim(), validateRequest, organizationController.getOrganizationWorkspaces ); router.patch( - '/:organizationId/name', + "/:organizationId/name", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireOrganizationAuth({ acceptedRoles: [OWNER, ADMIN, MEMBER], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), - param('organizationId').exists().trim(), - body('name').exists().trim().notEmpty(), + param("organizationId").exists().trim(), + body("name").exists().trim().notEmpty(), validateRequest, organizationController.changeOrganizationName ); router.get( - '/:organizationId/incidentContactOrg', + "/:organizationId/incidentContactOrg", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireOrganizationAuth({ acceptedRoles: [OWNER, ADMIN, MEMBER], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), - param('organizationId').exists().trim(), + param("organizationId").exists().trim(), validateRequest, organizationController.getOrganizationIncidentContacts ); router.post( - '/:organizationId/incidentContactOrg', + "/:organizationId/incidentContactOrg", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireOrganizationAuth({ acceptedRoles: [OWNER, ADMIN, MEMBER], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), - param('organizationId').exists().trim(), - body('email').exists().trim().notEmpty(), + param("organizationId").exists().trim(), + body("email").exists().trim().notEmpty(), validateRequest, organizationController.addOrganizationIncidentContact ); router.delete( - '/:organizationId/incidentContactOrg', + "/:organizationId/incidentContactOrg", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireOrganizationAuth({ acceptedRoles: [OWNER, ADMIN, MEMBER], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), - param('organizationId').exists().trim(), - body('email').exists().trim().notEmpty(), + param("organizationId").exists().trim(), + body("email").exists().trim().notEmpty(), validateRequest, organizationController.deleteOrganizationIncidentContact ); router.post( - '/:organizationId/customer-portal-session', + "/:organizationId/customer-portal-session", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireOrganizationAuth({ acceptedRoles: [OWNER, ADMIN, MEMBER], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), - param('organizationId').exists().trim(), + param("organizationId").exists().trim(), validateRequest, organizationController.createOrganizationPortalSession ); router.get( - '/:organizationId/subscriptions', + "/:organizationId/subscriptions", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireOrganizationAuth({ acceptedRoles: [OWNER, ADMIN, MEMBER], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), - param('organizationId').exists().trim(), + param("organizationId").exists().trim(), validateRequest, organizationController.getOrganizationSubscriptions ); router.get( - '/:organizationId/workspace-memberships', + "/:organizationId/workspace-memberships", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireOrganizationAuth({ acceptedRoles: [OWNER, ADMIN, MEMBER], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), - param('organizationId').exists().trim(), + param("organizationId").exists().trim(), validateRequest, organizationController.getOrganizationMembersAndTheirWorkspaces ); diff --git a/backend/src/routes/v1/password.ts b/backend/src/routes/v1/password.ts index b04fa36af3..7268b1a3cd 100644 --- a/backend/src/routes/v1/password.ts +++ b/backend/src/routes/v1/password.ts @@ -1,93 +1,93 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); -import { body } from 'express-validator'; -import { requireAuth, requireSignupAuth, validateRequest } from '../../middleware'; -import { passwordController } from '../../controllers/v1'; -import { passwordLimiter } from '../../helpers/rateLimiter'; +import { body } from "express-validator"; +import { requireAuth, requireSignupAuth, validateRequest } from "../../middleware"; +import { passwordController } from "../../controllers/v1"; +import { passwordLimiter } from "../../helpers/rateLimiter"; import { - AUTH_MODE_JWT -} from '../../variables'; + AUTH_MODE_JWT, +} from "../../variables"; router.post( - '/srp1', + "/srp1", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), - body('clientPublicKey').exists().isString().trim().notEmpty(), + body("clientPublicKey").exists().isString().trim().notEmpty(), validateRequest, passwordController.srp1 ); router.post( - '/change-password', + "/change-password", passwordLimiter, requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), - body('clientProof').exists().trim().notEmpty(), - body('protectedKey').exists().isString().trim().notEmpty(), - body('protectedKeyIV').exists().isString().trim().notEmpty(), - body('protectedKeyTag').exists().isString().trim().notEmpty(), - body('encryptedPrivateKey').exists().isString().trim().notEmpty(), // private key encrypted under new pwd - body('encryptedPrivateKeyIV').exists().isString().trim().notEmpty(), // new iv for private key - body('encryptedPrivateKeyTag').exists().isString().trim().notEmpty(), // new tag for private key - body('salt').exists().isString().trim().notEmpty(), // part of new pwd - body('verifier').exists().isString().trim().notEmpty(), // part of new pwd + body("clientProof").exists().trim().notEmpty(), + body("protectedKey").exists().isString().trim().notEmpty(), + body("protectedKeyIV").exists().isString().trim().notEmpty(), + body("protectedKeyTag").exists().isString().trim().notEmpty(), + body("encryptedPrivateKey").exists().isString().trim().notEmpty(), // private key encrypted under new pwd + body("encryptedPrivateKeyIV").exists().isString().trim().notEmpty(), // new iv for private key + body("encryptedPrivateKeyTag").exists().isString().trim().notEmpty(), // new tag for private key + body("salt").exists().isString().trim().notEmpty(), // part of new pwd + body("verifier").exists().isString().trim().notEmpty(), // part of new pwd validateRequest, passwordController.changePassword ); router.post( - '/email/password-reset', + "/email/password-reset", passwordLimiter, - body('email').exists().isString().trim().notEmpty().isEmail(), + body("email").exists().isString().trim().notEmpty().isEmail(), validateRequest, passwordController.emailPasswordReset ); router.post( - '/email/password-reset-verify', + "/email/password-reset-verify", passwordLimiter, - body('email').exists().isString().trim().notEmpty().isEmail(), - body('code').exists().isString().trim().notEmpty(), + body("email").exists().isString().trim().notEmpty().isEmail(), + body("code").exists().isString().trim().notEmpty(), validateRequest, passwordController.emailPasswordResetVerify ); router.get( - '/backup-private-key', + "/backup-private-key", passwordLimiter, requireSignupAuth, passwordController.getBackupPrivateKey ); router.post( - '/backup-private-key', + "/backup-private-key", passwordLimiter, requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), - body('clientProof').exists().isString().trim().notEmpty(), - body('encryptedPrivateKey').exists().isString().trim().notEmpty(), // (backup) private key encrypted under a strong key - body('iv').exists().isString().trim().notEmpty(), // new iv for (backup) private key - body('tag').exists().isString().trim().notEmpty(), // new tag for (backup) private key - body('salt').exists().isString().trim().notEmpty(), // salt generated from strong key - body('verifier').exists().isString().trim().notEmpty(), // salt generated from strong key + body("clientProof").exists().isString().trim().notEmpty(), + body("encryptedPrivateKey").exists().isString().trim().notEmpty(), // (backup) private key encrypted under a strong key + body("iv").exists().isString().trim().notEmpty(), // new iv for (backup) private key + body("tag").exists().isString().trim().notEmpty(), // new tag for (backup) private key + body("salt").exists().isString().trim().notEmpty(), // salt generated from strong key + body("verifier").exists().isString().trim().notEmpty(), // salt generated from strong key validateRequest, passwordController.createBackupPrivateKey ); router.post( - '/password-reset', + "/password-reset", requireSignupAuth, - body('protectedKey').exists().isString().trim().notEmpty(), - body('protectedKeyIV').exists().isString().trim().notEmpty(), - body('protectedKeyTag').exists().isString().trim().notEmpty(), - body('encryptedPrivateKey').exists().isString().trim().notEmpty(), // private key encrypted under new pwd - body('encryptedPrivateKeyIV').exists().isString().trim().notEmpty(), // new iv for private key - body('encryptedPrivateKeyTag').exists().isString().trim().notEmpty(), // new tag for private key - body('salt').exists().isString().trim().notEmpty(), // part of new pwd - body('verifier').exists().isString().trim().notEmpty(), // part of new pwd + body("protectedKey").exists().isString().trim().notEmpty(), + body("protectedKeyIV").exists().isString().trim().notEmpty(), + body("protectedKeyTag").exists().isString().trim().notEmpty(), + body("encryptedPrivateKey").exists().isString().trim().notEmpty(), // private key encrypted under new pwd + body("encryptedPrivateKeyIV").exists().isString().trim().notEmpty(), // new iv for private key + body("encryptedPrivateKeyTag").exists().isString().trim().notEmpty(), // new tag for private key + body("salt").exists().isString().trim().notEmpty(), // part of new pwd + body("verifier").exists().isString().trim().notEmpty(), // part of new pwd validateRequest, passwordController.resetPassword ); diff --git a/backend/src/routes/v1/secret.ts b/backend/src/routes/v1/secret.ts index e55dfaf43f..89ed3c975c 100644 --- a/backend/src/routes/v1/secret.ts +++ b/backend/src/routes/v1/secret.ts @@ -1,61 +1,61 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); import { requireAuth, - requireWorkspaceAuth, requireServiceTokenAuth, - validateRequest -} from '../../middleware'; -import { body, query, param } from 'express-validator'; -import { secretController } from '../../controllers/v1'; + requireWorkspaceAuth, + validateRequest, +} from "../../middleware"; +import { body, param, query } from "express-validator"; +import { secretController } from "../../controllers/v1"; import { ADMIN, + AUTH_MODE_JWT, MEMBER, - AUTH_MODE_JWT -} from '../../variables'; +} from "../../variables"; // note to devs: these endpoints will be deprecated in favor of v2 router.post( - '/:workspaceId', + "/:workspaceId", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - body('secrets').exists(), - body('keys').exists(), - body('environment').exists().trim().notEmpty(), - body('channel'), - param('workspaceId').exists().trim(), + body("secrets").exists(), + body("keys").exists(), + body("environment").exists().trim().notEmpty(), + body("channel"), + param("workspaceId").exists().trim(), validateRequest, secretController.pushSecrets ); router.get( - '/:workspaceId', + "/:workspaceId", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - query('environment').exists().trim(), - query('channel'), - param('workspaceId').exists().trim(), + query("environment").exists().trim(), + query("channel"), + param("workspaceId").exists().trim(), validateRequest, secretController.pullSecrets ); router.get( - '/:workspaceId/service-token', + "/:workspaceId/service-token", requireServiceTokenAuth, - query('environment').exists().trim(), - query('channel'), - param('workspaceId').exists().trim(), + query("environment").exists().trim(), + query("channel"), + param("workspaceId").exists().trim(), validateRequest, secretController.pullSecretsServiceToken ); diff --git a/backend/src/routes/v1/serviceToken.ts b/backend/src/routes/v1/serviceToken.ts index 2b75e7cbfa..b3f3abb705 100644 --- a/backend/src/routes/v1/serviceToken.ts +++ b/backend/src/routes/v1/serviceToken.ts @@ -1,43 +1,43 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); import { requireAuth, - requireWorkspaceAuth, requireServiceTokenAuth, - validateRequest -} from '../../middleware'; -import { body } from 'express-validator'; + requireWorkspaceAuth, + validateRequest, +} from "../../middleware"; +import { body } from "express-validator"; import { ADMIN, + AUTH_MODE_JWT, MEMBER, - AUTH_MODE_JWT -} from '../../variables'; -import { serviceTokenController } from '../../controllers/v1'; +} from "../../variables"; +import { serviceTokenController } from "../../controllers/v1"; // note: deprecate service-token routes in favor of service-token data routes/structure router.get( - '/', + "/", requireServiceTokenAuth, serviceTokenController.getServiceToken ); router.post( - '/', + "/", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'body' + locationWorkspaceId: "body", }), - body('name').exists().trim().notEmpty(), - body('workspaceId').exists().trim().notEmpty(), - body('environment').exists().trim().notEmpty(), - body('expiresIn'), // measured in ms - body('publicKey').exists().trim().notEmpty(), - body('encryptedKey').exists().trim().notEmpty(), - body('nonce').exists().trim().notEmpty(), + body("name").exists().trim().notEmpty(), + body("workspaceId").exists().trim().notEmpty(), + body("environment").exists().trim().notEmpty(), + body("expiresIn"), // measured in ms + body("publicKey").exists().trim().notEmpty(), + body("encryptedKey").exists().trim().notEmpty(), + body("nonce").exists().trim().notEmpty(), validateRequest, serviceTokenController.createServiceToken ); diff --git a/backend/src/routes/v1/signup.ts b/backend/src/routes/v1/signup.ts index 35a043c8e0..1b82edd3a2 100644 --- a/backend/src/routes/v1/signup.ts +++ b/backend/src/routes/v1/signup.ts @@ -1,23 +1,23 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); -import { body } from 'express-validator'; -import { validateRequest } from '../../middleware'; -import { signupController } from '../../controllers/v1'; -import { authLimiter } from '../../helpers/rateLimiter'; +import { body } from "express-validator"; +import { validateRequest } from "../../middleware"; +import { signupController } from "../../controllers/v1"; +import { authLimiter } from "../../helpers/rateLimiter"; router.post( - '/email/signup', + "/email/signup", authLimiter, - body('email').exists().trim().notEmpty().isEmail(), + body("email").exists().trim().notEmpty().isEmail(), validateRequest, signupController.beginEmailSignup ); router.post( - '/email/verify', + "/email/verify", authLimiter, - body('email').exists().trim().notEmpty().isEmail(), - body('code').exists().trim().notEmpty(), + body("email").exists().trim().notEmpty().isEmail(), + body("code").exists().trim().notEmpty(), validateRequest, signupController.verifyEmailSignup ); diff --git a/backend/src/routes/v1/stripe.ts b/backend/src/routes/v1/stripe.ts index cfcca77cb1..d4ba1255d9 100644 --- a/backend/src/routes/v1/stripe.ts +++ b/backend/src/routes/v1/stripe.ts @@ -1,7 +1,7 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); -import { stripeController } from '../../controllers/v1'; +import { stripeController } from "../../controllers/v1"; -router.post('/webhook', stripeController.handleWebhook); +router.post("/webhook", stripeController.handleWebhook); export default router; diff --git a/backend/src/routes/v1/user.ts b/backend/src/routes/v1/user.ts index b9d88dfb12..d499a23773 100644 --- a/backend/src/routes/v1/user.ts +++ b/backend/src/routes/v1/user.ts @@ -1,15 +1,15 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); -import { requireAuth } from '../../middleware'; -import { userController } from '../../controllers/v1'; +import { requireAuth } from "../../middleware"; +import { userController } from "../../controllers/v1"; import { - AUTH_MODE_JWT -} from '../../variables'; + AUTH_MODE_JWT, +} from "../../variables"; router.get( - '/', + "/", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), userController.getUser ); diff --git a/backend/src/routes/v1/userAction.ts b/backend/src/routes/v1/userAction.ts index c8d21f918c..29cc811bdb 100644 --- a/backend/src/routes/v1/userAction.ts +++ b/backend/src/routes/v1/userAction.ts @@ -1,27 +1,27 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); -import { requireAuth, validateRequest } from '../../middleware'; -import { body, query } from 'express-validator'; -import { userActionController } from '../../controllers/v1'; -import { AUTH_MODE_JWT } from '../../variables'; +import { requireAuth, validateRequest } from "../../middleware"; +import { body, query } from "express-validator"; +import { userActionController } from "../../controllers/v1"; +import { AUTH_MODE_JWT } from "../../variables"; // note: [userAction] will be deprecated in /v2 in favor of [action] router.post( - '/', + "/", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), - body('action'), + body("action"), validateRequest, userActionController.addUserAction ); router.get( - '/', + "/", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), - query('action'), + query("action"), validateRequest, userActionController.getUserAction ); diff --git a/backend/src/routes/v1/workspace.ts b/backend/src/routes/v1/workspace.ts index 431a2e4f95..8b696d4aca 100644 --- a/backend/src/routes/v1/workspace.ts +++ b/backend/src/routes/v1/workspace.ts @@ -1,161 +1,161 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); -import { body, param, query } from 'express-validator'; +import { body, param } from "express-validator"; import { requireAuth, requireWorkspaceAuth, - validateRequest -} from '../../middleware'; + validateRequest, +} from "../../middleware"; import { ADMIN, + AUTH_MODE_JWT, MEMBER, - AUTH_MODE_JWT -} from '../../variables'; -import { workspaceController, membershipController } from '../../controllers/v1'; +} from "../../variables"; +import { membershipController, workspaceController } from "../../controllers/v1"; router.get( - '/:workspaceId/keys', + "/:workspaceId/keys", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - param('workspaceId').exists().trim(), + param("workspaceId").exists().trim(), validateRequest, workspaceController.getWorkspacePublicKeys ); router.get( - '/:workspaceId/users', + "/:workspaceId/users", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - param('workspaceId').exists().trim(), + param("workspaceId").exists().trim(), validateRequest, workspaceController.getWorkspaceMemberships ); router.get( - '/', + "/", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), workspaceController.getWorkspaces ); router.get( - '/:workspaceId', + "/:workspaceId", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - param('workspaceId').exists().trim(), + param("workspaceId").exists().trim(), validateRequest, workspaceController.getWorkspace ); router.post( - '/', + "/", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), - body('workspaceName').exists().trim().notEmpty(), - body('organizationId').exists().trim().notEmpty(), + body("workspaceName").exists().trim().notEmpty(), + body("organizationId").exists().trim().notEmpty(), validateRequest, workspaceController.createWorkspace ); router.delete( - '/:workspaceId', + "/:workspaceId", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - param('workspaceId').exists().trim(), + param("workspaceId").exists().trim(), validateRequest, workspaceController.deleteWorkspace ); router.post( - '/:workspaceId/name', + "/:workspaceId/name", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - param('workspaceId').exists().trim(), - body('name').exists().trim().notEmpty(), + param("workspaceId").exists().trim(), + body("name").exists().trim().notEmpty(), validateRequest, workspaceController.changeWorkspaceName ); router.post( - '/:workspaceId/invite-signup', + "/:workspaceId/invite-signup", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - param('workspaceId').exists().trim(), - body('email').exists().trim().notEmpty(), + param("workspaceId").exists().trim(), + body("email").exists().trim().notEmpty(), validateRequest, membershipController.inviteUserToWorkspace ); router.get( - '/:workspaceId/integrations', + "/:workspaceId/integrations", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - param('workspaceId').exists().trim(), + param("workspaceId").exists().trim(), validateRequest, workspaceController.getWorkspaceIntegrations ); router.get( - '/:workspaceId/authorizations', + "/:workspaceId/authorizations", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - param('workspaceId').exists().trim(), + param("workspaceId").exists().trim(), validateRequest, workspaceController.getWorkspaceIntegrationAuthorizations ); router.get( - '/:workspaceId/service-tokens', // deprecate + "/:workspaceId/service-tokens", // deprecate requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - param('workspaceId').exists().trim(), + param("workspaceId").exists().trim(), validateRequest, workspaceController.getWorkspaceServiceTokens ); diff --git a/backend/src/routes/v2/apiKeyData.ts b/backend/src/routes/v2/apiKeyData.ts index 939bdbe1f0..eae8d7ddda 100644 --- a/backend/src/routes/v2/apiKeyData.ts +++ b/backend/src/routes/v2/apiKeyData.ts @@ -1,40 +1,40 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); -import { param, body } from 'express-validator'; +import { body, param } from "express-validator"; import { requireAuth, - validateRequest -} from '../../middleware'; -import { apiKeyDataController } from '../../controllers/v2'; + validateRequest, +} from "../../middleware"; +import { apiKeyDataController } from "../../controllers/v2"; import { - AUTH_MODE_JWT -} from '../../variables'; + AUTH_MODE_JWT, +} from "../../variables"; router.get( - '/', + "/", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), apiKeyDataController.getAPIKeyData ); router.post( - '/', + "/", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), - body('name').exists().trim(), - body('expiresIn'), // measured in ms + body("name").exists().trim(), + body("expiresIn"), // measured in ms validateRequest, apiKeyDataController.createAPIKeyData ); router.delete( - '/:apiKeyDataId', + "/:apiKeyDataId", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), - param('apiKeyDataId').exists().trim(), + param("apiKeyDataId").exists().trim(), validateRequest, apiKeyDataController.deleteAPIKeyData ); diff --git a/backend/src/routes/v2/auth.ts b/backend/src/routes/v2/auth.ts index 288004e657..444819f271 100644 --- a/backend/src/routes/v2/auth.ts +++ b/backend/src/routes/v2/auth.ts @@ -1,42 +1,42 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); -import { body } from 'express-validator'; -import { requireMfaAuth, validateRequest } from '../../middleware'; -import { authController } from '../../controllers/v2'; -import { authLimiter } from '../../helpers/rateLimiter'; +import { body } from "express-validator"; +import { requireMfaAuth, validateRequest } from "../../middleware"; +import { authController } from "../../controllers/v2"; +import { authLimiter } from "../../helpers/rateLimiter"; router.post( - '/login1', + "/login1", authLimiter, - body('email').isString().trim().notEmpty(), - body('clientPublicKey').isString().trim().notEmpty(), + body("email").isString().trim().notEmpty(), + body("clientPublicKey").isString().trim().notEmpty(), validateRequest, authController.login1 ); router.post( - '/login2', + "/login2", authLimiter, - body('email').isString().trim().notEmpty(), - body('clientProof').isString().trim().notEmpty(), + body("email").isString().trim().notEmpty(), + body("clientProof").isString().trim().notEmpty(), validateRequest, authController.login2 ); router.post( - '/mfa/send', + "/mfa/send", authLimiter, - body('email').isString().trim().notEmpty().isEmail(), + body("email").isString().trim().notEmpty().isEmail(), validateRequest, authController.sendMfaToken ); router.post( - '/mfa/verify', + "/mfa/verify", authLimiter, requireMfaAuth, - body('email').isString().trim().notEmpty(), - body('mfaToken').isString().trim().notEmpty(), + body("email").isString().trim().notEmpty(), + body("mfaToken").isString().trim().notEmpty(), validateRequest, authController.verifyMfaToken ); diff --git a/backend/src/routes/v2/environment.ts b/backend/src/routes/v2/environment.ts index 0eb4b4a204..f9943f33da 100644 --- a/backend/src/routes/v2/environment.ts +++ b/backend/src/routes/v2/environment.ts @@ -1,76 +1,76 @@ -import express, { Response, Request } from 'express'; +import express from "express"; const router = express.Router(); -import { body, param } from 'express-validator'; -import { environmentController } from '../../controllers/v2'; +import { body, param } from "express-validator"; +import { environmentController } from "../../controllers/v2"; import { requireAuth, requireWorkspaceAuth, validateRequest, -} from '../../middleware'; +} from "../../middleware"; import { ADMIN, + AUTH_MODE_JWT, MEMBER, - AUTH_MODE_JWT -} from '../../variables'; +} from "../../variables"; router.post( - '/:workspaceId/environments', + "/:workspaceId/environments", requireAuth({ acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - param('workspaceId').exists().trim(), - body('environmentSlug').exists().trim(), - body('environmentName').exists().trim(), + param("workspaceId").exists().trim(), + body("environmentSlug").exists().trim(), + body("environmentName").exists().trim(), validateRequest, environmentController.createWorkspaceEnvironment ); router.put( - '/:workspaceId/environments', + "/:workspaceId/environments", requireAuth({ acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - param('workspaceId').exists().trim(), - body('environmentSlug').exists().trim(), - body('environmentName').exists().trim(), - body('oldEnvironmentSlug').exists().trim(), + param("workspaceId").exists().trim(), + body("environmentSlug").exists().trim(), + body("environmentName").exists().trim(), + body("oldEnvironmentSlug").exists().trim(), validateRequest, environmentController.renameWorkspaceEnvironment ); router.delete( - '/:workspaceId/environments', + "/:workspaceId/environments", requireAuth({ acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - param('workspaceId').exists().trim(), - body('environmentSlug').exists().trim(), + param("workspaceId").exists().trim(), + body("environmentSlug").exists().trim(), validateRequest, environmentController.deleteWorkspaceEnvironment ); router.get( - '/:workspaceId/environments', + "/:workspaceId/environments", requireAuth({ acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [MEMBER, ADMIN], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - param('workspaceId').exists().trim(), + param("workspaceId").exists().trim(), validateRequest, environmentController.getAllAccessibleEnvironmentsOfWorkspace ); diff --git a/backend/src/routes/v2/index.ts b/backend/src/routes/v2/index.ts index c088771eb0..fc73537296 100644 --- a/backend/src/routes/v2/index.ts +++ b/backend/src/routes/v2/index.ts @@ -1,13 +1,13 @@ -import auth from './auth'; -import signup from './signup'; -import users from './users'; -import organizations from './organizations'; -import workspace from './workspace'; -import secret from './secret'; // deprecated -import secrets from './secrets'; -import serviceTokenData from './serviceTokenData'; -import serviceAccounts from './serviceAccounts'; -import apiKeyData from './apiKeyData'; +import auth from "./auth"; +import signup from "./signup"; +import users from "./users"; +import organizations from "./organizations"; +import workspace from "./workspace"; +import secret from "./secret"; // deprecated +import secrets from "./secrets"; +import serviceTokenData from "./serviceTokenData"; +import serviceAccounts from "./serviceAccounts"; +import apiKeyData from "./apiKeyData"; import environment from "./environment" import tags from "./tags" @@ -23,5 +23,5 @@ export { serviceAccounts, apiKeyData, environment, - tags + tags, } \ No newline at end of file diff --git a/backend/src/routes/v2/organizations.ts b/backend/src/routes/v2/organizations.ts index eb2cef8eb9..46223cf93f 100644 --- a/backend/src/routes/v2/organizations.ts +++ b/backend/src/routes/v2/organizations.ts @@ -1,101 +1,101 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); import { requireAuth, - requireOrganizationAuth, requireMembershipOrgAuth, - validateRequest -} from '../../middleware'; -import { body, param } from 'express-validator'; + requireOrganizationAuth, + validateRequest, +} from "../../middleware"; +import { body, param } from "express-validator"; import { - OWNER, + ACCEPTED, ADMIN, - MEMBER, - ACCEPTED, + AUTH_MODE_API_KEY, AUTH_MODE_JWT, - AUTH_MODE_API_KEY -} from '../../variables'; -import { organizationsController } from '../../controllers/v2'; + MEMBER, + OWNER, +} from "../../variables"; +import { organizationsController } from "../../controllers/v2"; // TODO: /POST to create membership router.get( - '/:organizationId/memberships', - param('organizationId').exists().trim(), + "/:organizationId/memberships", + param("organizationId").exists().trim(), validateRequest, requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY] + acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY], }), requireOrganizationAuth({ acceptedRoles: [OWNER, ADMIN, MEMBER], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), organizationsController.getOrganizationMemberships ); router.patch( - '/:organizationId/memberships/:membershipId', - param('organizationId').exists().trim(), - param('membershipId').exists().trim(), - body('role').exists().isString().trim().isIn([OWNER, ADMIN, MEMBER]), + "/:organizationId/memberships/:membershipId", + param("organizationId").exists().trim(), + param("membershipId").exists().trim(), + body("role").exists().isString().trim().isIn([OWNER, ADMIN, MEMBER]), validateRequest, requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY] + acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY], }), requireOrganizationAuth({ acceptedRoles: [OWNER, ADMIN], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), requireMembershipOrgAuth({ acceptedRoles: [OWNER, ADMIN], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), organizationsController.updateOrganizationMembership ); router.delete( - '/:organizationId/memberships/:membershipId', - param('organizationId').exists().trim(), - param('membershipId').exists().trim(), + "/:organizationId/memberships/:membershipId", + param("organizationId").exists().trim(), + param("membershipId").exists().trim(), validateRequest, requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY] + acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY], }), requireOrganizationAuth({ acceptedRoles: [OWNER, ADMIN], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), requireMembershipOrgAuth({ acceptedRoles: [OWNER, ADMIN], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), organizationsController.deleteOrganizationMembership ); router.get( - '/:organizationId/workspaces', - param('organizationId').exists().trim(), + "/:organizationId/workspaces", + param("organizationId").exists().trim(), validateRequest, requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY] + acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY], }), requireOrganizationAuth({ acceptedRoles: [OWNER, ADMIN], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), organizationsController.getOrganizationWorkspaces ); router.get( - '/:organizationId/service-accounts', - param('organizationId').exists().trim(), + "/:organizationId/service-accounts", + param("organizationId").exists().trim(), validateRequest, requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireOrganizationAuth({ acceptedRoles: [OWNER, ADMIN], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), organizationsController.getOrganizationServiceAccounts ); diff --git a/backend/src/routes/v2/secret.ts b/backend/src/routes/v2/secret.ts index f2c825ba80..e577d2a477 100644 --- a/backend/src/routes/v2/secret.ts +++ b/backend/src/routes/v2/secret.ts @@ -1,146 +1,146 @@ -import express from 'express'; +import express from "express"; import { requireAuth, - requireWorkspaceAuth, requireSecretAuth, - validateRequest -} from '../../middleware'; -import { body, param, query } from 'express-validator'; + requireWorkspaceAuth, + validateRequest, +} from "../../middleware"; +import { body, param, query } from "express-validator"; import { ADMIN, - MEMBER, AUTH_MODE_JWT, AUTH_MODE_SERVICE_TOKEN, + MEMBER, PERMISSION_READ_SECRETS, - PERMISSION_WRITE_SECRETS -} from '../../variables'; -import { CreateSecretRequestBody, ModifySecretRequestBody } from '../../types/secret'; -import { secretController } from '../../controllers/v2'; + PERMISSION_WRITE_SECRETS, +} from "../../variables"; +import { CreateSecretRequestBody, ModifySecretRequestBody } from "../../types/secret"; +import { secretController } from "../../controllers/v2"; // note to devs: stop supporting these routes [deprecated] const router = express.Router(); router.post( - '/batch-create/workspace/:workspaceId/environment/:environment', + "/batch-create/workspace/:workspaceId/environment/:environment", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - param('workspaceId').exists().isMongoId().trim(), - param('environment').exists().trim(), - body('secrets').exists().isArray().custom((value) => value.every((item: CreateSecretRequestBody) => typeof item === 'object')), - body('channel'), + param("workspaceId").exists().isMongoId().trim(), + param("environment").exists().trim(), + body("secrets").exists().isArray().custom((value) => value.every((item: CreateSecretRequestBody) => typeof item === "object")), + body("channel"), validateRequest, secretController.createSecrets ); router.post( - '/workspace/:workspaceId/environment/:environment', + "/workspace/:workspaceId/environment/:environment", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - param('workspaceId').exists().isMongoId().trim(), - param('environment').exists().trim(), - body('secret').exists().isObject(), - body('channel'), + param("workspaceId").exists().isMongoId().trim(), + param("environment").exists().trim(), + body("secret").exists().isObject(), + body("channel"), validateRequest, secretController.createSecret ); router.get( - '/workspace/:workspaceId', - param('workspaceId').exists().trim(), + "/workspace/:workspaceId", + param("workspaceId").exists().trim(), query("environment").exists(), requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_SERVICE_TOKEN] + acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_SERVICE_TOKEN], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - query('channel'), + query("channel"), validateRequest, secretController.getSecrets ); router.get( - '/:secretId', + "/:secretId", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_SERVICE_TOKEN] + acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_SERVICE_TOKEN], }), requireSecretAuth({ acceptedRoles: [ADMIN, MEMBER], - requiredPermissions: [PERMISSION_READ_SECRETS] + requiredPermissions: [PERMISSION_READ_SECRETS], }), validateRequest, secretController.getSecret ); router.delete( - '/batch/workspace/:workspaceId/environment/:environmentName', + "/batch/workspace/:workspaceId/environment/:environmentName", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), - param('workspaceId').exists().isMongoId().trim(), - param('environmentName').exists().trim(), - body('secretIds').exists().isArray().custom(array => array.length > 0), + param("workspaceId").exists().isMongoId().trim(), + param("environmentName").exists().trim(), + body("secretIds").exists().isArray().custom(array => array.length > 0), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), validateRequest, secretController.deleteSecrets ); router.delete( - '/:secretId', + "/:secretId", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireSecretAuth({ acceptedRoles: [ADMIN, MEMBER], - requiredPermissions: [PERMISSION_READ_SECRETS, PERMISSION_WRITE_SECRETS] + requiredPermissions: [PERMISSION_READ_SECRETS, PERMISSION_WRITE_SECRETS], }), - param('secretId').isMongoId(), + param("secretId").isMongoId(), validateRequest, secretController.deleteSecret ); router.patch( - '/batch-modify/workspace/:workspaceId/environment/:environmentName', + "/batch-modify/workspace/:workspaceId/environment/:environmentName", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), - body('secrets').exists().isArray().custom((secrets: ModifySecretRequestBody[]) => secrets.length > 0), - param('workspaceId').exists().isMongoId().trim(), - param('environmentName').exists().trim(), + body("secrets").exists().isArray().custom((secrets: ModifySecretRequestBody[]) => secrets.length > 0), + param("workspaceId").exists().isMongoId().trim(), + param("environmentName").exists().trim(), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), validateRequest, secretController.updateSecrets ); router.patch( - '/workspace/:workspaceId/environment/:environmentName', + "/workspace/:workspaceId/environment/:environmentName", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), - body('secret').isObject(), - param('workspaceId').exists().isMongoId().trim(), - param('environmentName').exists().trim(), + body("secret").isObject(), + param("workspaceId").exists().isMongoId().trim(), + param("environmentName").exists().trim(), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), validateRequest, secretController.updateSecret diff --git a/backend/src/routes/v2/secrets.ts b/backend/src/routes/v2/secrets.ts index 3cf7e83d56..cd550d99e0 100644 --- a/backend/src/routes/v2/secrets.ts +++ b/backend/src/routes/v2/secrets.ts @@ -3,24 +3,24 @@ const router = express.Router(); import { Types } from "mongoose"; import { requireAuth, - requireWorkspaceAuth, requireSecretsAuth, + requireWorkspaceAuth, validateRequest, } from "../../middleware"; import { validateClientForSecrets } from "../../validation"; -import { query, body } from "express-validator"; +import { body, query } from "express-validator"; import { secretsController } from "../../controllers/v2"; import { ADMIN, - MEMBER, - SECRET_PERSONAL, - SECRET_SHARED, - PERMISSION_READ_SECRETS, - PERMISSION_WRITE_SECRETS, + AUTH_MODE_API_KEY, AUTH_MODE_JWT, AUTH_MODE_SERVICE_ACCOUNT, AUTH_MODE_SERVICE_TOKEN, - AUTH_MODE_API_KEY, + MEMBER, + PERMISSION_READ_SECRETS, + PERMISSION_WRITE_SECRETS, + SECRET_PERSONAL, + SECRET_SHARED, } from "../../variables"; import { BatchSecretRequest } from "../../types/secret"; diff --git a/backend/src/routes/v2/serviceAccounts.ts b/backend/src/routes/v2/serviceAccounts.ts index 6f0db91b73..244739e72f 100644 --- a/backend/src/routes/v2/serviceAccounts.ts +++ b/backend/src/routes/v2/serviceAccounts.ts @@ -1,157 +1,157 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); import { requireAuth, requireOrganizationAuth, - requireWorkspaceAuth, requireServiceAccountAuth, requireServiceAccountWorkspacePermissionAuth, - validateRequest -} from '../../middleware'; -import { param, query, body } from 'express-validator'; + requireWorkspaceAuth, + validateRequest, +} from "../../middleware"; +import { body, param, query } from "express-validator"; import { - OWNER, - ADMIN, - MEMBER, ACCEPTED, + ADMIN, AUTH_MODE_JWT, - AUTH_MODE_SERVICE_ACCOUNT -} from '../../variables'; -import { serviceAccountsController } from '../../controllers/v2'; + AUTH_MODE_SERVICE_ACCOUNT, + MEMBER, + OWNER, +} from "../../variables"; +import { serviceAccountsController } from "../../controllers/v2"; router.get( // TODO: check - '/me', + "/me", requireAuth({ - acceptedAuthModes: [AUTH_MODE_SERVICE_ACCOUNT] + acceptedAuthModes: [AUTH_MODE_SERVICE_ACCOUNT], }), serviceAccountsController.getCurrentServiceAccount ); router.get( - '/:serviceAccountId', - param('serviceAccountId').exists().isString().trim(), + "/:serviceAccountId", + param("serviceAccountId").exists().isString().trim(), requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireServiceAccountAuth({ acceptedRoles: [OWNER, ADMIN], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), serviceAccountsController.getServiceAccountById ); router.post( - '/', - body('organizationId').exists().isString().trim(), - body('name').exists().isString().trim(), - body('publicKey').exists().isString().trim(), - body('expiresIn').isNumeric(), // measured in ms + "/", + body("organizationId").exists().isString().trim(), + body("name").exists().isString().trim(), + body("publicKey").exists().isString().trim(), + body("expiresIn").isNumeric(), // measured in ms validateRequest, requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireOrganizationAuth({ acceptedRoles: [OWNER, ADMIN, MEMBER], acceptedStatuses: [ACCEPTED], - locationOrganizationId: 'body' + locationOrganizationId: "body", }), serviceAccountsController.createServiceAccount ); router.patch( - '/:serviceAccountId/name', - param('serviceAccountId').exists().isString().trim(), + "/:serviceAccountId/name", + param("serviceAccountId").exists().isString().trim(), validateRequest, requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireServiceAccountAuth({ acceptedRoles: [OWNER, ADMIN], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), serviceAccountsController.changeServiceAccountName ); router.delete( - '/:serviceAccountId', - param('serviceAccountId').exists().isString().trim(), + "/:serviceAccountId", + param("serviceAccountId").exists().isString().trim(), validateRequest, requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireServiceAccountAuth({ acceptedRoles: [OWNER, ADMIN], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), serviceAccountsController.deleteServiceAccount ); router.get( - '/:serviceAccountId/permissions/workspace', - param('serviceAccountId').exists().isString().trim(), + "/:serviceAccountId/permissions/workspace", + param("serviceAccountId").exists().isString().trim(), validateRequest, requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireServiceAccountAuth({ acceptedRoles: [OWNER, ADMIN], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), serviceAccountsController.getServiceAccountWorkspacePermissions ); router.post( - '/:serviceAccountId/permissions/workspace', - param('serviceAccountId').exists().isString().trim(), - body('workspaceId').exists().isString().notEmpty(), - body('environment').exists().isString().notEmpty(), - body('read').isBoolean().optional(), - body('write').isBoolean().optional(), - body('encryptedKey').exists().isString().notEmpty(), - body('nonce').exists().isString().notEmpty(), + "/:serviceAccountId/permissions/workspace", + param("serviceAccountId").exists().isString().trim(), + body("workspaceId").exists().isString().notEmpty(), + body("environment").exists().isString().notEmpty(), + body("read").isBoolean().optional(), + body("write").isBoolean().optional(), + body("encryptedKey").exists().isString().notEmpty(), + body("nonce").exists().isString().notEmpty(), validateRequest, requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireServiceAccountAuth({ acceptedRoles: [OWNER, ADMIN], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'body' + locationWorkspaceId: "body", }), serviceAccountsController.addServiceAccountWorkspacePermission ); router.delete( - '/:serviceAccountId/permissions/workspace/:serviceAccountWorkspacePermissionId', - param('serviceAccountId').exists().isString().trim(), - param('serviceAccountWorkspacePermissionId').exists().isString().trim(), + "/:serviceAccountId/permissions/workspace/:serviceAccountWorkspacePermissionId", + param("serviceAccountId").exists().isString().trim(), + param("serviceAccountWorkspacePermissionId").exists().isString().trim(), validateRequest, requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireServiceAccountAuth({ acceptedRoles: [OWNER, ADMIN], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), requireServiceAccountWorkspacePermissionAuth({ acceptedRoles: [OWNER, ADMIN], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), serviceAccountsController.deleteServiceAccountWorkspacePermission ); router.get( - '/:serviceAccountId/keys', - query('workspaceId').optional().isString(), + "/:serviceAccountId/keys", + query("workspaceId").optional().isString(), requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_SERVICE_ACCOUNT] + acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_SERVICE_ACCOUNT], }), requireServiceAccountAuth({ acceptedRoles: [OWNER, ADMIN], - acceptedStatuses: [ACCEPTED] + acceptedStatuses: [ACCEPTED], }), serviceAccountsController.getServiceAccountKeys ); diff --git a/backend/src/routes/v2/serviceTokenData.ts b/backend/src/routes/v2/serviceTokenData.ts index e96064715a..33ffad3cf5 100644 --- a/backend/src/routes/v2/serviceTokenData.ts +++ b/backend/src/routes/v2/serviceTokenData.ts @@ -2,18 +2,18 @@ import express from "express"; const router = express.Router(); import { requireAuth, - requireWorkspaceAuth, requireServiceTokenDataAuth, + requireWorkspaceAuth, validateRequest, } from "../../middleware"; -import { param, body } from "express-validator"; +import { body, param } from "express-validator"; import { ADMIN, - MEMBER, - PERMISSION_WRITE_SECRETS, AUTH_MODE_JWT, AUTH_MODE_SERVICE_ACCOUNT, AUTH_MODE_SERVICE_TOKEN, + MEMBER, + PERMISSION_WRITE_SECRETS, } from "../../variables"; import { serviceTokenDataController } from "../../controllers/v2"; diff --git a/backend/src/routes/v2/signup.ts b/backend/src/routes/v2/signup.ts index 1385918795..cc701b0343 100644 --- a/backend/src/routes/v2/signup.ts +++ b/backend/src/routes/v2/signup.ts @@ -1,47 +1,47 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); -import { body } from 'express-validator'; -import { requireSignupAuth, validateRequest } from '../../middleware'; -import { signupController } from '../../controllers/v2'; -import { authLimiter } from '../../helpers/rateLimiter'; +import { body } from "express-validator"; +import { requireSignupAuth, validateRequest } from "../../middleware"; +import { signupController } from "../../controllers/v2"; +import { authLimiter } from "../../helpers/rateLimiter"; router.post( - '/complete-account/signup', + "/complete-account/signup", authLimiter, requireSignupAuth, - body('email').exists().isString().trim().notEmpty().isEmail(), - body('firstName').exists().isString().trim().notEmpty(), - body('lastName').exists().isString().trim().notEmpty(), - body('protectedKey').exists().isString().trim().notEmpty(), - body('protectedKeyIV').exists().isString().trim().notEmpty(), - body('protectedKeyTag').exists().isString().trim().notEmpty(), - body('publicKey').exists().isString().trim().notEmpty(), - body('encryptedPrivateKey').exists().isString().trim().notEmpty(), - body('encryptedPrivateKeyIV').exists().isString().trim().notEmpty(), - body('encryptedPrivateKeyTag').exists().isString().trim().notEmpty(), - body('salt').exists().isString().trim().notEmpty(), - body('verifier').exists().isString().trim().notEmpty(), - body('organizationName').exists().isString().trim().notEmpty(), + body("email").exists().isString().trim().notEmpty().isEmail(), + body("firstName").exists().isString().trim().notEmpty(), + body("lastName").exists().isString().trim().notEmpty(), + body("protectedKey").exists().isString().trim().notEmpty(), + body("protectedKeyIV").exists().isString().trim().notEmpty(), + body("protectedKeyTag").exists().isString().trim().notEmpty(), + body("publicKey").exists().isString().trim().notEmpty(), + body("encryptedPrivateKey").exists().isString().trim().notEmpty(), + body("encryptedPrivateKeyIV").exists().isString().trim().notEmpty(), + body("encryptedPrivateKeyTag").exists().isString().trim().notEmpty(), + body("salt").exists().isString().trim().notEmpty(), + body("verifier").exists().isString().trim().notEmpty(), + body("organizationName").exists().isString().trim().notEmpty(), validateRequest, signupController.completeAccountSignup ); router.post( - '/complete-account/invite', + "/complete-account/invite", authLimiter, requireSignupAuth, - body('email').exists().isString().trim().notEmpty().isEmail(), - body('firstName').exists().isString().trim().notEmpty(), - body('lastName').exists().isString().trim().notEmpty(), - body('protectedKey').exists().isString().trim().notEmpty(), - body('protectedKeyIV').exists().isString().trim().notEmpty(), - body('protectedKeyTag').exists().isString().trim().notEmpty(), - body('publicKey').exists().trim().notEmpty(), - body('encryptedPrivateKey').exists().isString().trim().notEmpty(), - body('encryptedPrivateKeyIV').exists().isString().trim().notEmpty(), - body('encryptedPrivateKeyTag').exists().isString().trim().notEmpty(), - body('salt').exists().isString().trim().notEmpty(), - body('verifier').exists().isString().trim().notEmpty(), + body("email").exists().isString().trim().notEmpty().isEmail(), + body("firstName").exists().isString().trim().notEmpty(), + body("lastName").exists().isString().trim().notEmpty(), + body("protectedKey").exists().isString().trim().notEmpty(), + body("protectedKeyIV").exists().isString().trim().notEmpty(), + body("protectedKeyTag").exists().isString().trim().notEmpty(), + body("publicKey").exists().trim().notEmpty(), + body("encryptedPrivateKey").exists().isString().trim().notEmpty(), + body("encryptedPrivateKeyIV").exists().isString().trim().notEmpty(), + body("encryptedPrivateKeyTag").exists().isString().trim().notEmpty(), + body("salt").exists().isString().trim().notEmpty(), + body("verifier").exists().isString().trim().notEmpty(), validateRequest, signupController.completeAccountInvite ); diff --git a/backend/src/routes/v2/tags.ts b/backend/src/routes/v2/tags.ts index c9a11c1bcf..8974bd9fdd 100644 --- a/backend/src/routes/v2/tags.ts +++ b/backend/src/routes/v2/tags.ts @@ -1,54 +1,54 @@ -import express, { Response, Request } from 'express'; +import express from "express"; const router = express.Router(); -import { body, param } from 'express-validator'; -import { tagController } from '../../controllers/v2'; +import { body, param } from "express-validator"; +import { tagController } from "../../controllers/v2"; import { requireAuth, requireWorkspaceAuth, - validateRequest -} from '../../middleware'; + validateRequest, +} from "../../middleware"; import { ADMIN, + AUTH_MODE_JWT, MEMBER, - AUTH_MODE_JWT -} from '../../variables'; +} from "../../variables"; router.get( - '/:workspaceId/tags', + "/:workspaceId/tags", requireAuth({ acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [MEMBER, ADMIN], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - param('workspaceId').exists().trim(), + param("workspaceId").exists().trim(), validateRequest, tagController.getWorkspaceTags ); router.delete( - '/tags/:tagId', + "/tags/:tagId", requireAuth({ acceptedAuthModes: [AUTH_MODE_JWT], }), - param('tagId').exists().trim(), + param("tagId").exists().trim(), validateRequest, tagController.deleteWorkspaceTag ); router.post( - '/:workspaceId/tags', + "/:workspaceId/tags", requireAuth({ acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [MEMBER, ADMIN], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - param('workspaceId').exists().trim(), - body('name').exists().trim(), - body('slug').exists().trim(), + param("workspaceId").exists().trim(), + body("name").exists().trim(), + body("slug").exists().trim(), validateRequest, tagController.createWorkspaceTag ); diff --git a/backend/src/routes/v2/users.ts b/backend/src/routes/v2/users.ts index 63ae5eee9c..970824eaa6 100644 --- a/backend/src/routes/v2/users.ts +++ b/backend/src/routes/v2/users.ts @@ -1,38 +1,38 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); import { requireAuth, - validateRequest -} from '../../middleware'; -import { body } from 'express-validator'; -import { usersController } from '../../controllers/v2'; + validateRequest, +} from "../../middleware"; +import { body } from "express-validator"; +import { usersController } from "../../controllers/v2"; import { + AUTH_MODE_API_KEY, AUTH_MODE_JWT, - AUTH_MODE_API_KEY -} from '../../variables'; +} from "../../variables"; router.get( - '/me', + "/me", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY] + acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY], }), usersController.getMe ); router.patch( - '/me/mfa', + "/me/mfa", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY] + acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY], }), - body('isMfaEnabled').exists().isBoolean(), + body("isMfaEnabled").exists().isBoolean(), validateRequest, usersController.updateMyMfaEnabled ); router.get( - '/me/organizations', + "/me/organizations", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY] + acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY], }), usersController.getMyOrganizations ); diff --git a/backend/src/routes/v2/workspace.ts b/backend/src/routes/v2/workspace.ts index e258636fbb..c36a0b7f86 100644 --- a/backend/src/routes/v2/workspace.ts +++ b/backend/src/routes/v2/workspace.ts @@ -1,147 +1,147 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); -import { body, param, query } from 'express-validator'; +import { body, param, query } from "express-validator"; import { requireAuth, requireMembershipAuth, requireWorkspaceAuth, - validateRequest -} from '../../middleware'; + validateRequest, +} from "../../middleware"; import { ADMIN, - MEMBER, + AUTH_MODE_API_KEY, AUTH_MODE_JWT, AUTH_MODE_SERVICE_TOKEN, - AUTH_MODE_API_KEY -} from '../../variables'; -import { workspaceController } from '../../controllers/v2'; + MEMBER, +} from "../../variables"; +import { workspaceController } from "../../controllers/v2"; router.post( - '/:workspaceId/secrets', + "/:workspaceId/secrets", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - body('secrets').exists(), - body('keys').exists(), - body('environment').exists().trim().notEmpty(), - body('channel'), - param('workspaceId').exists().trim(), + body("secrets").exists(), + body("keys").exists(), + body("environment").exists().trim().notEmpty(), + body("channel"), + param("workspaceId").exists().trim(), validateRequest, workspaceController.pushWorkspaceSecrets ); router.get( - '/:workspaceId/secrets', + "/:workspaceId/secrets", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_SERVICE_TOKEN] + acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_SERVICE_TOKEN], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - query('environment').exists().trim(), - query('channel'), - param('workspaceId').exists().trim(), + query("environment").exists().trim(), + query("channel"), + param("workspaceId").exists().trim(), validateRequest, workspaceController.pullSecrets ); router.get( - '/:workspaceId/encrypted-key', + "/:workspaceId/encrypted-key", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY] + acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - param('workspaceId').exists().trim(), + param("workspaceId").exists().trim(), validateRequest, workspaceController.getWorkspaceKey ); router.get( - '/:workspaceId/service-token-data', + "/:workspaceId/service-token-data", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - param('workspaceId').exists().trim(), + param("workspaceId").exists().trim(), validateRequest, workspaceController.getWorkspaceServiceTokenData ); router.get( // new - TODO: rewire dashboard to this route - '/:workspaceId/memberships', - param('workspaceId').exists().trim(), + "/:workspaceId/memberships", + param("workspaceId").exists().trim(), validateRequest, requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY] + acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), workspaceController.getWorkspaceMemberships ); router.patch( // TODO - rewire dashboard to this route - '/:workspaceId/memberships/:membershipId', - param('workspaceId').exists().trim(), - param('membershipId').exists().trim(), - body('role').exists().isString().trim().isIn([ADMIN, MEMBER]), + "/:workspaceId/memberships/:membershipId", + param("workspaceId").exists().trim(), + param("membershipId").exists().trim(), + body("role").exists().isString().trim().isIn([ADMIN, MEMBER]), validateRequest, requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY] + acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), requireMembershipAuth({ acceptedRoles: [ADMIN], - locationMembershipId: 'params' + locationMembershipId: "params", }), workspaceController.updateWorkspaceMembership ); router.delete( // TODO - rewire dashboard to this route - '/:workspaceId/memberships/:membershipId', - param('workspaceId').exists().trim(), - param('membershipId').exists().trim(), + "/:workspaceId/memberships/:membershipId", + param("workspaceId").exists().trim(), + param("membershipId").exists().trim(), validateRequest, requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY] + acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), requireMembershipAuth({ acceptedRoles: [ADMIN], - locationMembershipId: 'params' + locationMembershipId: "params", }), workspaceController.deleteWorkspaceMembership ); router.patch( - '/:workspaceId/auto-capitalization', + "/:workspaceId/auto-capitalization", requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), - param('workspaceId').exists().trim(), - body('autoCapitalization').exists().trim().notEmpty(), + param("workspaceId").exists().trim(), + body("autoCapitalization").exists().trim().notEmpty(), validateRequest, workspaceController.toggleAutoCapitalization ); diff --git a/backend/src/routes/v3/auth.ts b/backend/src/routes/v3/auth.ts index 6539b5c0ff..12afb51136 100644 --- a/backend/src/routes/v3/auth.ts +++ b/backend/src/routes/v3/auth.ts @@ -1,27 +1,27 @@ -import express from 'express'; -import { body } from 'express-validator'; -import { validateRequest } from '../../middleware'; -import { authController } from '../../controllers/v3'; -import { authLimiter } from '../../helpers/rateLimiter'; +import express from "express"; +import { body } from "express-validator"; +import { validateRequest } from "../../middleware"; +import { authController } from "../../controllers/v3"; +import { authLimiter } from "../../helpers/rateLimiter"; const router = express.Router(); router.post( - '/login1', + "/login1", authLimiter, - body('email').isString().trim(), - body('providerAuthToken').isString().trim().optional({nullable: true}), - body('clientPublicKey').isString().trim().notEmpty(), + body("email").isString().trim(), + body("providerAuthToken").isString().trim().optional({nullable: true}), + body("clientPublicKey").isString().trim().notEmpty(), validateRequest, authController.login1 ); router.post( - '/login2', + "/login2", authLimiter, - body('email').isString().trim(), - body('providerAuthToken').isString().trim().optional({nullable: true}), - body('clientProof').isString().trim().notEmpty(), + body("email").isString().trim(), + body("providerAuthToken").isString().trim().optional({nullable: true}), + body("clientProof").isString().trim().notEmpty(), validateRequest, authController.login2 ); diff --git a/backend/src/routes/v3/index.ts b/backend/src/routes/v3/index.ts index 2560a8f828..f4fcfe55b5 100644 --- a/backend/src/routes/v3/index.ts +++ b/backend/src/routes/v3/index.ts @@ -1,7 +1,7 @@ -import auth from './auth'; -import secrets from './secrets'; -import workspaces from './workspaces'; -import signup from './signup'; +import auth from "./auth"; +import secrets from "./secrets"; +import workspaces from "./workspaces"; +import signup from "./signup"; export { auth, diff --git a/backend/src/routes/v3/secrets.ts b/backend/src/routes/v3/secrets.ts index 56573dd9f3..c010151c6c 100644 --- a/backend/src/routes/v3/secrets.ts +++ b/backend/src/routes/v3/secrets.ts @@ -8,16 +8,16 @@ import { import { body, param, query } from "express-validator"; import { secretsController } from "../../controllers/v3"; import { - AUTH_MODE_JWT, - AUTH_MODE_API_KEY, - AUTH_MODE_SERVICE_TOKEN, - AUTH_MODE_SERVICE_ACCOUNT, ADMIN, + AUTH_MODE_API_KEY, + AUTH_MODE_JWT, + AUTH_MODE_SERVICE_ACCOUNT, + AUTH_MODE_SERVICE_TOKEN, MEMBER, - PERMISSION_WRITE_SECRETS, - SECRET_SHARED, - SECRET_PERSONAL, PERMISSION_READ_SECRETS, + PERMISSION_WRITE_SECRETS, + SECRET_PERSONAL, + SECRET_SHARED, } from "../../variables"; router.get( @@ -40,7 +40,7 @@ router.get( locationEnvironment: "query", requiredPermissions: [PERMISSION_READ_SECRETS], requireBlindIndicesEnabled: true, - requireE2EEOff: true + requireE2EEOff: true, }), secretsController.getSecretsRaw ); @@ -67,7 +67,7 @@ router.get( locationEnvironment: "query", requiredPermissions: [PERMISSION_READ_SECRETS], requireBlindIndicesEnabled: true, - requireE2EEOff: true + requireE2EEOff: true, }), secretsController.getSecretByNameRaw ); @@ -95,7 +95,7 @@ router.post( locationEnvironment: "body", requiredPermissions: [PERMISSION_WRITE_SECRETS], requireBlindIndicesEnabled: true, - requireE2EEOff: true + requireE2EEOff: true, }), secretsController.createSecretRaw ); @@ -123,7 +123,7 @@ router.patch( locationEnvironment: "body", requiredPermissions: [PERMISSION_WRITE_SECRETS], requireBlindIndicesEnabled: true, - requireE2EEOff: true + requireE2EEOff: true, }), secretsController.updateSecretByNameRaw ); @@ -150,7 +150,7 @@ router.delete( locationEnvironment: "body", requiredPermissions: [PERMISSION_WRITE_SECRETS], requireBlindIndicesEnabled: true, - requireE2EEOff: true + requireE2EEOff: true, }), secretsController.deleteSecretByNameRaw ); @@ -175,7 +175,7 @@ router.get( locationEnvironment: "query", requiredPermissions: [PERMISSION_READ_SECRETS], requireBlindIndicesEnabled: true, - requireE2EEOff: false + requireE2EEOff: false, }), secretsController.getSecrets ); @@ -210,7 +210,7 @@ router.post( locationEnvironment: "body", requiredPermissions: [PERMISSION_WRITE_SECRETS], requireBlindIndicesEnabled: true, - requireE2EEOff: false + requireE2EEOff: false, }), secretsController.createSecret ); @@ -266,7 +266,7 @@ router.patch( locationEnvironment: "body", requiredPermissions: [PERMISSION_WRITE_SECRETS], requireBlindIndicesEnabled: true, - requireE2EEOff: false + requireE2EEOff: false, }), secretsController.updateSecretByName ); @@ -293,7 +293,7 @@ router.delete( locationEnvironment: "body", requiredPermissions: [PERMISSION_WRITE_SECRETS], requireBlindIndicesEnabled: true, - requireE2EEOff: false + requireE2EEOff: false, }), secretsController.deleteSecretByName ); diff --git a/backend/src/routes/v3/signup.ts b/backend/src/routes/v3/signup.ts index b2fb4af81b..eb3ff9023d 100644 --- a/backend/src/routes/v3/signup.ts +++ b/backend/src/routes/v3/signup.ts @@ -1,27 +1,27 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); -import { body } from 'express-validator'; -import { signupController } from '../../controllers/v3'; -import { authLimiter } from '../../helpers/rateLimiter'; -import { validateRequest } from '../../middleware'; +import { body } from "express-validator"; +import { signupController } from "../../controllers/v3"; +import { authLimiter } from "../../helpers/rateLimiter"; +import { validateRequest } from "../../middleware"; router.post( - '/complete-account/signup', + "/complete-account/signup", authLimiter, - body('email').exists().isString().trim().notEmpty().isEmail(), - body('firstName').exists().isString().trim().notEmpty(), - body('lastName').exists().isString().trim().optional({nullable: true}), - body('protectedKey').exists().isString().trim().notEmpty(), - body('protectedKeyIV').exists().isString().trim().notEmpty(), - body('protectedKeyTag').exists().isString().trim().notEmpty(), - body('publicKey').exists().isString().trim().notEmpty(), - body('encryptedPrivateKey').exists().isString().trim().notEmpty(), - body('encryptedPrivateKeyIV').exists().isString().trim().notEmpty(), - body('encryptedPrivateKeyTag').exists().isString().trim().notEmpty(), - body('salt').exists().isString().trim().notEmpty(), - body('verifier').exists().isString().trim().notEmpty(), - body('organizationName').exists().isString().trim().notEmpty(), - body('providerAuthToken').isString().trim().optional({nullable: true}), + body("email").exists().isString().trim().notEmpty().isEmail(), + body("firstName").exists().isString().trim().notEmpty(), + body("lastName").exists().isString().trim().optional({nullable: true}), + body("protectedKey").exists().isString().trim().notEmpty(), + body("protectedKeyIV").exists().isString().trim().notEmpty(), + body("protectedKeyTag").exists().isString().trim().notEmpty(), + body("publicKey").exists().isString().trim().notEmpty(), + body("encryptedPrivateKey").exists().isString().trim().notEmpty(), + body("encryptedPrivateKeyIV").exists().isString().trim().notEmpty(), + body("encryptedPrivateKeyTag").exists().isString().trim().notEmpty(), + body("salt").exists().isString().trim().notEmpty(), + body("verifier").exists().isString().trim().notEmpty(), + body("organizationName").exists().isString().trim().notEmpty(), + body("providerAuthToken").isString().trim().optional({nullable: true}), validateRequest, signupController.completeAccountSignup, ); diff --git a/backend/src/routes/v3/workspaces.ts b/backend/src/routes/v3/workspaces.ts index 5c4df39d86..7aa9096936 100644 --- a/backend/src/routes/v3/workspaces.ts +++ b/backend/src/routes/v3/workspaces.ts @@ -1,75 +1,75 @@ -import express from 'express'; +import express from "express"; const router = express.Router(); import { requireAuth, requireWorkspaceAuth, - validateRequest -} from '../../middleware'; -import { workspacesController } from '../../controllers/v3'; + validateRequest, +} from "../../middleware"; +import { workspacesController } from "../../controllers/v3"; import { + ADMIN, AUTH_MODE_JWT, - ADMIN -} from '../../variables'; -import { param, body } from 'express-validator'; +} from "../../variables"; +import { body, param } from "express-validator"; // -- migration to blind indices endpoints router.get( - '/:workspaceId/secrets/blind-index-status', - param('workspaceId').exists().isString().trim(), + "/:workspaceId/secrets/blind-index-status", + param("workspaceId").exists().isString().trim(), validateRequest, requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN], - locationWorkspaceId: 'params', + locationWorkspaceId: "params", }), workspacesController.getWorkspaceBlindIndexStatus ); router.get( // allow admins to get all workspace secrets (part of blind indices migration) - '/:workspaceId/secrets', - param('workspaceId').exists().isString().trim(), + "/:workspaceId/secrets", + param("workspaceId").exists().isString().trim(), validateRequest, requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN], - locationWorkspaceId: 'params', + locationWorkspaceId: "params", }), workspacesController.getWorkspaceSecrets ); router.post( // allow admins to name all workspace secrets (part of blind indices migration) - '/:workspaceId/secrets/names', - param('workspaceId').exists().isString().trim(), - body('secretsToUpdate') + "/:workspaceId/secrets/names", + param("workspaceId").exists().isString().trim(), + body("secretsToUpdate") .exists() .isArray() - .withMessage('secretsToUpdate must be an array') + .withMessage("secretsToUpdate must be an array") .customSanitizer((value) => { return value.map((secret: any) => ({ secretName: secret.secretName, - _id: secret._id + _id: secret._id, })); }), - body('secretsToUpdate.*.secretName') + body("secretsToUpdate.*.secretName") .exists() .isString() - .withMessage('secretName must be a string'), - body('secretsToUpdate.*._id') + .withMessage("secretName must be a string"), + body("secretsToUpdate.*._id") .exists() .isString() - .withMessage('secretId must be a string'), + .withMessage("secretId must be a string"), validateRequest, requireAuth({ - acceptedAuthModes: [AUTH_MODE_JWT] + acceptedAuthModes: [AUTH_MODE_JWT], }), requireWorkspaceAuth({ acceptedRoles: [ADMIN], - locationWorkspaceId: 'params' + locationWorkspaceId: "params", }), workspacesController.nameWorkspaceSecrets ); diff --git a/backend/src/services/BotService.ts b/backend/src/services/BotService.ts index 0e3768a9c9..ca31bf1031 100644 --- a/backend/src/services/BotService.ts +++ b/backend/src/services/BotService.ts @@ -1,10 +1,10 @@ import { Types } from "mongoose"; import { - getSecretsBotHelper, - encryptSymmetricHelper, decryptSymmetricHelper, - getKey, + encryptSymmetricHelper, getIsWorkspaceE2EEHelper, + getKey, + getSecretsBotHelper, } from "../helpers/bot"; /** diff --git a/backend/src/services/DatabaseService.ts b/backend/src/services/DatabaseService.ts index 616f56c471..4b40863d05 100644 --- a/backend/src/services/DatabaseService.ts +++ b/backend/src/services/DatabaseService.ts @@ -1,7 +1,7 @@ import { + closeDatabaseHelper, initDatabaseHelper, - closeDatabaseHelper -} from '../helpers/database'; +} from "../helpers/database"; /** * Class to handle database actions @@ -15,7 +15,7 @@ class DatabaseService { */ static async initDatabase(MONGO_URL: string) { return await initDatabaseHelper({ - mongoURL: MONGO_URL + mongoURL: MONGO_URL, }); } diff --git a/backend/src/services/EventService.ts b/backend/src/services/EventService.ts index 160086be88..7abc7c1b1e 100644 --- a/backend/src/services/EventService.ts +++ b/backend/src/services/EventService.ts @@ -1,5 +1,5 @@ -import { Types } from 'mongoose'; -import { handleEventHelper } from '../helpers/event'; +import { Types } from "mongoose"; +import { handleEventHelper } from "../helpers/event"; interface Event { name: string; @@ -22,7 +22,7 @@ class EventService { */ static async handleEvent({ event }: { event: Event }): Promise { await handleEventHelper({ - event + event, }); } } diff --git a/backend/src/services/IntegrationService.ts b/backend/src/services/IntegrationService.ts index 1e7409ad0a..b5b8b1d3f2 100644 --- a/backend/src/services/IntegrationService.ts +++ b/backend/src/services/IntegrationService.ts @@ -1,12 +1,12 @@ -import { Types } from 'mongoose'; +import { Types } from "mongoose"; import { - handleOAuthExchangeHelper, - syncIntegrationsHelper, - getIntegrationAuthRefreshHelper, getIntegrationAuthAccessHelper, - setIntegrationAuthRefreshHelper, + getIntegrationAuthRefreshHelper, + handleOAuthExchangeHelper, setIntegrationAuthAccessHelper, -} from '../helpers/integration'; + setIntegrationAuthRefreshHelper, + syncIntegrationsHelper, +} from "../helpers/integration"; /** * Class to handle integrations @@ -30,7 +30,7 @@ class IntegrationService { workspaceId, integration, code, - environment + environment, }: { workspaceId: string; integration: string; @@ -41,7 +41,7 @@ class IntegrationService { workspaceId, integration, code, - environment + environment, }); } @@ -53,13 +53,13 @@ class IntegrationService { */ static async syncIntegrations({ workspaceId, - environment + environment, }: { workspaceId: Types.ObjectId; environment?: string; }) { return await syncIntegrationsHelper({ - workspaceId + workspaceId, }); } @@ -72,7 +72,7 @@ class IntegrationService { */ static async getIntegrationAuthRefresh({ integrationAuthId }: { integrationAuthId: Types.ObjectId}) { return await getIntegrationAuthRefreshHelper({ - integrationAuthId + integrationAuthId, }); } @@ -85,7 +85,7 @@ class IntegrationService { */ static async getIntegrationAuthAccess({ integrationAuthId }: { integrationAuthId: Types.ObjectId }) { return await getIntegrationAuthAccessHelper({ - integrationAuthId + integrationAuthId, }); } @@ -100,14 +100,14 @@ class IntegrationService { */ static async setIntegrationAuthRefresh({ integrationAuthId, - refreshToken + refreshToken, }: { integrationAuthId: string; refreshToken: string; }) { return await setIntegrationAuthRefreshHelper({ integrationAuthId, - refreshToken + refreshToken, }); } @@ -126,7 +126,7 @@ class IntegrationService { integrationAuthId, accessId, accessToken, - accessExpiresAt + accessExpiresAt, }: { integrationAuthId: string; accessId: string | null; @@ -137,7 +137,7 @@ class IntegrationService { integrationAuthId, accessId, accessToken, - accessExpiresAt + accessExpiresAt, }); } } diff --git a/backend/src/services/SecretService.ts b/backend/src/services/SecretService.ts index afd706dbd7..ef372bddc5 100644 --- a/backend/src/services/SecretService.ts +++ b/backend/src/services/SecretService.ts @@ -1,22 +1,22 @@ import { Types } from "mongoose"; import { CreateSecretParams, - GetSecretsParams, + DeleteSecretParams, GetSecretParams, + GetSecretsParams, UpdateSecretParams, - DeleteSecretParams -} from '../interfaces/services/SecretService'; +} from "../interfaces/services/SecretService"; import { createSecretBlindIndexDataHelper, - getSecretBlindIndexSaltHelper, - generateSecretBlindIndexWithSaltHelper, - generateSecretBlindIndexHelper, createSecretHelper, - getSecretsHelper, + deleteSecretHelper, + generateSecretBlindIndexHelper, + generateSecretBlindIndexWithSaltHelper, + getSecretBlindIndexSaltHelper, getSecretHelper, + getSecretsHelper, updateSecretHelper, - deleteSecretHelper -} from '../helpers/secrets'; +} from "../helpers/secrets"; class SecretService { /** diff --git a/backend/src/services/TelemetryService.ts b/backend/src/services/TelemetryService.ts index da90732eb0..3db2fdb89b 100644 --- a/backend/src/services/TelemetryService.ts +++ b/backend/src/services/TelemetryService.ts @@ -1,24 +1,21 @@ -import { PostHog } from 'posthog-node'; -import { getLogger } from '../utils/logger'; -import { AuthData } from '../interfaces/middleware'; +import { PostHog } from "posthog-node"; +import { getLogger } from "../utils/logger"; +import { AuthData } from "../interfaces/middleware"; import { getNodeEnv, - getTelemetryEnabled, + getPostHogHost, getPostHogProjectApiKey, - getPostHogHost -} from '../config'; + getTelemetryEnabled, +} from "../config"; import { - IUser, - User, - IServiceAccount, ServiceAccount, - IServiceTokenData, - ServiceTokenData -} from '../models'; + ServiceTokenData, + User, +} from "../models"; import { AccountNotFoundError, - BadRequestError -} from '../utils/errors'; + BadRequestError, +} from "../utils/errors"; class Telemetry { /** @@ -31,7 +28,7 @@ class Telemetry { "To improve, Infisical collects telemetry data about general usage.", "This helps us understand how the product is doing and guide our product development to create the best possible platform; it also helps us demonstrate growth as we support Infisical as open-source software.", "To opt into telemetry, you can set `TELEMETRY_ENABLED=true` within the environment variables.", - ].join('\n')) + ].join("\n")) } } @@ -41,10 +38,10 @@ class Telemetry { */ static getPostHogClient = async () => { let postHogClient: any; - if ((await getNodeEnv()) === 'production' && (await getTelemetryEnabled())) { + if ((await getNodeEnv()) === "production" && (await getTelemetryEnabled())) { // case: enable opt-out telemetry in production postHogClient = new PostHog(await getPostHogProjectApiKey(), { - host: await getPostHogHost() + host: await getPostHogHost(), }); } @@ -52,11 +49,11 @@ class Telemetry { } static getDistinctId = async ({ - authData + authData, }: { authData: AuthData; }) => { - let distinctId = ''; + let distinctId = ""; if (authData.authPayload instanceof User) { distinctId = authData.authPayload.email; } else if (authData.authPayload instanceof ServiceAccount) { @@ -64,7 +61,7 @@ class Telemetry { } else if (authData.authPayload instanceof ServiceTokenData) { if (authData.authPayload.user) { - const user = await User.findById(authData.authPayload.user, 'email'); + const user = await User.findById(authData.authPayload.user, "email"); if (!user) throw AccountNotFoundError(); distinctId = user.email; } else if (authData.authPayload.serviceAccount) { @@ -72,8 +69,8 @@ class Telemetry { } } - if (distinctId === '') throw BadRequestError({ - message: 'Failed to obtain distinct id for logging telemetry' + if (distinctId === "") throw BadRequestError({ + message: "Failed to obtain distinct id for logging telemetry", }); return distinctId; diff --git a/backend/src/services/TokenService.ts b/backend/src/services/TokenService.ts index 6299f1d54d..7d0ff881d5 100644 --- a/backend/src/services/TokenService.ts +++ b/backend/src/services/TokenService.ts @@ -1,5 +1,5 @@ -import { Types } from 'mongoose'; -import { createTokenHelper, validateTokenHelper } from '../helpers/token'; +import { Types } from "mongoose"; +import { createTokenHelper, validateTokenHelper } from "../helpers/token"; /** * Class to handle token actions @@ -19,9 +19,9 @@ class TokenService { type, email, phoneNumber, - organizationId + organizationId, }: { - type: 'emailConfirmation' | 'emailMfa' | 'organizationInvitation' | 'passwordReset'; + type: "emailConfirmation" | "emailMfa" | "organizationInvitation" | "passwordReset"; email?: string; phoneNumber?: string; organizationId?: Types.ObjectId; @@ -30,7 +30,7 @@ class TokenService { type, email, phoneNumber, - organizationId + organizationId, }); } @@ -48,9 +48,9 @@ class TokenService { email, phoneNumber, organizationId, - token + token, }: { - type: 'emailConfirmation' | 'emailMfa' | 'organizationInvitation' | 'passwordReset'; + type: "emailConfirmation" | "emailMfa" | "organizationInvitation" | "passwordReset"; email?: string; phoneNumber?: string; organizationId?: Types.ObjectId; @@ -61,7 +61,7 @@ class TokenService { email, phoneNumber, organizationId, - token + token, }); } } diff --git a/backend/src/services/health.ts b/backend/src/services/health.ts index daf3bf962f..5ddfb8171a 100644 --- a/backend/src/services/health.ts +++ b/backend/src/services/health.ts @@ -1,19 +1,19 @@ -import mongoose from 'mongoose'; -import { createTerminus } from '@godaddy/terminus'; -import { getLogger } from '../utils/logger'; +import mongoose from "mongoose"; +import { createTerminus } from "@godaddy/terminus"; +import { getLogger } from "../utils/logger"; export const setUpHealthEndpoint = (server: T) => { const onSignal = async () => { - (await getLogger('backend-main')).info('Server is starting clean-up'); + (await getLogger("backend-main")).info("Server is starting clean-up"); return Promise.all([ new Promise((resolve) => { if (mongoose.connection && mongoose.connection.readyState == 1) { mongoose.connection.close() - .then(() => resolve('Database connection closed')); + .then(() => resolve("Database connection closed")); } else { - resolve('Database connection already closed'); + resolve("Database connection already closed"); } - }) + }), ]); }; @@ -25,8 +25,8 @@ export const setUpHealthEndpoint = (server: T) => { createTerminus(server, { healthChecks: { - '/healthcheck': healthCheck, - onSignal - } + "/healthcheck": healthCheck, + onSignal, + }, }); }; diff --git a/backend/src/services/index.ts b/backend/src/services/index.ts index db0bd39a34..ad83bf5102 100644 --- a/backend/src/services/index.ts +++ b/backend/src/services/index.ts @@ -1,11 +1,11 @@ -import DatabaseService from './DatabaseService'; +import DatabaseService from "./DatabaseService"; // import { logTelemetryMessage, getPostHogClient } from './TelemetryService'; -import TelemetryService from './TelemetryService'; -import BotService from './BotService'; -import EventService from './EventService'; -import IntegrationService from './IntegrationService'; -import TokenService from './TokenService'; -import SecretService from './SecretService'; +import TelemetryService from "./TelemetryService"; +import BotService from "./BotService"; +import EventService from "./EventService"; +import IntegrationService from "./IntegrationService"; +import TokenService from "./TokenService"; +import SecretService from "./SecretService"; export { TelemetryService, @@ -14,5 +14,5 @@ export { EventService, IntegrationService, TokenService, - SecretService + SecretService, } \ No newline at end of file diff --git a/backend/src/services/smtp.ts b/backend/src/services/smtp.ts index 0231e7f54b..4bd58020b8 100644 --- a/backend/src/services/smtp.ts +++ b/backend/src/services/smtp.ts @@ -1,31 +1,31 @@ -import nodemailer from 'nodemailer'; +import nodemailer from "nodemailer"; import { - SMTP_HOST_SENDGRID, + SMTP_HOST_GMAIL, SMTP_HOST_MAILGUN, + SMTP_HOST_SENDGRID, SMTP_HOST_SOCKETLABS, SMTP_HOST_ZOHOMAIL, - SMTP_HOST_GMAIL -} from '../variables'; -import SMTPConnection from 'nodemailer/lib/smtp-connection'; -import * as Sentry from '@sentry/node'; +} from "../variables"; +import SMTPConnection from "nodemailer/lib/smtp-connection"; +import * as Sentry from "@sentry/node"; import { getSmtpHost, - getSmtpUsername, getSmtpPassword, + getSmtpPort, getSmtpSecure, - getSmtpPort -} from '../config'; + getSmtpUsername, +} from "../config"; export const initSmtp = async () => { const mailOpts: SMTPConnection.Options = { host: await getSmtpHost(), - port: await getSmtpPort() + port: await getSmtpPort(), }; if ((await getSmtpUsername()) && (await getSmtpPassword())) { mailOpts.auth = { user: await getSmtpUsername(), - pass: await getSmtpPassword() + pass: await getSmtpPassword(), }; } @@ -37,31 +37,31 @@ export const initSmtp = async () => { case SMTP_HOST_MAILGUN: mailOpts.requireTLS = true; mailOpts.tls = { - ciphers: 'TLSv1.2' + ciphers: "TLSv1.2", } break; case SMTP_HOST_SOCKETLABS: mailOpts.requireTLS = true; mailOpts.tls = { - ciphers: 'TLSv1.2' + ciphers: "TLSv1.2", } break; case SMTP_HOST_ZOHOMAIL: mailOpts.requireTLS = true; mailOpts.tls = { - ciphers: 'TLSv1.2' + ciphers: "TLSv1.2", } break; case SMTP_HOST_GMAIL: mailOpts.requireTLS = true; mailOpts.tls = { - ciphers: 'TLSv1.2' + ciphers: "TLSv1.2", } break; default: - if ((await getSmtpHost()).includes('amazonaws.com')) { + if ((await getSmtpHost()).includes("amazonaws.com")) { mailOpts.tls = { - ciphers: 'TLSv1.2' + ciphers: "TLSv1.2", } } else { mailOpts.secure = true; @@ -75,7 +75,7 @@ export const initSmtp = async () => { .verify() .then((err) => { Sentry.setUser(null); - Sentry.captureMessage('SMTP - Successfully connected'); + Sentry.captureMessage("SMTP - Successfully connected"); console.log("SMTP - Successfully connected") }) .catch(async (err) => { diff --git a/backend/src/types/express/index.d.ts b/backend/src/types/express/index.d.ts index 471506d452..f3b2700da2 100644 --- a/backend/src/types/express/index.d.ts +++ b/backend/src/types/express/index.d.ts @@ -1,16 +1,11 @@ -import * as express from 'express'; -import { Types } from 'mongoose'; -import { - IUser, - IServiceAccount, - IServiceTokenData, - ISecret -} from '../../models'; -import { - AuthData -} from '../../interfaces/middleware'; +import { Types } from "mongoose"; -declare module 'express' { + +import { + AuthData, +} from "../../interfaces/middleware"; + +declare module "express" { interface Request { user?: any; } diff --git a/backend/src/types/secret/index.d.ts b/backend/src/types/secret/index.d.ts index deab73e955..13391549e3 100644 --- a/backend/src/types/secret/index.d.ts +++ b/backend/src/types/secret/index.d.ts @@ -1,7 +1,5 @@ -import { Types } from "mongoose"; import { Assign, Omit } from "utility-types"; import { ISecret } from "../../models"; -import { mongo } from "mongoose"; // Everything is required, except the omitted types export type CreateSecretRequestBody = Omit< diff --git a/backend/src/utils/addDevelopmentUser.ts b/backend/src/utils/addDevelopmentUser.ts index 2c78662299..d8b6689096 100644 --- a/backend/src/utils/addDevelopmentUser.ts +++ b/backend/src/utils/addDevelopmentUser.ts @@ -6,8 +6,8 @@ import { Key, Membership, MembershipOrg, Organization, User, Workspace } from "../models"; import { SecretService } from "../services"; -import { Types } from 'mongoose'; -import { getNodeEnv } from '../config'; +import { Types } from "mongoose"; +import { getNodeEnv } from "../config"; export const testUserEmail = "test@localhost.local" export const testUserPassword = "testInfisical1" @@ -25,71 +25,71 @@ export const createTestUserForDevelopment = async () => { _id: testUserId, email: testUserEmail, refreshVersion: 0, - encryptedPrivateKey: 'ITMdDXtLoxib4+53U/qzvIV/T/UalRwimogFCXv/UsulzEoiKM+aK2aqOb0=', - firstName: 'Jake', - iv: '9fp0dZHI+UuHeKkWMDvD6w==', - lastName: 'Moni', - publicKey: 'cf44BhkybbBfsE0fZHe2jvqtCj6KLXvSq4hVjV0svzk=', - salt: 'd8099dc70958090346910fb9639262b83cf526fc9b4555a171b36a9e1bcd0240', - tag: 'bQ/UTghqcQHRoSMpLQD33g==', - verifier: '12271fcd50937ca4512e1e3166adaf9d9fc7a5cd0e4c4cb3eda89f35572ede4d9eef23f64aef9220367abff9437b0b6fa55792c442f177201d87051cf77dadade254ff667170440327355fb7d6ac4745d4db302f4843632c2ed5919ebdcff343287a4cd552255d9e3ce81177edefe089617b7616683901475d393405f554634b9bf9230c041ac85624f37a60401be20b78044932580ae0868323be3749fbf856df1518153ba375fec628275f0c445f237446ea4aa7f12c1aa1d6b5fd74b7f2e88d062845a19819ec63f2d2ed9e9f37c055149649461d997d2ae1482f53b04f9de7493efbb9686fb19b2d559b9aa2b502c22dec83f9fc43290dfea89a1dc6f03580b3642b3824513853e81a441be9a0b2fde2231bac60f3287872617a36884697805eeea673cf1a351697834484ada0f282e4745015c9c2928d61e6d092f1b9c3a27eda8413175d23bb2edae62f82ccaf52bf5a6a90344a766c7e4ebf65dae9ae90b2ad4ae65dbf16e3a6948e429771cc50307ae86d454f71a746939ed061f080dd3ae369c1a0739819aca17af46a085bac1f2a5d936d198e7951a8ac3bb38b893665fe7312835abd3f61811f81efa2a8761af5070085f9b6adcca80bf9b0d81899c3d41487fba90728bb24eceb98bd69770360a232624133700ceb4d153f2ad702e0a5b7dfaf97d20bc8aa71dc8c20024a58c06a8fecdad18cb5a2f89c51eaf7' + encryptedPrivateKey: "ITMdDXtLoxib4+53U/qzvIV/T/UalRwimogFCXv/UsulzEoiKM+aK2aqOb0=", + firstName: "Jake", + iv: "9fp0dZHI+UuHeKkWMDvD6w==", + lastName: "Moni", + publicKey: "cf44BhkybbBfsE0fZHe2jvqtCj6KLXvSq4hVjV0svzk=", + salt: "d8099dc70958090346910fb9639262b83cf526fc9b4555a171b36a9e1bcd0240", + tag: "bQ/UTghqcQHRoSMpLQD33g==", + verifier: "12271fcd50937ca4512e1e3166adaf9d9fc7a5cd0e4c4cb3eda89f35572ede4d9eef23f64aef9220367abff9437b0b6fa55792c442f177201d87051cf77dadade254ff667170440327355fb7d6ac4745d4db302f4843632c2ed5919ebdcff343287a4cd552255d9e3ce81177edefe089617b7616683901475d393405f554634b9bf9230c041ac85624f37a60401be20b78044932580ae0868323be3749fbf856df1518153ba375fec628275f0c445f237446ea4aa7f12c1aa1d6b5fd74b7f2e88d062845a19819ec63f2d2ed9e9f37c055149649461d997d2ae1482f53b04f9de7493efbb9686fb19b2d559b9aa2b502c22dec83f9fc43290dfea89a1dc6f03580b3642b3824513853e81a441be9a0b2fde2231bac60f3287872617a36884697805eeea673cf1a351697834484ada0f282e4745015c9c2928d61e6d092f1b9c3a27eda8413175d23bb2edae62f82ccaf52bf5a6a90344a766c7e4ebf65dae9ae90b2ad4ae65dbf16e3a6948e429771cc50307ae86d454f71a746939ed061f080dd3ae369c1a0739819aca17af46a085bac1f2a5d936d198e7951a8ac3bb38b893665fe7312835abd3f61811f81efa2a8761af5070085f9b6adcca80bf9b0d81899c3d41487fba90728bb24eceb98bd69770360a232624133700ceb4d153f2ad702e0a5b7dfaf97d20bc8aa71dc8c20024a58c06a8fecdad18cb5a2f89c51eaf7", } const testWorkspaceKey = { _id: new Types.ObjectId(testWorkspaceKeyId), workspace: testWorkspaceId, - encryptedKey: '96ZIRSU21CjVzIQ4Yp994FGWQvDdyK3gq+z+NCaJLK0ByTlvUePmf+AYGFJjkAdz', - nonce: '1jhCGqg9Wx3n0OtVxbDgiYYGq4S3EdgO', - sender: '63cefa6ec8d3175601cfa980', - receiver: '63cefa6ec8d3175601cfa980', + encryptedKey: "96ZIRSU21CjVzIQ4Yp994FGWQvDdyK3gq+z+NCaJLK0ByTlvUePmf+AYGFJjkAdz", + nonce: "1jhCGqg9Wx3n0OtVxbDgiYYGq4S3EdgO", + sender: "63cefa6ec8d3175601cfa980", + receiver: "63cefa6ec8d3175601cfa980", } const testWorkspace = { _id: new Types.ObjectId(testWorkspaceId), - name: 'Example Project', + name: "Example Project", organization: testOrgId, environments: [ { - _id: '63cefb15c8d3175601cfa98a', - name: 'Development', - slug: 'dev' + _id: "63cefb15c8d3175601cfa98a", + name: "Development", + slug: "dev", }, { - _id: '63cefb15c8d3175601cfa98b', - name: 'Test', - slug: 'test' + _id: "63cefb15c8d3175601cfa98b", + name: "Test", + slug: "test", }, { - _id: '63cefb15c8d3175601cfa98c', - name: 'Staging', - slug: 'staging' + _id: "63cefb15c8d3175601cfa98c", + name: "Staging", + slug: "staging", }, { - _id: '63cefb15c8d3175601cfa98d', - name: 'Production', - slug: 'prod' - } + _id: "63cefb15c8d3175601cfa98d", + name: "Production", + slug: "prod", + }, ], } const testOrg = { _id: testOrgId, - name: 'Jake\'s organization' + name: "Jake's organization", } const testMembershipOrg = { _id: testMembershipOrgId, organization: testOrgId, - role: 'owner', - status: 'accepted', + role: "owner", + status: "accepted", user: testUserId, } const testMembership = { _id: testMembershipId, - role: 'admin', + role: "admin", user: testUserId, - workspace: testWorkspaceId + workspace: testWorkspaceId, } try { @@ -124,7 +124,7 @@ export const createTestUserForDevelopment = async () => { // initialize blind index salt for workspace await SecretService.createSecretBlindIndexData({ - workspaceId: workspace._id + workspaceId: workspace._id, }); } diff --git a/backend/src/utils/aes-gcm.ts b/backend/src/utils/aes-gcm.ts index 20d0bb829b..4457616a6f 100644 --- a/backend/src/utils/aes-gcm.ts +++ b/backend/src/utils/aes-gcm.ts @@ -1,6 +1,6 @@ -import crypto = require('crypto'); +import crypto = require("crypto"); -const ALGORITHM = 'aes-256-gcm'; +const ALGORITHM = "aes-256-gcm"; const BLOCK_SIZE_BYTES = 16; export default class AesGCM { @@ -13,12 +13,12 @@ export default class AesGCM { const iv = crypto.randomBytes(BLOCK_SIZE_BYTES); const cipher = crypto.createCipheriv(ALGORITHM, secret, iv); - let ciphertext = cipher.update(text, 'utf8', 'base64'); - ciphertext += cipher.final('base64'); + let ciphertext = cipher.update(text, "utf8", "base64"); + ciphertext += cipher.final("base64"); return { ciphertext, - iv: iv.toString('base64'), - tag: cipher.getAuthTag().toString('base64') + iv: iv.toString("base64"), + tag: cipher.getAuthTag().toString("base64"), }; } @@ -31,12 +31,12 @@ export default class AesGCM { const decipher = crypto.createDecipheriv( ALGORITHM, secret, - Buffer.from(iv, 'base64') + Buffer.from(iv, "base64") ); - decipher.setAuthTag(Buffer.from(tag, 'base64')); + decipher.setAuthTag(Buffer.from(tag, "base64")); - let cleartext = decipher.update(ciphertext, 'base64', 'utf8'); - cleartext += decipher.final('utf8'); + let cleartext = decipher.update(ciphertext, "base64", "utf8"); + cleartext += decipher.final("utf8"); return cleartext; } diff --git a/backend/src/utils/auth.ts b/backend/src/utils/auth.ts index 5144af16d6..6970292c4c 100644 --- a/backend/src/utils/auth.ts +++ b/backend/src/utils/auth.ts @@ -1,22 +1,22 @@ -import express from 'express'; -import passport from 'passport'; -import { AuthData } from '../interfaces/middleware'; +import express from "express"; +import passport from "passport"; +import { AuthData } from "../interfaces/middleware"; import { AuthProvider, - User, ServiceAccount, ServiceTokenData, -} from '../models'; -import { createToken } from '../helpers/auth'; + User, +} from "../models"; +import { createToken } from "../helpers/auth"; import { getClientIdGoogle, getClientSecretGoogle, getJwtProviderAuthLifetime, - getJwtProviderAuthSecret -} from '../config'; + getJwtProviderAuthSecret, +} from "../config"; // eslint-disable-next-line @typescript-eslint/no-var-requires -const GoogleStrategy = require('passport-google-oauth20').Strategy; +const GoogleStrategy = require("passport-google-oauth20").Strategy; // TODO: find a more optimal folder structure to store these types of functions @@ -68,8 +68,8 @@ const initializePassport = async () => { passReqToCallback: true, clientID: googleClientId, clientSecret: googleClientSecret, - callbackURL: '/api/v1/auth/callback/google', - scope: ['profile', ' email'], + callbackURL: "/api/v1/auth/callback/google", + scope: ["profile", " email"], }, async ( req: express.Request, accessToken: string, @@ -82,7 +82,7 @@ const initializePassport = async () => { let user = await User.findOne({ authProvider: AuthProvider.GOOGLE, authId: profile.id, - }).select('+publicKey') + }).select("+publicKey") if (!user) { user = await new User({ @@ -97,7 +97,7 @@ const initializePassport = async () => { userId: user._id.toString(), email: user.email, authProvider: user.authProvider, - isUserCompleted: !!user.publicKey + isUserCompleted: !!user.publicKey, }, expiresIn: await getJwtProviderAuthLifetime(), secret: await getJwtProviderAuthSecret(), diff --git a/backend/src/utils/crypto/index.ts b/backend/src/utils/crypto/index.ts index 9c38777174..9194bd7e82 100644 --- a/backend/src/utils/crypto/index.ts +++ b/backend/src/utils/crypto/index.ts @@ -1,20 +1,19 @@ -import crypto from 'crypto'; -import nacl from 'tweetnacl'; -import util from 'tweetnacl-util'; +import crypto from "crypto"; +import nacl from "tweetnacl"; +import util from "tweetnacl-util"; import { - IGenerateKeyPairOutput, + IDecryptAsymmetricInput, + IDecryptSymmetricInput, IEncryptAsymmetricInput, IEncryptAsymmetricOutput, - IDecryptAsymmetricInput, IEncryptSymmetricInput, - IDecryptSymmetricInput -} from '../../interfaces/utils'; -import { BadRequestError } from '../errors'; + IGenerateKeyPairOutput, +} from "../../interfaces/utils"; +import { BadRequestError } from "../errors"; import { - ALGORITHM_AES_256_GCM, - NONCE_BYTES_SIZE, - BLOCK_SIZE_BYTES_16 -} from '../../variables'; + ALGORITHM_AES_256_GCM, + BLOCK_SIZE_BYTES_16, +} from "../../variables"; /** * Return new base64, NaCl, public-private key pair. @@ -27,7 +26,7 @@ const generateKeyPair = (): IGenerateKeyPairOutput => { return ({ publicKey: util.encodeBase64(pair.publicKey), - privateKey: util.encodeBase64(pair.secretKey) + privateKey: util.encodeBase64(pair.secretKey), }); } @@ -45,7 +44,7 @@ const generateKeyPair = (): IGenerateKeyPairOutput => { const encryptAsymmetric = ({ plaintext, publicKey, - privateKey + privateKey, }: IEncryptAsymmetricInput): IEncryptAsymmetricOutput => { const nonce = nacl.randomBytes(24); const ciphertext = nacl.box( @@ -57,7 +56,7 @@ const encryptAsymmetric = ({ return { ciphertext: util.encodeBase64(ciphertext), - nonce: util.encodeBase64(nonce) + nonce: util.encodeBase64(nonce), }; }; @@ -75,7 +74,7 @@ const decryptAsymmetric = ({ ciphertext, nonce, publicKey, - privateKey + privateKey, }: IDecryptAsymmetricInput): string => { const plaintext: Uint8Array | null = nacl.box.open( util.decodeBase64(ciphertext), @@ -85,7 +84,7 @@ const decryptAsymmetric = ({ ); if (plaintext == null) throw BadRequestError({ - message: 'Invalid ciphertext or keys' + message: "Invalid ciphertext or keys", }); return util.encodeUTF8(plaintext); @@ -108,18 +107,18 @@ const decryptAsymmetric = ({ */ const encryptSymmetric128BitHexKeyUTF8 = ({ plaintext, - key + key, }: IEncryptSymmetricInput) => { const iv = crypto.randomBytes(BLOCK_SIZE_BYTES_16); const cipher = crypto.createCipheriv(ALGORITHM_AES_256_GCM, key, iv); - let ciphertext = cipher.update(plaintext, 'utf8', 'base64'); - ciphertext += cipher.final('base64'); + let ciphertext = cipher.update(plaintext, "utf8", "base64"); + ciphertext += cipher.final("base64"); return { ciphertext, - iv: iv.toString('base64'), - tag: cipher.getAuthTag().toString('base64') + iv: iv.toString("base64"), + tag: cipher.getAuthTag().toString("base64"), }; } /** @@ -141,18 +140,18 @@ const decryptSymmetric128BitHexKeyUTF8 = ({ ciphertext, iv, tag, - key + key, }: IDecryptSymmetricInput) => { const decipher = crypto.createDecipheriv( ALGORITHM_AES_256_GCM, key, - Buffer.from(iv, 'base64') + Buffer.from(iv, "base64") ); - decipher.setAuthTag(Buffer.from(tag, 'base64')); + decipher.setAuthTag(Buffer.from(tag, "base64")); - let cleartext = decipher.update(ciphertext, 'base64', 'utf8'); - cleartext += decipher.final('utf8'); + let cleartext = decipher.update(ciphertext, "base64", "utf8"); + cleartext += decipher.final("utf8"); return cleartext; } @@ -162,5 +161,5 @@ export { encryptAsymmetric, decryptAsymmetric, encryptSymmetric128BitHexKeyUTF8, - decryptSymmetric128BitHexKeyUTF8 + decryptSymmetric128BitHexKeyUTF8, }; diff --git a/backend/src/utils/errors.ts b/backend/src/utils/errors.ts index 4b698bee3d..f99ef27b23 100644 --- a/backend/src/utils/errors.ts +++ b/backend/src/utils/errors.ts @@ -4,231 +4,231 @@ import RequestError, { LogLevel, RequestErrorContext } from "./requestError" export const RouteNotFoundError = (error?: Partial) => new RequestError({ logLevel: error?.logLevel ?? LogLevel.INFO, statusCode: error?.statusCode ?? 404, - type: error?.type ?? 'route_not_found', - message: error?.message ?? 'The requested source was not found', + type: error?.type ?? "route_not_found", + message: error?.message ?? "The requested source was not found", context: error?.context, - stack: error?.stack + stack: error?.stack, }); export const MethodNotAllowedError = (error?: Partial) => new RequestError({ logLevel: error?.logLevel ?? LogLevel.INFO, statusCode: error?.statusCode ?? 405, - type: error?.type ?? 'method_not_allowed', - message: error?.message ?? 'The requested method is not allowed for the resource', + type: error?.type ?? "method_not_allowed", + message: error?.message ?? "The requested method is not allowed for the resource", context: error?.context, - stack: error?.stack + stack: error?.stack, }); export const UnauthorizedRequestError = (error?: Partial) => new RequestError({ logLevel: error?.logLevel ?? LogLevel.INFO, statusCode: error?.statusCode ?? 401, - type: error?.type ?? 'unauthorized', - message: error?.message ?? 'You are not authorized to access this resource', + type: error?.type ?? "unauthorized", + message: error?.message ?? "You are not authorized to access this resource", context: error?.context, - stack: error?.stack + stack: error?.stack, }); export const ForbiddenRequestError = (error?: Partial) => new RequestError({ logLevel: error?.logLevel ?? LogLevel.INFO, statusCode: error?.statusCode ?? 403, - type: error?.type ?? 'forbidden', - message: error?.message ?? 'You are not allowed to access this resource', + type: error?.type ?? "forbidden", + message: error?.message ?? "You are not allowed to access this resource", context: error?.context, - stack: error?.stack + stack: error?.stack, }); export const BadRequestError = (error?: Partial) => new RequestError({ logLevel: error?.logLevel ?? LogLevel.INFO, statusCode: error?.statusCode ?? 400, - type: error?.type ?? 'bad_request', - message: error?.message ?? 'The request is invalid or cannot be served', + type: error?.type ?? "bad_request", + message: error?.message ?? "The request is invalid or cannot be served", context: error?.context, - stack: error?.stack + stack: error?.stack, }); export const InternalServerError = (error?: Partial) => new RequestError({ logLevel: error?.logLevel ?? LogLevel.ERROR, statusCode: error?.statusCode ?? 500, - type: error?.type ?? 'internal_server_error', - message: error?.message ?? 'The server encountered an error while processing the request', + type: error?.type ?? "internal_server_error", + message: error?.message ?? "The server encountered an error while processing the request", context: error?.context, - stack: error?.stack + stack: error?.stack, }); export const ServiceUnavailableError = (error?: Partial) => new RequestError({ logLevel: error?.logLevel ?? LogLevel.ERROR, statusCode: error?.statusCode ?? 503, - type: error?.type ?? 'service_unavailable', - message: error?.message ?? 'The service is currently unavailable. Please try again later.', + type: error?.type ?? "service_unavailable", + message: error?.message ?? "The service is currently unavailable. Please try again later.", context: error?.context, - stack: error?.stack + stack: error?.stack, }); export const ValidationError = (error?: Partial) => new RequestError({ logLevel: error?.logLevel ?? LogLevel.ERROR, statusCode: error?.statusCode ?? 400, - type: error?.type ?? 'validation_error', - message: error?.message ?? 'The request failed validation', + type: error?.type ?? "validation_error", + message: error?.message ?? "The request failed validation", context: error?.context, - stack: error?.stack + stack: error?.stack, }); //* ----->[INTEGRATION AUTH ERRORS]<----- export const IntegrationAuthNotFoundError = (error?: Partial) => new RequestError({ logLevel: error?.logLevel ?? LogLevel.ERROR, statusCode: error?.statusCode ?? 404, - type: error?.type ?? 'integration_auth_not_found_error', - message: error?.message ?? 'The requested integration authorization was not found', + type: error?.type ?? "integration_auth_not_found_error", + message: error?.message ?? "The requested integration authorization was not found", context: error?.context, - stack: error?.stack + stack: error?.stack, }); //* ----->[INTEGRATION ERRORS]<----- export const IntegrationNotFoundError = (error?: Partial) => new RequestError({ logLevel: error?.logLevel ?? LogLevel.ERROR, statusCode: error?.statusCode ?? 404, - type: error?.type ?? 'integration_not_found_error', - message: error?.message ?? 'The requested integration was not found', + type: error?.type ?? "integration_not_found_error", + message: error?.message ?? "The requested integration was not found", context: error?.context, - stack: error?.stack + stack: error?.stack, }); //* ----->[WORKSPACE ERRORS]<----- export const WorkspaceNotFoundError = (error?: Partial) => new RequestError({ logLevel: error?.logLevel ?? LogLevel.ERROR, statusCode: error?.statusCode ?? 404, - type: error?.type ?? 'workspace_not_found_error', - message: error?.message ?? 'The requested workspace was not found', + type: error?.type ?? "workspace_not_found_error", + message: error?.message ?? "The requested workspace was not found", context: error?.context, - stack: error?.stack + stack: error?.stack, }); //* ----->[WORKSPACE MEMBERSHIP ERRORS]<----- export const MembershipNotFoundError = (error?: Partial) => new RequestError({ logLevel: error?.logLevel ?? LogLevel.ERROR, statusCode: error?.statusCode ?? 404, - type: error?.type ?? 'workspace_membership_not_found_error', - message: error?.message ?? 'The requested membership was not found', + type: error?.type ?? "workspace_membership_not_found_error", + message: error?.message ?? "The requested membership was not found", context: error?.context, - stack: error?.stack + stack: error?.stack, }); //* ----->[ORGANIZATION ERRORS]<----- export const OrganizationNotFoundError = (error?: Partial) => new RequestError({ logLevel: error?.logLevel ?? LogLevel.ERROR, statusCode: error?.statusCode ?? 404, - type: error?.type ?? 'organization_not_found_error', - message: error?.message ?? 'The requested organization was not found', + type: error?.type ?? "organization_not_found_error", + message: error?.message ?? "The requested organization was not found", context: error?.context, - stack: error?.stack + stack: error?.stack, }); //* ----->[MEMBERSHIP ORGANIZATION ERRORS]<----- export const MembershipOrgNotFoundError = (error?: Partial) => new RequestError({ logLevel: error?.logLevel ?? LogLevel.ERROR, statusCode: error?.statusCode ?? 404, - type: error?.type ?? 'organization_membership_not_found_error', - message: error?.message ?? 'The requested organization membership was not found', + type: error?.type ?? "organization_membership_not_found_error", + message: error?.message ?? "The requested organization membership was not found", context: error?.context, - stack: error?.stack + stack: error?.stack, }); //* ----->[ACCOUNT ERRORS]<----- export const AccountNotFoundError = (error?: Partial) => new RequestError({ logLevel: error?.logLevel ?? LogLevel.ERROR, statusCode: error?.statusCode ?? 404, - type: error?.type ?? 'account_not_found_error', - message: error?.message ?? 'The requested account was not found', + type: error?.type ?? "account_not_found_error", + message: error?.message ?? "The requested account was not found", context: error?.context, - stack: error?.stack + stack: error?.stack, }); //* ----->[SECRET ERRORS]<----- export const SecretNotFoundError = (error?: Partial) => new RequestError({ logLevel: error?.logLevel ?? LogLevel.ERROR, statusCode: error?.statusCode ?? 404, - type: error?.type ?? 'secret_not_found_error', - message: error?.message ?? 'The requested secret was not found', + type: error?.type ?? "secret_not_found_error", + message: error?.message ?? "The requested secret was not found", context: error?.context, - stack: error?.stack + stack: error?.stack, }); //* ----->[SECRET BLIND INDEX DATA ERRORS]<----- export const SecretBlindIndexDataNotFoundError = (error?: Partial) => new RequestError({ logLevel: error?.logLevel ?? LogLevel.ERROR, statusCode: error?.statusCode ?? 404, - type: error?.type ?? 'secret_blind_index_data_not_found_error', - message: error?.message ?? 'The requested secret was not found', + type: error?.type ?? "secret_blind_index_data_not_found_error", + message: error?.message ?? "The requested secret was not found", context: error?.context, - stack: error?.stack + stack: error?.stack, }); //* ----->[SECRET SNAPSHOT ERRORS]<----- export const SecretSnapshotNotFoundError = (error?: Partial) => new RequestError({ logLevel: error?.logLevel ?? LogLevel.ERROR, statusCode: error?.statusCode ?? 404, - type: error?.type ?? 'secret_snapshot_not_found_error', - message: error?.message ?? 'The requested secret snapshot was not found', + type: error?.type ?? "secret_snapshot_not_found_error", + message: error?.message ?? "The requested secret snapshot was not found", context: error?.context, - stack: error?.stack + stack: error?.stack, }); //* ----->[ACTION ERRORS]<----- export const ActionNotFoundError = (error?: Partial) => new RequestError({ logLevel: error?.logLevel ?? LogLevel.ERROR, statusCode: error?.statusCode ?? 404, - type: error?.type ?? 'action_not_found_error', - message: error?.message ?? 'The requested action was not found', + type: error?.type ?? "action_not_found_error", + message: error?.message ?? "The requested action was not found", context: error?.context, - stack: error?.stack + stack: error?.stack, }); //* ----->[SERVICE TOKEN DATA ERRORS]<----- export const ServiceTokenDataNotFoundError = (error?: Partial) => new RequestError({ logLevel: error?.logLevel ?? LogLevel.ERROR, statusCode: error?.statusCode ?? 404, - type: error?.type ?? 'service_token_data_not_found_error', - message: error?.message ?? 'The requested service token data was not found', + type: error?.type ?? "service_token_data_not_found_error", + message: error?.message ?? "The requested service token data was not found", context: error?.context, - stack: error?.stack + stack: error?.stack, }) //* ----->[API KEY DATA ERRORS]<----- export const APIKeyDataNotFoundError = (error?: Partial) => new RequestError({ logLevel: error?.logLevel ?? LogLevel.ERROR, statusCode: error?.statusCode ?? 404, - type: error?.type ?? 'api_key_data_not_found_error', - message: error?.message ?? 'The requested service token data was not found', + type: error?.type ?? "api_key_data_not_found_error", + message: error?.message ?? "The requested service token data was not found", context: error?.context, - stack: error?.stack + stack: error?.stack, }); //* ----->[SERVICE_ACCOUNT ERRORS]<----- export const ServiceAccountNotFoundError = (error?: Partial) => new RequestError({ logLevel: error?.logLevel ?? LogLevel.ERROR, statusCode: error?.statusCode ?? 404, - type: error?.type ?? 'service_account_not_found_error', - message: error?.message ?? 'The requested service account was not found', + type: error?.type ?? "service_account_not_found_error", + message: error?.message ?? "The requested service account was not found", context: error?.context, - stack: error?.stack + stack: error?.stack, }); export const ServiceAccountKeyNotFoundError = (error?: Partial) => new RequestError({ logLevel: error?.logLevel ?? LogLevel.ERROR, statusCode: error?.statusCode ?? 404, - type: error?.type ?? 'service_account_key_not_found_error', - message: error?.message ?? 'The requested service account key was not found', + type: error?.type ?? "service_account_key_not_found_error", + message: error?.message ?? "The requested service account key was not found", context: error?.context, - stack: error?.stack + stack: error?.stack, }) export const BotNotFoundError = (error?: Partial) => new RequestError({ logLevel: error?.logLevel ?? LogLevel.ERROR, statusCode: error?.statusCode ?? 404, - type: error?.type ?? 'bot_not_found_error', - message: error?.message ?? 'The requested bot was not found', + type: error?.type ?? "bot_not_found_error", + message: error?.message ?? "The requested bot was not found", context: error?.context, - stack: error?.stack + stack: error?.stack, }) //* ----->[MISC ERRORS]<----- diff --git a/backend/src/utils/logger.ts b/backend/src/utils/logger.ts index 15335a619c..9673f1115c 100644 --- a/backend/src/utils/logger.ts +++ b/backend/src/utils/logger.ts @@ -1,7 +1,7 @@ /* eslint-disable no-console */ -import { createLogger, format, transports } from 'winston'; -import LokiTransport from 'winston-loki'; -import { getLokiHost, getNodeEnv } from '../config'; +import { createLogger, format, transports } from "winston"; +import LokiTransport from "winston-loki"; +import { getLokiHost, getNodeEnv } from "../config"; const { combine, colorize, label, printf, splat, timestamp } = format; @@ -13,7 +13,7 @@ const logFormat = (prefix: string) => combine( ); const createLoggerWithLabel = async (level: string, label: string) => { - const _level = level.toLowerCase() || 'info' + const _level = level.toLowerCase() || "info" //* Always add Console output to transports const _transports: any[] = [ new transports.Console({ @@ -21,8 +21,8 @@ const createLoggerWithLabel = async (level: string, label: string) => { colorize(), logFormat(label), // format.json() - ) - }) + ), + }), ] //* Add LokiTransport if it's enabled if((await getLokiHost()) !== undefined){ @@ -40,9 +40,9 @@ const createLoggerWithLabel = async (level: string, label: string) => { labels: { app: process.env.npm_package_name, version: process.env.npm_package_version, - environment: await getNodeEnv() + environment: await getNodeEnv(), }, - onConnectionError: (err: Error)=> console.error('Connection error while connecting to Loki Server.\n', err) + onConnectionError: (err: Error)=> console.error("Connection error while connecting to Loki Server.\n", err), }) ) } @@ -53,15 +53,15 @@ const createLoggerWithLabel = async (level: string, label: string) => { transports: _transports, format: format.combine( logFormat(label), - format.metadata({ fillExcept: ['message', 'level', 'timestamp', 'label'] }) - ) + format.metadata({ fillExcept: ["message", "level", "timestamp", "label"] }) + ), }); } -export const getLogger = async (loggerName: 'backend-main' | 'database') => { +export const getLogger = async (loggerName: "backend-main" | "database") => { const logger = { - "backend-main": await createLoggerWithLabel('info', '[IFSC:backend-main]'), - "database": await createLoggerWithLabel('info', '[IFSC:database]'), + "backend-main": await createLoggerWithLabel("info", "[IFSC:backend-main]"), + "database": await createLoggerWithLabel("info", "[IFSC:database]"), } return logger[loggerName] } diff --git a/backend/src/utils/posthog.ts b/backend/src/utils/posthog.ts index 85a411ca76..06c4048888 100644 --- a/backend/src/utils/posthog.ts +++ b/backend/src/utils/posthog.ts @@ -7,7 +7,7 @@ export const getChannelFromUserAgent = function (userAgent: string | undefined) return "cli" } else if (userAgent == K8_OPERATOR_AGENT_NAME) { return "k8-operator" - } else if (userAgent.toLowerCase().includes('mozilla')) { + } else if (userAgent.toLowerCase().includes("mozilla")) { return "web" } else { return "other" diff --git a/backend/src/utils/requestError.ts b/backend/src/utils/requestError.ts index 570ed132ed..0c4e093b23 100644 --- a/backend/src/utils/requestError.ts +++ b/backend/src/utils/requestError.ts @@ -1,5 +1,5 @@ -import { Request } from 'express' -import { getVerboseErrorOutput } from '../config'; +import { Request } from "express" +import { getVerboseErrorOutput } from "../config"; export enum LogLevel { DEBUG = 100, @@ -44,7 +44,7 @@ export default class RequestError extends Error{ if(stack) this.stack = stack else Error.captureStackTrace(this, this.constructor) - this.stacktrace = this.stack?.split('\n') + this.stacktrace = this.stack?.split("\n") } static convertFrom(error: Error) { @@ -52,13 +52,13 @@ export default class RequestError extends Error{ return new RequestError({ logLevel: LogLevel.ERROR, statusCode: 500, - type: 'internal_server_error', - message: 'This error was not handled by error handler. Please report this incident to the staff', + type: "internal_server_error", + message: "This error was not handled by error handler. Please report this incident to the staff", context: { message: error.message, - name: error.name + name: error.name, }, - stack: error.stack + stack: error.stack, }) } @@ -66,7 +66,7 @@ export default class RequestError extends Error{ get levelName(){ return this._logName } withTags(...tags: string[]|number[]){ - this.context['tags'] = Object.assign(tags, this.context['tags']) + this.context["tags"] = Object.assign(tags, this.context["tags"]) return this } @@ -83,14 +83,14 @@ export default class RequestError extends Error{ public async format(req: Request){ let _context = Object.assign({ - stacktrace: this.stacktrace + stacktrace: this.stacktrace, }, this.context) //* Omit sensitive information from context that can leak internal workings of this program if user is not developer if(!(await getVerboseErrorOutput())){ _context = this._omit(_context, [ - 'stacktrace', - 'exception', + "stacktrace", + "exception", ]) } @@ -102,9 +102,9 @@ export default class RequestError extends Error{ level_name: this.levelName, status_code: this.statusCode, datetime_iso: new Date().toISOString(), - application: process.env.npm_package_name || 'unknown', + application: process.env.npm_package_name || "unknown", request_id: req.headers["Request-Id"], - extra: this.extra + extra: this.extra, } return formatObject diff --git a/backend/src/utils/setup/backfillData.ts b/backend/src/utils/setup/backfillData.ts index af05cfab78..a77d3ee275 100644 --- a/backend/src/utils/setup/backfillData.ts +++ b/backend/src/utils/setup/backfillData.ts @@ -5,22 +5,22 @@ import { encryptSymmetric128BitHexKeyUTF8 } from "../crypto"; import { EESecretService } from "../../ee/services"; import { ISecretVersion, SecretSnapshot, SecretVersion } from "../../ee/models"; import { - Secret, - ISecret, - SecretBlindIndexData, - Workspace, - Bot, BackupPrivateKey, - IntegrationAuth, - ServiceTokenData, + Bot, + ISecret, Integration, + IntegrationAuth, + Secret, + SecretBlindIndexData, + ServiceTokenData, + Workspace, } from "../../models"; import { generateKeyPair } from "../../utils/crypto"; import { client, getEncryptionKey, getRootEncryptionKey } from "../../config"; import { ALGORITHM_AES_256_GCM, - ENCODING_SCHEME_UTF8, ENCODING_SCHEME_BASE64, + ENCODING_SCHEME_UTF8, } from "../../variables"; import { InternalServerError } from "../errors"; diff --git a/backend/src/utils/setup/index.ts b/backend/src/utils/setup/index.ts index d7f333b17d..16d9ee1ae3 100644 --- a/backend/src/utils/setup/index.ts +++ b/backend/src/utils/setup/index.ts @@ -7,24 +7,24 @@ import { createTestUserForDevelopment } from "../addDevelopmentUser"; // eslint-disable-next-line @typescript-eslint/no-var-requires import { validateEncryptionKeysConfig } from "./validateConfig"; import { - backfillSecretVersions, backfillBots, - backfillSecretBlindIndexData, backfillEncryptionMetadata, - backfillSecretFolders, - backfillServiceToken, backfillIntegration, + backfillSecretBlindIndexData, + backfillSecretFolders, + backfillSecretVersions, + backfillServiceToken, } from "./backfillData"; import { reencryptBotPrivateKeys, reencryptSecretBlindIndexDataSalts, } from "./reencryptData"; import { - getNodeEnv, - getMongoURL, - getSentryDSN, - getClientSecretGoogle, getClientIdGoogle, + getClientSecretGoogle, + getMongoURL, + getNodeEnv, + getSentryDSN, } from "../../config"; import { initializePassport } from "../auth"; diff --git a/backend/src/utils/setup/reencryptData.ts b/backend/src/utils/setup/reencryptData.ts index 0741b44f40..7ea5db2026 100644 --- a/backend/src/utils/setup/reencryptData.ts +++ b/backend/src/utils/setup/reencryptData.ts @@ -2,19 +2,19 @@ import { Bot, IBot, ISecretBlindIndexData, - SecretBlindIndexData -} from '../../models'; -import { decryptSymmetric128BitHexKeyUTF8 } from '../../utils/crypto'; + SecretBlindIndexData, +} from "../../models"; +import { decryptSymmetric128BitHexKeyUTF8 } from "../../utils/crypto"; import { client, getEncryptionKey, - getRootEncryptionKey -} from '../../config'; + getRootEncryptionKey, +} from "../../config"; import { ALGORITHM_AES_256_GCM, + ENCODING_SCHEME_BASE64, ENCODING_SCHEME_UTF8, - ENCODING_SCHEME_BASE64 -} from '../../variables'; +} from "../../variables"; /** * Re-encrypt bot private keys from hex 128-bit ENCRYPTION_KEY @@ -28,8 +28,8 @@ export const reencryptBotPrivateKeys = async () => { // 1: re-encrypt bot private keys under ROOT_ENCRYPTION_KEY const bots = await Bot.find({ algorithm: ALGORITHM_AES_256_GCM, - keyEncoding: ENCODING_SCHEME_UTF8 - }).select('+encryptedPrivateKey iv tag algorithm keyEncoding'); + keyEncoding: ENCODING_SCHEME_UTF8, + }).select("+encryptedPrivateKey iv tag algorithm keyEncoding"); if (bots.length === 0) return; @@ -40,28 +40,28 @@ export const reencryptBotPrivateKeys = async () => { ciphertext: bot.encryptedPrivateKey, iv: bot.iv, tag: bot.tag, - key: encryptionKey + key: encryptionKey, }); const { ciphertext: encryptedPrivateKey, iv, - tag + tag, } = client.encryptSymmetric(privateKey, rootEncryptionKey); return ({ updateOne: { filter: { - _id: bot._id + _id: bot._id, }, update: { encryptedPrivateKey, iv, tag, algorithm: ALGORITHM_AES_256_GCM, - keyEncoding: ENCODING_SCHEME_BASE64 - } - } + keyEncoding: ENCODING_SCHEME_BASE64, + }, + }, }) }) ); @@ -81,8 +81,8 @@ export const reencryptSecretBlindIndexDataSalts = async () => { if (encryptionKey && rootEncryptionKey) { const secretBlindIndexData = await SecretBlindIndexData.find({ algorithm: ALGORITHM_AES_256_GCM, - keyEncoding: ENCODING_SCHEME_UTF8 - }).select('+encryptedSaltCiphertext +saltIV +saltTag +algorithm +keyEncoding'); + keyEncoding: ENCODING_SCHEME_UTF8, + }).select("+encryptedSaltCiphertext +saltIV +saltTag +algorithm +keyEncoding"); if (secretBlindIndexData.length == 0) return; @@ -93,28 +93,28 @@ export const reencryptSecretBlindIndexDataSalts = async () => { ciphertext: secretBlindIndexDatum.encryptedSaltCiphertext, iv: secretBlindIndexDatum.saltIV, tag: secretBlindIndexDatum.saltTag, - key: encryptionKey + key: encryptionKey, }); const { ciphertext: encryptedSaltCiphertext, iv: saltIV, - tag: saltTag + tag: saltTag, } = client.encryptSymmetric(salt, rootEncryptionKey); return ({ updateOne: { filter: { - _id: secretBlindIndexDatum._id + _id: secretBlindIndexDatum._id, }, update: { encryptedSaltCiphertext, saltIV, saltTag, algorithm: ALGORITHM_AES_256_GCM, - keyEncoding: ENCODING_SCHEME_BASE64 - } - } + keyEncoding: ENCODING_SCHEME_BASE64, + }, + }, }) }) ); diff --git a/backend/src/utils/setup/validateConfig.ts b/backend/src/utils/setup/validateConfig.ts index f8ebd3c175..3a39747913 100644 --- a/backend/src/utils/setup/validateConfig.ts +++ b/backend/src/utils/setup/validateConfig.ts @@ -1,10 +1,10 @@ import { getEncryptionKey, - getRootEncryptionKey -} from '../../config'; + getRootEncryptionKey, +} from "../../config"; import { - InternalServerError -} from '../../utils/errors'; + InternalServerError, +} from "../../utils/errors"; /** * Validate ENCRYPTION_KEY and ROOT_ENCRYPTION_KEY. Specifically: @@ -26,7 +26,7 @@ export const validateEncryptionKeysConfig = async () => { (encryptionKey === undefined || encryptionKey === "") && (rootEncryptionKey === undefined || rootEncryptionKey === "") ) throw InternalServerError({ - message: "Failed to find required root encryption key environment variable. Please make sure that you're passing in a ROOT_ENCRYPTION_KEY environment variable." + message: "Failed to find required root encryption key environment variable. Please make sure that you're passing in a ROOT_ENCRYPTION_KEY environment variable.", }); // if (encryptionKey && encryptionKey !== '') { @@ -44,18 +44,18 @@ export const validateEncryptionKeysConfig = async () => { // }); // } - if (rootEncryptionKey && rootEncryptionKey !== '') { + if (rootEncryptionKey && rootEncryptionKey !== "") { // validate [rootEncryptionKey] - const keyBuffer = Buffer.from(rootEncryptionKey, 'base64') - const decoded = keyBuffer.toString('base64'); + const keyBuffer = Buffer.from(rootEncryptionKey, "base64") + const decoded = keyBuffer.toString("base64"); if (decoded !== rootEncryptionKey) throw InternalServerError({ - message: 'Failed to validate that the root encryption key is correctly encoded in base64' + message: "Failed to validate that the root encryption key is correctly encoded in base64", }); if (keyBuffer.length !== 32) throw InternalServerError({ - message: 'Failed to validate that the encryption key is a 256-bit base64 string' + message: "Failed to validate that the encryption key is a 256-bit base64 string", }); } } \ No newline at end of file diff --git a/backend/src/validation/bot.ts b/backend/src/validation/bot.ts index 7104eec331..7e19ca7709 100644 --- a/backend/src/validation/bot.ts +++ b/backend/src/validation/bot.ts @@ -1,25 +1,25 @@ -import { Types } from 'mongoose'; +import { Types } from "mongoose"; import { - IUser, + Bot, IServiceAccount, IServiceTokenData, - Bot, - User, + IUser, ServiceAccount, - ServiceTokenData -} from '../models'; -import { validateServiceAccountClientForWorkspace } from './serviceAccount'; -import { validateUserClientForWorkspace } from './user'; + ServiceTokenData, + User, +} from "../models"; +import { validateServiceAccountClientForWorkspace } from "./serviceAccount"; +import { validateUserClientForWorkspace } from "./user"; import { + BotNotFoundError, UnauthorizedRequestError, - BotNotFoundError -} from '../utils/errors'; +} from "../utils/errors"; import { + AUTH_MODE_API_KEY, AUTH_MODE_JWT, AUTH_MODE_SERVICE_ACCOUNT, AUTH_MODE_SERVICE_TOKEN, - AUTH_MODE_API_KEY -} from '../variables'; +} from "../variables"; /** * Validate authenticated clients for bot with id [botId] based diff --git a/backend/src/validation/index.ts b/backend/src/validation/index.ts index 177c716ea3..4cc25450ff 100644 --- a/backend/src/validation/index.ts +++ b/backend/src/validation/index.ts @@ -1,11 +1,11 @@ -export * from './user'; -export * from './workspace'; -export * from './bot'; -export * from './integration'; -export * from './integrationAuth'; -export * from './membership'; -export * from './membershipOrg'; -export * from './organization'; -export * from './secrets'; -export * from './serviceAccount'; -export * from './serviceTokenData'; \ No newline at end of file +export * from "./user"; +export * from "./workspace"; +export * from "./bot"; +export * from "./integration"; +export * from "./integrationAuth"; +export * from "./membership"; +export * from "./membershipOrg"; +export * from "./organization"; +export * from "./secrets"; +export * from "./serviceAccount"; +export * from "./serviceTokenData"; \ No newline at end of file diff --git a/backend/src/validation/integration.ts b/backend/src/validation/integration.ts index 5b2f4ad3c5..3f39a87b66 100644 --- a/backend/src/validation/integration.ts +++ b/backend/src/validation/integration.ts @@ -1,28 +1,28 @@ -import { Types } from 'mongoose'; +import { Types } from "mongoose"; import { - IUser, IServiceAccount, IServiceTokenData, + IUser, Integration, IntegrationAuth, - User, ServiceAccount, - ServiceTokenData -} from '../models'; -import { validateServiceAccountClientForWorkspace } from './serviceAccount'; -import { validateUserClientForWorkspace } from './user'; -import { IntegrationService } from '../services'; + ServiceTokenData, + User, +} from "../models"; +import { validateServiceAccountClientForWorkspace } from "./serviceAccount"; +import { validateUserClientForWorkspace } from "./user"; +import { IntegrationService } from "../services"; import { - IntegrationNotFoundError, IntegrationAuthNotFoundError, - UnauthorizedRequestError -} from '../utils/errors'; + IntegrationNotFoundError, + UnauthorizedRequestError, +} from "../utils/errors"; import { + AUTH_MODE_API_KEY, AUTH_MODE_JWT, AUTH_MODE_SERVICE_ACCOUNT, AUTH_MODE_SERVICE_TOKEN, - AUTH_MODE_API_KEY -} from '../variables'; +} from "../variables"; /** * Validate authenticated clients for integration with id [integrationId] based @@ -37,14 +37,14 @@ import { export const validateClientForIntegration = async ({ authData, integrationId, - acceptedRoles + acceptedRoles, }: { authData: { authMode: string; authPayload: IUser | IServiceAccount | IServiceTokenData; }; integrationId: Types.ObjectId; - acceptedRoles: Array<'admin' | 'member'>; + acceptedRoles: Array<"admin" | "member">; }) => { const integration = await Integration.findById(integrationId); @@ -53,20 +53,20 @@ export const validateClientForIntegration = async ({ const integrationAuth = await IntegrationAuth .findById(integration.integrationAuth) .select( - '+refreshCiphertext +refreshIV +refreshTag +accessCiphertext +accessIV +accessTag +accessExpiresAt' + "+refreshCiphertext +refreshIV +refreshTag +accessCiphertext +accessIV +accessTag +accessExpiresAt" ); if (!integrationAuth) throw IntegrationAuthNotFoundError(); const accessToken = (await IntegrationService.getIntegrationAuthAccess({ - integrationAuthId: integrationAuth._id + integrationAuthId: integrationAuth._id, })).accessToken; if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) { await validateUserClientForWorkspace({ user: authData.authPayload, workspaceId: integration.workspace, - acceptedRoles + acceptedRoles, }); return ({ integration, accessToken }); @@ -75,7 +75,7 @@ export const validateClientForIntegration = async ({ if (authData.authMode === AUTH_MODE_SERVICE_ACCOUNT && authData.authPayload instanceof ServiceAccount) { await validateServiceAccountClientForWorkspace({ serviceAccount: authData.authPayload, - workspaceId: integration.workspace + workspaceId: integration.workspace, }); return ({ integration, accessToken }); @@ -83,7 +83,7 @@ export const validateClientForIntegration = async ({ if (authData.authMode === AUTH_MODE_SERVICE_TOKEN && authData.authPayload instanceof ServiceTokenData) { throw UnauthorizedRequestError({ - message: 'Failed service token authorization for integration' + message: "Failed service token authorization for integration", }); } @@ -91,13 +91,13 @@ export const validateClientForIntegration = async ({ await validateUserClientForWorkspace({ user: authData.authPayload, workspaceId: integration.workspace, - acceptedRoles + acceptedRoles, }); return ({ integration, accessToken }); } throw UnauthorizedRequestError({ - message: 'Failed client authorization for integration' + message: "Failed client authorization for integration", }); } \ No newline at end of file diff --git a/backend/src/validation/integrationAuth.ts b/backend/src/validation/integrationAuth.ts index e93af154d2..fa77f3d628 100644 --- a/backend/src/validation/integrationAuth.ts +++ b/backend/src/validation/integrationAuth.ts @@ -1,27 +1,27 @@ -import { Types } from 'mongoose'; +import { Types } from "mongoose"; import { - IntegrationAuth, - IUser, - User, IServiceAccount, - ServiceAccount, IServiceTokenData, + IUser, + IWorkspace, + IntegrationAuth, + ServiceAccount, ServiceTokenData, - IWorkspace -} from '../models'; + User, +} from "../models"; import { + AUTH_MODE_API_KEY, AUTH_MODE_JWT, AUTH_MODE_SERVICE_ACCOUNT, AUTH_MODE_SERVICE_TOKEN, - AUTH_MODE_API_KEY -} from '../variables'; +} from "../variables"; import { IntegrationAuthNotFoundError, - UnauthorizedRequestError -} from '../utils/errors'; -import { IntegrationService } from '../services'; -import { validateUserClientForWorkspace } from './user'; -import { validateServiceAccountClientForWorkspace } from './serviceAccount'; + UnauthorizedRequestError, +} from "../utils/errors"; +import { IntegrationService } from "../services"; +import { validateUserClientForWorkspace } from "./user"; +import { validateServiceAccountClientForWorkspace } from "./serviceAccount"; /** * Validate authenticated clients for integration authorization with id [integrationAuthId] based @@ -36,22 +36,22 @@ import { validateServiceAccountClientForWorkspace } from './serviceAccount'; authData, integrationAuthId, acceptedRoles, - attachAccessToken + attachAccessToken, }: { authData: { authMode: string; authPayload: IUser | IServiceAccount | IServiceTokenData; }; integrationAuthId: Types.ObjectId; - acceptedRoles: Array<'admin' | 'member'>; + acceptedRoles: Array<"admin" | "member">; attachAccessToken?: boolean; }) => { const integrationAuth = await IntegrationAuth .findById(integrationAuthId) - .populate<{ workspace: IWorkspace }>('workspace') + .populate<{ workspace: IWorkspace }>("workspace") .select( - '+refreshCiphertext +refreshIV +refreshTag +accessCiphertext +accessIV +accessTag +accessExpiresAt' + "+refreshCiphertext +refreshIV +refreshTag +accessCiphertext +accessIV +accessTag +accessExpiresAt" ); if (!integrationAuth) throw IntegrationAuthNotFoundError(); @@ -59,7 +59,7 @@ import { validateServiceAccountClientForWorkspace } from './serviceAccount'; let accessToken, accessId; if (attachAccessToken) { const access = (await IntegrationService.getIntegrationAuthAccess({ - integrationAuthId: integrationAuth._id + integrationAuthId: integrationAuth._id, })); accessToken = access.accessToken; @@ -70,7 +70,7 @@ import { validateServiceAccountClientForWorkspace } from './serviceAccount'; await validateUserClientForWorkspace({ user: authData.authPayload, workspaceId: integrationAuth.workspace._id, - acceptedRoles + acceptedRoles, }); return ({ integrationAuth, accessToken, accessId }); @@ -79,7 +79,7 @@ import { validateServiceAccountClientForWorkspace } from './serviceAccount'; if (authData.authMode === AUTH_MODE_SERVICE_ACCOUNT && authData.authPayload instanceof ServiceAccount) { await validateServiceAccountClientForWorkspace({ serviceAccount: authData.authPayload, - workspaceId: integrationAuth.workspace._id + workspaceId: integrationAuth.workspace._id, }); return ({ integrationAuth, accessToken, accessId }); @@ -87,7 +87,7 @@ import { validateServiceAccountClientForWorkspace } from './serviceAccount'; if (authData.authMode === AUTH_MODE_SERVICE_TOKEN && authData.authPayload instanceof ServiceTokenData) { throw UnauthorizedRequestError({ - message: 'Failed service token authorization for integration authorization' + message: "Failed service token authorization for integration authorization", }); } @@ -95,17 +95,17 @@ import { validateServiceAccountClientForWorkspace } from './serviceAccount'; await validateUserClientForWorkspace({ user: authData.authPayload, workspaceId: integrationAuth.workspace._id, - acceptedRoles + acceptedRoles, }); return ({ integrationAuth, accessToken, accessId }); } throw UnauthorizedRequestError({ - message: 'Failed client authorization for integration authorization' + message: "Failed client authorization for integration authorization", }); } export { - validateClientForIntegrationAuth + validateClientForIntegrationAuth, }; \ No newline at end of file diff --git a/backend/src/validation/membership.ts b/backend/src/validation/membership.ts index ab4f8dc76e..aee5f8bcac 100644 --- a/backend/src/validation/membership.ts +++ b/backend/src/validation/membership.ts @@ -1,26 +1,26 @@ -import { Types } from 'mongoose'; +import { Types } from "mongoose"; import { - IUser, IServiceAccount, IServiceTokenData, + IUser, Membership, - User, ServiceAccount, - ServiceTokenData -} from '../models'; -import { validateServiceAccountClientForWorkspace } from './serviceAccount'; -import { validateUserClientForWorkspace } from './user'; -import { validateServiceTokenDataClientForWorkspace } from './serviceTokenData'; + ServiceTokenData, + User, +} from "../models"; +import { validateServiceAccountClientForWorkspace } from "./serviceAccount"; +import { validateUserClientForWorkspace } from "./user"; +import { validateServiceTokenDataClientForWorkspace } from "./serviceTokenData"; import { MembershipNotFoundError, - UnauthorizedRequestError -} from '../utils/errors'; + UnauthorizedRequestError, +} from "../utils/errors"; import { + AUTH_MODE_API_KEY, AUTH_MODE_JWT, AUTH_MODE_SERVICE_ACCOUNT, AUTH_MODE_SERVICE_TOKEN, - AUTH_MODE_API_KEY -} from '../variables'; +} from "../variables"; /** * Validate authenticated clients for membership with id [membershipId] based @@ -34,27 +34,27 @@ import { export const validateClientForMembership = async ({ authData, membershipId, - acceptedRoles + acceptedRoles, }: { authData: { authMode: string; authPayload: IUser | IServiceAccount | IServiceTokenData; }; membershipId: Types.ObjectId; - acceptedRoles: Array<'admin' | 'member'>; + acceptedRoles: Array<"admin" | "member">; }) => { const membership = await Membership.findById(membershipId); if (!membership) throw MembershipNotFoundError({ - message: 'Failed to find membership' + message: "Failed to find membership", }); if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) { await validateUserClientForWorkspace({ user: authData.authPayload, workspaceId: membership.workspace, - acceptedRoles + acceptedRoles, }); return membership; @@ -63,7 +63,7 @@ export const validateClientForMembership = async ({ if (authData.authMode === AUTH_MODE_SERVICE_ACCOUNT && authData.authPayload instanceof ServiceAccount) { await validateServiceAccountClientForWorkspace({ serviceAccount: authData.authPayload, - workspaceId: membership.workspace + workspaceId: membership.workspace, }); return membership; @@ -72,7 +72,7 @@ export const validateClientForMembership = async ({ if (authData.authMode === AUTH_MODE_SERVICE_TOKEN && authData.authPayload instanceof ServiceTokenData) { await validateServiceTokenDataClientForWorkspace({ serviceTokenData: authData.authPayload, - workspaceId: new Types.ObjectId(membership.workspace) + workspaceId: new Types.ObjectId(membership.workspace), }); return membership; @@ -82,13 +82,13 @@ export const validateClientForMembership = async ({ await validateUserClientForWorkspace({ user: authData.authPayload, workspaceId: membership.workspace, - acceptedRoles + acceptedRoles, }); return membership; } throw UnauthorizedRequestError({ - message: 'Failed client authorization for membership' + message: "Failed client authorization for membership", }); } \ No newline at end of file diff --git a/backend/src/validation/membershipOrg.ts b/backend/src/validation/membershipOrg.ts index 7fd86a374b..444f2aa2a0 100644 --- a/backend/src/validation/membershipOrg.ts +++ b/backend/src/validation/membershipOrg.ts @@ -1,26 +1,26 @@ -import { Types } from 'mongoose'; +import { Types } from "mongoose"; import { - IUser, IServiceAccount, IServiceTokenData, + IUser, MembershipOrg, - User, ServiceAccount, - ServiceTokenData -} from '../models'; + ServiceTokenData, + User, +} from "../models"; import { - validateMembershipOrg -} from '../helpers/membershipOrg'; + validateMembershipOrg, +} from "../helpers/membershipOrg"; import { MembershipOrgNotFoundError, - UnauthorizedRequestError -} from '../utils/errors'; + UnauthorizedRequestError, +} from "../utils/errors"; import { + AUTH_MODE_API_KEY, AUTH_MODE_JWT, AUTH_MODE_SERVICE_ACCOUNT, AUTH_MODE_SERVICE_TOKEN, - AUTH_MODE_API_KEY -} from '../variables'; +} from "../variables"; /** * Validate authenticated clients for organization membership with id [membershipOrgId] based @@ -35,20 +35,20 @@ export const validateClientForMembershipOrg = async ({ authData, membershipOrgId, acceptedRoles, - acceptedStatuses + acceptedStatuses, }: { authData: { authMode: string; authPayload: IUser | IServiceAccount | IServiceTokenData; }; membershipOrgId: Types.ObjectId; - acceptedRoles: Array<'owner' | 'admin' | 'member'>; - acceptedStatuses: Array<'invited' | 'accepted'>; + acceptedRoles: Array<"owner" | "admin" | "member">; + acceptedStatuses: Array<"invited" | "accepted">; }) => { const membershipOrg = await MembershipOrg.findById(membershipOrgId); if (!membershipOrg) throw MembershipOrgNotFoundError({ - message: 'Failed to find organization membership ' + message: "Failed to find organization membership ", }); if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) { @@ -56,7 +56,7 @@ export const validateClientForMembershipOrg = async ({ userId: authData.authPayload._id, organizationId: membershipOrg.organization, acceptedRoles, - acceptedStatuses + acceptedStatuses, }); return membershipOrg; @@ -64,7 +64,7 @@ export const validateClientForMembershipOrg = async ({ if (authData.authMode === AUTH_MODE_SERVICE_ACCOUNT && authData.authPayload instanceof ServiceAccount) { if (!authData.authPayload.organization.equals(membershipOrg.organization)) throw UnauthorizedRequestError({ - message: 'Failed service account client authorization for organization membership' + message: "Failed service account client authorization for organization membership", }); return membershipOrg; @@ -72,7 +72,7 @@ export const validateClientForMembershipOrg = async ({ if (authData.authMode === AUTH_MODE_SERVICE_TOKEN && authData.authPayload instanceof ServiceTokenData) { throw UnauthorizedRequestError({ - message: 'Failed service account client authorization for organization membership' + message: "Failed service account client authorization for organization membership", }); } @@ -81,13 +81,13 @@ export const validateClientForMembershipOrg = async ({ userId: authData.authPayload._id, organizationId: membershipOrg.organization, acceptedRoles, - acceptedStatuses + acceptedStatuses, }); return membershipOrg; } throw UnauthorizedRequestError({ - message: 'Failed client authorization for organization membership' + message: "Failed client authorization for organization membership", }); } \ No newline at end of file diff --git a/backend/src/validation/organization.ts b/backend/src/validation/organization.ts index 239517b75e..35e0aab042 100644 --- a/backend/src/validation/organization.ts +++ b/backend/src/validation/organization.ts @@ -1,25 +1,25 @@ -import { Types } from 'mongoose'; +import { Types } from "mongoose"; import { - IUser, IServiceAccount, IServiceTokenData, + IUser, Organization, - User, ServiceAccount, - ServiceTokenData -} from '../models'; + ServiceTokenData, + User, +} from "../models"; import { + AUTH_MODE_API_KEY, AUTH_MODE_JWT, AUTH_MODE_SERVICE_ACCOUNT, AUTH_MODE_SERVICE_TOKEN, - AUTH_MODE_API_KEY -} from '../variables'; +} from "../variables"; import { OrganizationNotFoundError, - UnauthorizedRequestError -} from '../utils/errors'; -import { validateUserClientForOrganization } from './user'; -import { validateServiceAccountClientForOrganization } from './serviceAccount'; + UnauthorizedRequestError, +} from "../utils/errors"; +import { validateUserClientForOrganization } from "./user"; +import { validateServiceAccountClientForOrganization } from "./serviceAccount"; /** * Validate accepted clients for organization with id [organizationId] diff --git a/backend/src/validation/secrets.ts b/backend/src/validation/secrets.ts index 272fe45458..0de983dbe4 100644 --- a/backend/src/validation/secrets.ts +++ b/backend/src/validation/secrets.ts @@ -1,26 +1,26 @@ -import { Types } from 'mongoose'; +import { Types } from "mongoose"; import { ISecret, Secret, - User, ServiceAccount, - ServiceTokenData -} from '../models'; -import { validateServiceAccountClientForWorkspace, validateServiceAccountClientForSecrets } from './serviceAccount'; -import { validateUserClientForSecret, validateUserClientForSecrets } from './user'; -import { validateServiceTokenDataClientForWorkspace, validateServiceTokenDataClientForSecrets } from './serviceTokenData'; -import { AuthData } from '../interfaces/middleware'; + ServiceTokenData, + User, +} from "../models"; +import { validateServiceAccountClientForSecrets, validateServiceAccountClientForWorkspace } from "./serviceAccount"; +import { validateUserClientForSecret, validateUserClientForSecrets } from "./user"; +import { validateServiceTokenDataClientForSecrets, validateServiceTokenDataClientForWorkspace } from "./serviceTokenData"; +import { AuthData } from "../interfaces/middleware"; import { + BadRequestError, SecretNotFoundError, UnauthorizedRequestError, - BadRequestError -} from '../utils/errors'; +} from "../utils/errors"; import { + AUTH_MODE_API_KEY, AUTH_MODE_JWT, AUTH_MODE_SERVICE_ACCOUNT, AUTH_MODE_SERVICE_TOKEN, - AUTH_MODE_API_KEY -} from '../variables'; +} from "../variables"; /** * Validate authenticated clients for secrets with id [secretId] based @@ -35,17 +35,17 @@ export const validateClientForSecret = async ({ authData, secretId, acceptedRoles, - requiredPermissions + requiredPermissions, }: { authData: AuthData; secretId: Types.ObjectId; - acceptedRoles: Array<'admin' | 'member'>; + acceptedRoles: Array<"admin" | "member">; requiredPermissions: string[]; }) => { const secret = await Secret.findById(secretId); if (!secret) throw SecretNotFoundError({ - message: 'Failed to find secret' + message: "Failed to find secret", }); if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) { @@ -53,7 +53,7 @@ export const validateClientForSecret = async ({ user: authData.authPayload, secret, acceptedRoles, - requiredPermissions + requiredPermissions, }); return secret; @@ -64,7 +64,7 @@ export const validateClientForSecret = async ({ serviceAccount: authData.authPayload, workspaceId: secret.workspace, environment: secret.environment, - requiredPermissions + requiredPermissions, }); return secret; @@ -74,7 +74,7 @@ export const validateClientForSecret = async ({ await validateServiceTokenDataClientForWorkspace({ serviceTokenData: authData.authPayload, workspaceId: secret.workspace, - environment: secret.environment + environment: secret.environment, }); return secret; @@ -85,14 +85,14 @@ export const validateClientForSecret = async ({ user: authData.authPayload, secret, acceptedRoles, - requiredPermissions + requiredPermissions, }); return secret; } throw UnauthorizedRequestError({ - message: 'Failed client authorization for secret' + message: "Failed client authorization for secret", }); } @@ -109,7 +109,7 @@ export const validateClientForSecret = async ({ export const validateClientForSecrets = async ({ authData, secretIds, - requiredPermissions + requiredPermissions, }: { authData: AuthData; secretIds: Types.ObjectId[]; @@ -120,19 +120,19 @@ export const validateClientForSecrets = async ({ secrets = await Secret.find({ _id: { - $in: secretIds - } + $in: secretIds, + }, }); if (secrets.length != secretIds.length) { - throw BadRequestError({ message: 'Failed to validate non-existent secrets' }) + throw BadRequestError({ message: "Failed to validate non-existent secrets" }) } if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) { await validateUserClientForSecrets({ user: authData.authPayload, secrets, - requiredPermissions + requiredPermissions, }); return secrets; @@ -142,7 +142,7 @@ export const validateClientForSecrets = async ({ await validateServiceAccountClientForSecrets({ serviceAccount: authData.authPayload, secrets, - requiredPermissions + requiredPermissions, }); return secrets; @@ -152,7 +152,7 @@ export const validateClientForSecrets = async ({ await validateServiceTokenDataClientForSecrets({ serviceTokenData: authData.authPayload, secrets, - requiredPermissions + requiredPermissions, }); return secrets; @@ -162,13 +162,13 @@ export const validateClientForSecrets = async ({ await validateUserClientForSecrets({ user: authData.authPayload, secrets, - requiredPermissions + requiredPermissions, }); return secrets; } throw UnauthorizedRequestError({ - message: 'Failed client authorization for secrets resource' + message: "Failed client authorization for secrets resource", }); } \ No newline at end of file diff --git a/backend/src/validation/serviceAccount.ts b/backend/src/validation/serviceAccount.ts index 11997763c9..78f2c9e696 100644 --- a/backend/src/validation/serviceAccount.ts +++ b/backend/src/validation/serviceAccount.ts @@ -1,35 +1,35 @@ -import _ from 'lodash'; -import { Types } from 'mongoose'; +import _ from "lodash"; +import { Types } from "mongoose"; import { - User, + IOrganization, + ISecret, + IServiceAccount, + IServiceTokenData, IUser, ServiceAccount, - IServiceAccount, + ServiceAccountWorkspacePermission, ServiceTokenData, - IServiceTokenData, - ISecret, - IOrganization, - ServiceAccountWorkspacePermission -} from '../models'; -import { validateUserClientForServiceAccount } from './user'; + User, +} from "../models"; +import { validateUserClientForServiceAccount } from "./user"; import { BadRequestError, + ServiceAccountNotFoundError, UnauthorizedRequestError, - ServiceAccountNotFoundError -} from '../utils/errors'; +} from "../utils/errors"; import { - PERMISSION_READ_SECRETS, - PERMISSION_WRITE_SECRETS, + AUTH_MODE_API_KEY, AUTH_MODE_JWT, AUTH_MODE_SERVICE_ACCOUNT, AUTH_MODE_SERVICE_TOKEN, - AUTH_MODE_API_KEY -} from '../variables'; + PERMISSION_READ_SECRETS, + PERMISSION_WRITE_SECRETS, +} from "../variables"; export const validateClientForServiceAccount = async ({ authData, serviceAccountId, - requiredPermissions + requiredPermissions, }: { authData: { authMode: string; @@ -42,7 +42,7 @@ export const validateClientForServiceAccount = async ({ if (!serviceAccount) { throw ServiceAccountNotFoundError({ - message: 'Failed to find service account' + message: "Failed to find service account", }); } @@ -50,7 +50,7 @@ export const validateClientForServiceAccount = async ({ await validateUserClientForServiceAccount({ user: authData.authPayload, serviceAccount, - requiredPermissions + requiredPermissions, }); return serviceAccount; @@ -60,7 +60,7 @@ export const validateClientForServiceAccount = async ({ await validateServiceAccountClientForServiceAccount({ serviceAccount: authData.authPayload, targetServiceAccount: serviceAccount, - requiredPermissions + requiredPermissions, }); return serviceAccount; @@ -68,7 +68,7 @@ export const validateClientForServiceAccount = async ({ if (authData.authMode === AUTH_MODE_SERVICE_TOKEN && authData.authPayload instanceof ServiceTokenData) { throw UnauthorizedRequestError({ - message: 'Failed service token authorization for service account resource' + message: "Failed service token authorization for service account resource", }); } @@ -76,14 +76,14 @@ export const validateClientForServiceAccount = async ({ await validateUserClientForServiceAccount({ user: authData.authPayload, serviceAccount, - requiredPermissions + requiredPermissions, }); return serviceAccount; } throw UnauthorizedRequestError({ - message: 'Failed client authorization for service account resource' + message: "Failed client authorization for service account resource", }); } @@ -101,7 +101,7 @@ export const validateServiceAccountClientForWorkspace = async ({ serviceAccount, workspaceId, environment, - requiredPermissions + requiredPermissions, }: { serviceAccount: IServiceAccount; workspaceId: Types.ObjectId; @@ -115,11 +115,11 @@ export const validateServiceAccountClientForWorkspace = async ({ const permission = await ServiceAccountWorkspacePermission.findOne({ serviceAccount, workspace: new Types.ObjectId(workspaceId), - environment + environment, }); if (!permission) throw UnauthorizedRequestError({ - message: 'Failed service account authorization for the given workspace environment' + message: "Failed service account authorization for the given workspace environment", }); let runningIsDisallowed = false; @@ -137,7 +137,7 @@ export const validateServiceAccountClientForWorkspace = async ({ if (runningIsDisallowed) { throw UnauthorizedRequestError({ - message: `Failed permissions authorization for workspace environment action : ${requiredPermission}` + message: `Failed permissions authorization for workspace environment action : ${requiredPermission}`, }); } }); @@ -149,11 +149,11 @@ export const validateServiceAccountClientForWorkspace = async ({ const permission = await ServiceAccountWorkspacePermission.findOne({ serviceAccount, - workspace: new Types.ObjectId(workspaceId) + workspace: new Types.ObjectId(workspaceId), }); if (!permission) throw UnauthorizedRequestError({ - message: 'Failed service account authorization for the given workspace' + message: "Failed service account authorization for the given workspace", }); } } @@ -169,7 +169,7 @@ export const validateServiceAccountClientForWorkspace = async ({ export const validateServiceAccountClientForSecrets = async ({ serviceAccount, secrets, - requiredPermissions + requiredPermissions, }: { serviceAccount: IServiceAccount; secrets: ISecret[]; @@ -177,7 +177,7 @@ export const validateServiceAccountClientForSecrets = async ({ }) => { const permissions = await ServiceAccountWorkspacePermission.find({ - serviceAccount: serviceAccount._id + serviceAccount: serviceAccount._id, }); const permissionsObj = _.keyBy(permissions, (p) => { @@ -188,7 +188,7 @@ export const validateServiceAccountClientForSecrets = async ({ const permission = permissionsObj[`${secret.workspace.toString()}-${secret.environment}`]; if (!permission) throw BadRequestError({ - message: 'Failed to find any permission for the secret workspace and environment' + message: "Failed to find any permission for the secret workspace and environment", }); requiredPermissions?.forEach((requiredPermission: string) => { @@ -207,7 +207,7 @@ export const validateServiceAccountClientForSecrets = async ({ if (runningIsDisallowed) { throw UnauthorizedRequestError({ - message: `Failed permissions authorization for workspace environment action : ${requiredPermission}` + message: `Failed permissions authorization for workspace environment action : ${requiredPermission}`, }); } }); @@ -226,7 +226,7 @@ export const validateServiceAccountClientForSecrets = async ({ export const validateServiceAccountClientForServiceAccount = ({ serviceAccount, targetServiceAccount, - requiredPermissions + requiredPermissions, }: { serviceAccount: IServiceAccount; targetServiceAccount: IServiceAccount; @@ -234,7 +234,7 @@ export const validateServiceAccountClientForServiceAccount = ({ }) => { if (!serviceAccount.organization.equals(targetServiceAccount.organization)) { throw UnauthorizedRequestError({ - message: 'Failed service account authorization for the given service account' + message: "Failed service account authorization for the given service account", }); } } @@ -247,14 +247,14 @@ export const validateServiceAccountClientForServiceAccount = ({ */ export const validateServiceAccountClientForOrganization = async ({ serviceAccount, - organization + organization, }: { serviceAccount: IServiceAccount; organization: IOrganization; }) => { if (!serviceAccount.organization.equals(organization._id)) { throw UnauthorizedRequestError({ - message: 'Failed service account authorization for the given organization' + message: "Failed service account authorization for the given organization", }); } } \ No newline at end of file diff --git a/backend/src/validation/serviceTokenData.ts b/backend/src/validation/serviceTokenData.ts index 8713e000f2..0ade7f96e2 100644 --- a/backend/src/validation/serviceTokenData.ts +++ b/backend/src/validation/serviceTokenData.ts @@ -1,25 +1,25 @@ -import { Types } from 'mongoose'; +import { Types } from "mongoose"; import { ISecret, - IServiceTokenData, - ServiceTokenData, - IUser, - User, IServiceAccount, + IServiceTokenData, + IUser, ServiceAccount, -} from '../models'; + ServiceTokenData, + User, +} from "../models"; import { + ServiceTokenDataNotFoundError, UnauthorizedRequestError, - ServiceTokenDataNotFoundError -} from '../utils/errors'; +} from "../utils/errors"; import { - AUTH_MODE_JWT, + AUTH_MODE_API_KEY, + AUTH_MODE_JWT, AUTH_MODE_SERVICE_ACCOUNT, AUTH_MODE_SERVICE_TOKEN, - AUTH_MODE_API_KEY -} from '../variables'; -import { validateUserClientForWorkspace } from './user'; -import { validateServiceAccountClientForWorkspace } from './serviceAccount'; +} from "../variables"; +import { validateUserClientForWorkspace } from "./user"; +import { validateServiceAccountClientForWorkspace } from "./serviceAccount"; /** * Validate authenticated clients for service token with id [serviceTokenId] based @@ -32,29 +32,29 @@ import { validateServiceAccountClientForWorkspace } from './serviceAccount'; export const validateClientForServiceTokenData = async ({ authData, serviceTokenDataId, - acceptedRoles + acceptedRoles, }: { authData: { authMode: string; authPayload: IUser | IServiceAccount | IServiceTokenData; }; serviceTokenDataId: Types.ObjectId; - acceptedRoles: Array<'admin' | 'member'>; + acceptedRoles: Array<"admin" | "member">; }) => { const serviceTokenData = await ServiceTokenData .findById(serviceTokenDataId) - .select('+encryptedKey +iv +tag') - .populate<{ user: IUser }>('user'); + .select("+encryptedKey +iv +tag") + .populate<{ user: IUser }>("user"); if (!serviceTokenData) throw ServiceTokenDataNotFoundError({ - message: 'Failed to find service token data' + message: "Failed to find service token data", }); if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) { await validateUserClientForWorkspace({ user: authData.authPayload, workspaceId: serviceTokenData.workspace, - acceptedRoles + acceptedRoles, }); return serviceTokenData; @@ -63,7 +63,7 @@ export const validateClientForServiceTokenData = async ({ if (authData.authMode === AUTH_MODE_SERVICE_ACCOUNT && authData.authPayload instanceof ServiceAccount) { await validateServiceAccountClientForWorkspace({ serviceAccount: authData.authPayload, - workspaceId: serviceTokenData.workspace + workspaceId: serviceTokenData.workspace, }); return serviceTokenData; @@ -71,7 +71,7 @@ export const validateClientForServiceTokenData = async ({ if (authData.authMode === AUTH_MODE_SERVICE_TOKEN && authData.authPayload instanceof ServiceTokenData) { throw UnauthorizedRequestError({ - message: 'Failed service token authorization for service token data' + message: "Failed service token authorization for service token data", }); } @@ -79,14 +79,14 @@ export const validateClientForServiceTokenData = async ({ await validateUserClientForWorkspace({ user: authData.authPayload, workspaceId: serviceTokenData.workspace, - acceptedRoles + acceptedRoles, }); return serviceTokenData; } throw UnauthorizedRequestError({ - message: 'Failed client authorization for service token data' + message: "Failed client authorization for service token data", }); } @@ -104,7 +104,7 @@ export const validateServiceTokenDataClientForWorkspace = async ({ serviceTokenData, workspaceId, environment, - requiredPermissions + requiredPermissions, }: { serviceTokenData: IServiceTokenData; workspaceId: Types.ObjectId; @@ -114,7 +114,7 @@ export const validateServiceTokenDataClientForWorkspace = async ({ if (!serviceTokenData.workspace.equals(workspaceId)) { // case: invalid workspaceId passed throw UnauthorizedRequestError({ - message: 'Failed service token authorization for the given workspace' + message: "Failed service token authorization for the given workspace", }); } @@ -124,14 +124,14 @@ export const validateServiceTokenDataClientForWorkspace = async ({ if (serviceTokenData.environment !== environment) { // case: invalid environment passed throw UnauthorizedRequestError({ - message: 'Failed service token authorization for the given workspace environment' + message: "Failed service token authorization for the given workspace environment", }); } requiredPermissions?.forEach((permission) => { if (!serviceTokenData.permissions.includes(permission)) { throw UnauthorizedRequestError({ - message: `Failed service token authorization for the given workspace environment action: ${permission}` + message: `Failed service token authorization for the given workspace environment action: ${permission}`, }); } }); @@ -149,7 +149,7 @@ export const validateServiceTokenDataClientForWorkspace = async ({ export const validateServiceTokenDataClientForSecrets = async ({ serviceTokenData, secrets, - requiredPermissions + requiredPermissions, }: { serviceTokenData: IServiceTokenData; secrets: ISecret[]; @@ -160,21 +160,21 @@ export const validateServiceTokenDataClientForSecrets = async ({ if (!serviceTokenData.workspace.equals(secret.workspace)) { // case: invalid workspaceId passed throw UnauthorizedRequestError({ - message: 'Failed service token authorization for the given workspace' + message: "Failed service token authorization for the given workspace", }); } if (serviceTokenData.environment !== secret.environment) { // case: invalid environment passed throw UnauthorizedRequestError({ - message: 'Failed service token authorization for the given workspace environment' + message: "Failed service token authorization for the given workspace environment", }); } requiredPermissions?.forEach((permission) => { if (!serviceTokenData.permissions.includes(permission)) { throw UnauthorizedRequestError({ - message: `Failed service token authorization for the given workspace environment action: ${permission}` + message: `Failed service token authorization for the given workspace environment action: ${permission}`, }); } }); diff --git a/backend/src/validation/user.ts b/backend/src/validation/user.ts index 4c412e52f3..f1edad3bf2 100644 --- a/backend/src/validation/user.ts +++ b/backend/src/validation/user.ts @@ -1,37 +1,37 @@ -import fs from 'fs'; -import path from 'path'; -import { Types } from 'mongoose'; +import fs from "fs"; +import path from "path"; +import { Types } from "mongoose"; import { - IUser, + IOrganization, ISecret, IServiceAccount, + IUser, Membership, - IOrganization, -} from '../models'; -import { validateMembership } from '../helpers/membership'; -import _ from 'lodash'; -import { BadRequestError, UnauthorizedRequestError, ValidationError } from '../utils/errors'; +} from "../models"; +import { validateMembership } from "../helpers/membership"; +import _ from "lodash"; +import { BadRequestError, UnauthorizedRequestError, ValidationError } from "../utils/errors"; import { - validateMembershipOrg -} from '../helpers/membershipOrg'; + validateMembershipOrg, +} from "../helpers/membershipOrg"; import { PERMISSION_READ_SECRETS, - PERMISSION_WRITE_SECRETS -} from '../variables'; + PERMISSION_WRITE_SECRETS, +} from "../variables"; /** * Validate that email [email] is not disposable * @param email - email to validate */ export const validateUserEmail = (email: string) => { - const emailDomain = email.split('@')[1]; + const emailDomain = email.split("@")[1]; const disposableEmails = fs.readFileSync( - path.resolve(__dirname, '../data/' + 'disposable_emails.txt'), - 'utf8' - ).split('\n'); + path.resolve(__dirname, "../data/" + "disposable_emails.txt"), + "utf8" + ).split("\n"); if (disposableEmails.includes(emailDomain)) throw ValidationError({ - message: 'Failed to validate email as non-disposable' + message: "Failed to validate email as non-disposable", }); } @@ -50,12 +50,12 @@ export const validateUserClientForWorkspace = async ({ workspaceId, environment, acceptedRoles, - requiredPermissions + requiredPermissions, }: { user: IUser; workspaceId: Types.ObjectId; environment?: string; - acceptedRoles: Array<'admin' | 'member'>; + acceptedRoles: Array<"admin" | "member">; requiredPermissions?: string[]; }) => { @@ -63,7 +63,7 @@ export const validateUserClientForWorkspace = async ({ const membership = await validateMembership({ userId: user._id, workspaceId, - acceptedRoles + acceptedRoles, }); let runningIsDisallowed = false; @@ -81,7 +81,7 @@ export const validateUserClientForWorkspace = async ({ if (runningIsDisallowed) { throw UnauthorizedRequestError({ - message: `Failed permissions authorization for workspace environment action : ${requiredPermission}` + message: `Failed permissions authorization for workspace environment action : ${requiredPermission}`, }); } }); @@ -101,17 +101,17 @@ export const validateUserClientForSecret = async ({ user, secret, acceptedRoles, - requiredPermissions + requiredPermissions, }: { user: IUser; secret: ISecret; - acceptedRoles?: Array<'admin' | 'member'>; + acceptedRoles?: Array<"admin" | "member">; requiredPermissions?: string[]; }) => { const membership = await validateMembership({ userId: user._id, workspaceId: secret.workspace, - acceptedRoles + acceptedRoles, }); if (requiredPermissions?.includes(PERMISSION_WRITE_SECRETS)) { @@ -119,7 +119,7 @@ export const validateUserClientForSecret = async ({ if (isDisallowed) { throw UnauthorizedRequestError({ - message: 'You do not have the required permissions to perform this action' + message: "You do not have the required permissions to perform this action", }); } } @@ -136,7 +136,7 @@ export const validateUserClientForSecret = async ({ export const validateUserClientForSecrets = async ({ user, secrets, - requiredPermissions + requiredPermissions, }: { user: IUser; secrets: ISecret[]; @@ -146,14 +146,14 @@ export const validateUserClientForSecrets = async ({ // TODO: add acceptedRoles? const userMemberships = await Membership.find({ user: user._id }) - const userMembershipById = _.keyBy(userMemberships, 'workspace'); + const userMembershipById = _.keyBy(userMemberships, "workspace"); const workspaceIdsSet = new Set(userMemberships.map((m) => m.workspace.toString())); // for each secret check if the secret belongs to a workspace the user is a member of secrets.forEach((secret: ISecret) => { if (!workspaceIdsSet.has(secret.workspace.toString())) { throw BadRequestError({ - message: 'Failed authorization for the secret' + message: "Failed authorization for the secret", }); } @@ -163,7 +163,7 @@ export const validateUserClientForSecrets = async ({ if (isDisallowed) { throw UnauthorizedRequestError({ - message: 'You do not have the required permissions to perform this action' + message: "You do not have the required permissions to perform this action", }); } } @@ -181,7 +181,7 @@ export const validateUserClientForSecrets = async ({ export const validateUserClientForServiceAccount = async ({ user, serviceAccount, - requiredPermissions + requiredPermissions, }: { user: IUser; serviceAccount: IServiceAccount; @@ -194,7 +194,7 @@ export const validateUserClientForServiceAccount = async ({ userId: user._id, organizationId: serviceAccount.organization, acceptedRoles: [], - acceptedStatuses: [] + acceptedStatuses: [], }); } } @@ -209,18 +209,18 @@ export const validateUserClientForOrganization = async ({ user, organization, acceptedRoles, - acceptedStatuses + acceptedStatuses, }: { user: IUser; organization: IOrganization; - acceptedRoles: Array<'owner' | 'admin' | 'member'>; - acceptedStatuses: Array<'invited' | 'accepted'>; + acceptedRoles: Array<"owner" | "admin" | "member">; + acceptedStatuses: Array<"invited" | "accepted">; }) => { const membershipOrg = await validateMembershipOrg({ userId: user._id, organizationId: organization._id, acceptedRoles, - acceptedStatuses + acceptedStatuses, }); return membershipOrg; diff --git a/backend/src/validation/workspace.ts b/backend/src/validation/workspace.ts index 28c4a20ea7..cdc2771f40 100644 --- a/backend/src/validation/workspace.ts +++ b/backend/src/validation/workspace.ts @@ -1,29 +1,29 @@ -import { Types } from 'mongoose'; +import { Types } from "mongoose"; import { - IUser, IServiceAccount, IServiceTokenData, - Workspace, - User, + IUser, + SecretBlindIndexData, ServiceAccount, ServiceTokenData, - SecretBlindIndexData -} from '../models'; -import { validateServiceAccountClientForWorkspace } from './serviceAccount'; -import { validateUserClientForWorkspace } from './user'; -import { validateServiceTokenDataClientForWorkspace } from './serviceTokenData'; + User, + Workspace, +} from "../models"; +import { validateServiceAccountClientForWorkspace } from "./serviceAccount"; +import { validateUserClientForWorkspace } from "./user"; +import { validateServiceTokenDataClientForWorkspace } from "./serviceTokenData"; import { BadRequestError, UnauthorizedRequestError, - WorkspaceNotFoundError -} from '../utils/errors'; + WorkspaceNotFoundError, +} from "../utils/errors"; import { + AUTH_MODE_API_KEY, AUTH_MODE_JWT, AUTH_MODE_SERVICE_ACCOUNT, AUTH_MODE_SERVICE_TOKEN, - AUTH_MODE_API_KEY -} from '../variables'; -import { BotService } from '../services'; +} from "../variables"; +import { BotService } from "../services"; /** * Validate authenticated clients for workspace with id [workspaceId] based @@ -42,7 +42,7 @@ export const validateClientForWorkspace = async ({ acceptedRoles, requiredPermissions, requireBlindIndicesEnabled, - requireE2EEOff + requireE2EEOff, }: { authData: { authMode: string; @@ -50,7 +50,7 @@ export const validateClientForWorkspace = async ({ }; workspaceId: Types.ObjectId; environment?: string; - acceptedRoles: Array<'admin' | 'member'>; + acceptedRoles: Array<"admin" | "member">; requiredPermissions?: string[]; requireBlindIndicesEnabled: boolean; requireE2EEOff: boolean; @@ -58,7 +58,7 @@ export const validateClientForWorkspace = async ({ const workspace = await Workspace.findById(workspaceId); if (!workspace) throw WorkspaceNotFoundError({ - message: 'Failed to find workspace' + message: "Failed to find workspace", }); if (requireBlindIndicesEnabled) { @@ -67,11 +67,11 @@ export const validateClientForWorkspace = async ({ // and no admin has enabled it) const secretBlindIndexData = await SecretBlindIndexData.exists({ - workspace: new Types.ObjectId(workspaceId) + workspace: new Types.ObjectId(workspaceId), }); if (!secretBlindIndexData) throw UnauthorizedRequestError({ - message: 'Failed workspace authorization due to blind indices not being enabled' + message: "Failed workspace authorization due to blind indices not being enabled", }); } @@ -79,7 +79,7 @@ export const validateClientForWorkspace = async ({ const isWorkspaceE2EE = await BotService.getIsWorkspaceE2EE(workspaceId); if (isWorkspaceE2EE) throw BadRequestError({ - message: 'Failed workspace authorization due to end-to-end encryption not being disabled' + message: "Failed workspace authorization due to end-to-end encryption not being disabled", }); } @@ -89,7 +89,7 @@ export const validateClientForWorkspace = async ({ workspaceId, environment, acceptedRoles, - requiredPermissions + requiredPermissions, }); return ({ membership, workspace }); @@ -100,7 +100,7 @@ export const validateClientForWorkspace = async ({ serviceAccount: authData.authPayload, workspaceId, environment, - requiredPermissions + requiredPermissions, }); return {}; @@ -111,7 +111,7 @@ export const validateClientForWorkspace = async ({ serviceTokenData: authData.authPayload, workspaceId, environment, - requiredPermissions + requiredPermissions, }); return {}; @@ -123,13 +123,13 @@ export const validateClientForWorkspace = async ({ workspaceId, environment, acceptedRoles, - requiredPermissions + requiredPermissions, }); return ({ membership, workspace }); } throw UnauthorizedRequestError({ - message: 'Failed client authorization for workspace' + message: "Failed client authorization for workspace", }); } diff --git a/backend/src/variables/action.ts b/backend/src/variables/action.ts index 9d4fb18d9b..033be15b0c 100644 --- a/backend/src/variables/action.ts +++ b/backend/src/variables/action.ts @@ -1,6 +1,6 @@ -export const ACTION_LOGIN = 'login'; -export const ACTION_LOGOUT = 'logout'; -export const ACTION_ADD_SECRETS = 'addSecrets'; -export const ACTION_DELETE_SECRETS = 'deleteSecrets'; -export const ACTION_UPDATE_SECRETS = 'updateSecrets'; -export const ACTION_READ_SECRETS = 'readSecrets'; \ No newline at end of file +export const ACTION_LOGIN = "login"; +export const ACTION_LOGOUT = "logout"; +export const ACTION_ADD_SECRETS = "addSecrets"; +export const ACTION_DELETE_SECRETS = "deleteSecrets"; +export const ACTION_UPDATE_SECRETS = "updateSecrets"; +export const ACTION_READ_SECRETS = "readSecrets"; \ No newline at end of file diff --git a/backend/src/variables/authentication.ts b/backend/src/variables/authentication.ts index ac19d2756e..38bfdfc2c5 100644 --- a/backend/src/variables/authentication.ts +++ b/backend/src/variables/authentication.ts @@ -1,4 +1,4 @@ -export const AUTH_MODE_JWT = 'jwt'; -export const AUTH_MODE_SERVICE_ACCOUNT = 'serviceAccount'; -export const AUTH_MODE_SERVICE_TOKEN = 'serviceToken'; -export const AUTH_MODE_API_KEY = 'apiKey'; // TODO: deprecate \ No newline at end of file +export const AUTH_MODE_JWT = "jwt"; +export const AUTH_MODE_SERVICE_ACCOUNT = "serviceAccount"; +export const AUTH_MODE_SERVICE_TOKEN = "serviceToken"; +export const AUTH_MODE_API_KEY = "apiKey"; // TODO: deprecate \ No newline at end of file diff --git a/backend/src/variables/crypto.ts b/backend/src/variables/crypto.ts index bd2ae110ca..64dde2c224 100644 --- a/backend/src/variables/crypto.ts +++ b/backend/src/variables/crypto.ts @@ -1,7 +1,7 @@ -export const ALGORITHM_AES_256_GCM = 'aes-256-gcm'; +export const ALGORITHM_AES_256_GCM = "aes-256-gcm"; export const NONCE_BYTES_SIZE = 12; export const BLOCK_SIZE_BYTES_16 = 16; -export const ENCODING_SCHEME_UTF8 = 'utf8'; -export const ENCODING_SCHEME_HEX = 'hex'; -export const ENCODING_SCHEME_BASE64 = 'base64'; \ No newline at end of file +export const ENCODING_SCHEME_UTF8 = "utf8"; +export const ENCODING_SCHEME_HEX = "hex"; +export const ENCODING_SCHEME_BASE64 = "base64"; \ No newline at end of file diff --git a/backend/src/variables/environment.ts b/backend/src/variables/environment.ts index b068b3d365..d0c8220efd 100644 --- a/backend/src/variables/environment.ts +++ b/backend/src/variables/environment.ts @@ -1,6 +1,6 @@ // environments -export const ENV_DEV = 'dev'; -export const ENV_TESTING = 'test'; -export const ENV_STAGING = 'staging'; -export const ENV_PROD = 'prod'; +export const ENV_DEV = "dev"; +export const ENV_TESTING = "test"; +export const ENV_STAGING = "staging"; +export const ENV_PROD = "prod"; export const ENV_SET = new Set([ENV_DEV, ENV_TESTING, ENV_STAGING, ENV_PROD]); \ No newline at end of file diff --git a/backend/src/variables/event.ts b/backend/src/variables/event.ts index 1c55eb3ec4..c5de005d19 100644 --- a/backend/src/variables/event.ts +++ b/backend/src/variables/event.ts @@ -1,2 +1,2 @@ -export const EVENT_PUSH_SECRETS = 'pushSecrets'; -export const EVENT_PULL_SECRETS = 'pullSecrets'; \ No newline at end of file +export const EVENT_PUSH_SECRETS = "pushSecrets"; +export const EVENT_PULL_SECRETS = "pullSecrets"; \ No newline at end of file diff --git a/backend/src/variables/index.ts b/backend/src/variables/index.ts index 281145a995..24e86b8fea 100644 --- a/backend/src/variables/index.ts +++ b/backend/src/variables/index.ts @@ -1,13 +1,13 @@ -export * from './action'; -export * from './authentication'; -export * from './crypto'; -export * from './environment'; -export * from './event'; -export * from './integration'; -export * from './organization'; -export * from './permission'; -export * from './secret'; -export * from './smtp'; -export * from './stripe'; -export * from './token'; -export * from './user'; +export * from "./action"; +export * from "./authentication"; +export * from "./crypto"; +export * from "./environment"; +export * from "./event"; +export * from "./integration"; +export * from "./organization"; +export * from "./permission"; +export * from "./secret"; +export * from "./smtp"; +export * from "./stripe"; +export * from "./token"; +export * from "./user"; diff --git a/backend/src/variables/integration.ts b/backend/src/variables/integration.ts index 26e9f25448..5da38c71bc 100644 --- a/backend/src/variables/integration.ts +++ b/backend/src/variables/integration.ts @@ -1,16 +1,16 @@ import { - getClientIdHeroku, - getClientSlugVercel, - getClientIdNetlify, getClientIdAzure, + getClientIdGitHub, getClientIdGitLab, - getClientIdGitHub -} from '../config'; + getClientIdHeroku, + getClientIdNetlify, + getClientSlugVercel, +} from "../config"; // integrations -export const INTEGRATION_AZURE_KEY_VAULT = 'azure-key-vault'; -export const INTEGRATION_AWS_PARAMETER_STORE = 'aws-parameter-store'; -export const INTEGRATION_AWS_SECRET_MANAGER = 'aws-secret-manager'; +export const INTEGRATION_AZURE_KEY_VAULT = "azure-key-vault"; +export const INTEGRATION_AWS_PARAMETER_STORE = "aws-parameter-store"; +export const INTEGRATION_AWS_SECRET_MANAGER = "aws-secret-manager"; export const INTEGRATION_HEROKU = "heroku"; export const INTEGRATION_VERCEL = "vercel"; export const INTEGRATION_NETLIFY = "netlify"; @@ -21,9 +21,9 @@ export const INTEGRATION_RAILWAY = "railway"; export const INTEGRATION_FLYIO = "flyio"; export const INTEGRATION_CIRCLECI = "circleci"; export const INTEGRATION_TRAVISCI = "travisci"; -export const INTEGRATION_SUPABASE = 'supabase'; -export const INTEGRATION_CHECKLY = 'checkly'; -export const INTEGRATION_HASHICORP_VAULT = 'hashicorp-vault'; +export const INTEGRATION_SUPABASE = "supabase"; +export const INTEGRATION_CHECKLY = "checkly"; +export const INTEGRATION_HASHICORP_VAULT = "hashicorp-vault"; export const INTEGRATION_SET = new Set([ INTEGRATION_AZURE_KEY_VAULT, INTEGRATION_HEROKU, @@ -37,15 +37,15 @@ export const INTEGRATION_SET = new Set([ INTEGRATION_TRAVISCI, INTEGRATION_SUPABASE, INTEGRATION_CHECKLY, - INTEGRATION_HASHICORP_VAULT + INTEGRATION_HASHICORP_VAULT, ]); // integration types export const INTEGRATION_OAUTH2 = "oauth2"; // integration oauth endpoints -export const INTEGRATION_AZURE_TOKEN_URL = `https://login.microsoftonline.com/common/oauth2/v2.0/token`; -export const INTEGRATION_HEROKU_TOKEN_URL = 'https://id.heroku.com/oauth/token'; +export const INTEGRATION_AZURE_TOKEN_URL = "https://login.microsoftonline.com/common/oauth2/v2.0/token"; +export const INTEGRATION_HEROKU_TOKEN_URL = "https://id.heroku.com/oauth/token"; export const INTEGRATION_VERCEL_TOKEN_URL = "https://api.vercel.com/v2/oauth/access_token"; export const INTEGRATION_NETLIFY_TOKEN_URL = "https://api.netlify.com/oauth/token"; @@ -63,165 +63,165 @@ export const INTEGRATION_RAILWAY_API_URL = "https://backboard.railway.app/graphq export const INTEGRATION_FLYIO_API_URL = "https://api.fly.io/graphql"; export const INTEGRATION_CIRCLECI_API_URL = "https://circleci.com/api"; export const INTEGRATION_TRAVISCI_API_URL = "https://api.travis-ci.com"; -export const INTEGRATION_SUPABASE_API_URL = 'https://api.supabase.com'; -export const INTEGRATION_CHECKLY_API_URL = 'https://api.checklyhq.com'; +export const INTEGRATION_SUPABASE_API_URL = "https://api.supabase.com"; +export const INTEGRATION_CHECKLY_API_URL = "https://api.checklyhq.com"; export const getIntegrationOptions = async () => { const INTEGRATION_OPTIONS = [ { - name: 'Heroku', - slug: 'heroku', - image: 'Heroku.png', + name: "Heroku", + slug: "heroku", + image: "Heroku.png", isAvailable: true, - type: 'oauth', + type: "oauth", clientId: await getClientIdHeroku(), - docsLink: '' + docsLink: "", }, { - name: 'Vercel', - slug: 'vercel', - image: 'Vercel.png', + name: "Vercel", + slug: "vercel", + image: "Vercel.png", isAvailable: true, - type: 'oauth', - clientId: '', + type: "oauth", + clientId: "", clientSlug: await getClientSlugVercel(), - docsLink: '' + docsLink: "", }, { - name: 'Netlify', - slug: 'netlify', - image: 'Netlify.png', + name: "Netlify", + slug: "netlify", + image: "Netlify.png", isAvailable: true, - type: 'oauth', + type: "oauth", clientId: await getClientIdNetlify(), - docsLink: '' + docsLink: "", }, { - name: 'GitHub', - slug: 'github', - image: 'GitHub.png', + name: "GitHub", + slug: "github", + image: "GitHub.png", isAvailable: true, - type: 'oauth', + type: "oauth", clientId: await getClientIdGitHub(), - docsLink: '' + docsLink: "", }, { - name: 'Render', - slug: 'render', - image: 'Render.png', + name: "Render", + slug: "render", + image: "Render.png", isAvailable: true, - type: 'pat', - clientId: '', - docsLink: '' + type: "pat", + clientId: "", + docsLink: "", }, { - name: 'Railway', - slug: 'railway', - image: 'Railway.png', + name: "Railway", + slug: "railway", + image: "Railway.png", isAvailable: true, - type: 'pat', - clientId: '', - docsLink: '' + type: "pat", + clientId: "", + docsLink: "", }, { - name: 'Fly.io', - slug: 'flyio', - image: 'Flyio.svg', + name: "Fly.io", + slug: "flyio", + image: "Flyio.svg", isAvailable: true, - type: 'pat', - clientId: '', - docsLink: '' + type: "pat", + clientId: "", + docsLink: "", }, { - name: 'AWS Parameter Store', - slug: 'aws-parameter-store', - image: 'Amazon Web Services.png', + name: "AWS Parameter Store", + slug: "aws-parameter-store", + image: "Amazon Web Services.png", isAvailable: true, - type: 'custom', - clientId: '', - docsLink: '' + type: "custom", + clientId: "", + docsLink: "", }, { - name: 'AWS Secret Manager', - slug: 'aws-secret-manager', - image: 'Amazon Web Services.png', + name: "AWS Secret Manager", + slug: "aws-secret-manager", + image: "Amazon Web Services.png", isAvailable: true, - type: 'custom', - clientId: '', - docsLink: '' + type: "custom", + clientId: "", + docsLink: "", }, { - name: 'Azure Key Vault', - slug: 'azure-key-vault', - image: 'Microsoft Azure.png', + name: "Azure Key Vault", + slug: "azure-key-vault", + image: "Microsoft Azure.png", isAvailable: true, - type: 'oauth', + type: "oauth", clientId: await getClientIdAzure(), - docsLink: '' + docsLink: "", }, { - name: 'Circle CI', - slug: 'circleci', - image: 'Circle CI.png', + name: "Circle CI", + slug: "circleci", + image: "Circle CI.png", isAvailable: true, - type: 'pat', - clientId: '', - docsLink: '' + type: "pat", + clientId: "", + docsLink: "", }, { - name: 'GitLab', - slug: 'gitlab', - image: 'GitLab.png', + name: "GitLab", + slug: "gitlab", + image: "GitLab.png", isAvailable: true, - type: 'custom', + type: "custom", clientId: await getClientIdGitLab(), - docsLink: '' + docsLink: "", }, { - name: 'Travis CI', - slug: 'travisci', - image: 'Travis CI.png', + name: "Travis CI", + slug: "travisci", + image: "Travis CI.png", isAvailable: true, - type: 'pat', - clientId: '', - docsLink: '' + type: "pat", + clientId: "", + docsLink: "", }, { - name: 'Supabase', - slug: 'supabase', - image: 'Supabase.png', + name: "Supabase", + slug: "supabase", + image: "Supabase.png", isAvailable: true, - type: 'pat', - clientId: '', - docsLink: '' + type: "pat", + clientId: "", + docsLink: "", }, { - name: 'Checkly', - slug: 'checkly', - image: 'Checkly.png', + name: "Checkly", + slug: "checkly", + image: "Checkly.png", isAvailable: true, - type: 'pat', - clientId: '', - docsLink: '' + type: "pat", + clientId: "", + docsLink: "", }, { - name: 'HashiCorp Vault', - slug: 'hashicorp-vault', - image: 'Vault.png', + name: "HashiCorp Vault", + slug: "hashicorp-vault", + image: "Vault.png", isAvailable: true, - type: 'pat', - clientId: '', - docsLink: '' + type: "pat", + clientId: "", + docsLink: "", }, { - name: 'Google Cloud Platform', - slug: 'gcp', - image: 'Google Cloud Platform.png', + name: "Google Cloud Platform", + slug: "gcp", + image: "Google Cloud Platform.png", isAvailable: false, - type: '', - clientId: '', - docsLink: '' - } + type: "", + clientId: "", + docsLink: "", + }, ] return INTEGRATION_OPTIONS; diff --git a/backend/src/variables/permission.ts b/backend/src/variables/permission.ts index 98c9ef538f..9dc4c61a31 100644 --- a/backend/src/variables/permission.ts +++ b/backend/src/variables/permission.ts @@ -1,2 +1,2 @@ -export const PERMISSION_READ_SECRETS = 'read'; -export const PERMISSION_WRITE_SECRETS = 'write'; \ No newline at end of file +export const PERMISSION_READ_SECRETS = "read"; +export const PERMISSION_WRITE_SECRETS = "write"; \ No newline at end of file diff --git a/backend/src/variables/secret.ts b/backend/src/variables/secret.ts index 571e66b9d2..74be3a1e9c 100644 --- a/backend/src/variables/secret.ts +++ b/backend/src/variables/secret.ts @@ -1,3 +1,3 @@ // secrets -export const SECRET_SHARED = 'shared'; -export const SECRET_PERSONAL = 'personal'; \ No newline at end of file +export const SECRET_SHARED = "shared"; +export const SECRET_PERSONAL = "personal"; \ No newline at end of file diff --git a/backend/src/variables/smtp.ts b/backend/src/variables/smtp.ts index f5dd05d0bc..8a0e752eb2 100644 --- a/backend/src/variables/smtp.ts +++ b/backend/src/variables/smtp.ts @@ -1,5 +1,5 @@ -export const SMTP_HOST_SENDGRID = 'smtp.sendgrid.net'; -export const SMTP_HOST_MAILGUN = 'smtp.mailgun.org'; -export const SMTP_HOST_SOCKETLABS = 'smtp.socketlabs.com'; -export const SMTP_HOST_ZOHOMAIL = 'smtp.zoho.com'; -export const SMTP_HOST_GMAIL = 'smtp.gmail.com'; +export const SMTP_HOST_SENDGRID = "smtp.sendgrid.net"; +export const SMTP_HOST_MAILGUN = "smtp.mailgun.org"; +export const SMTP_HOST_SOCKETLABS = "smtp.socketlabs.com"; +export const SMTP_HOST_ZOHOMAIL = "smtp.zoho.com"; +export const SMTP_HOST_GMAIL = "smtp.gmail.com"; diff --git a/backend/src/variables/stripe.ts b/backend/src/variables/stripe.ts index 7b6ae8fa18..fa0fdae071 100644 --- a/backend/src/variables/stripe.ts +++ b/backend/src/variables/stripe.ts @@ -1,2 +1,2 @@ -export const PLAN_STARTER = 'starter'; -export const PLAN_PRO = 'pro'; \ No newline at end of file +export const PLAN_STARTER = "starter"; +export const PLAN_PRO = "pro"; \ No newline at end of file diff --git a/backend/src/variables/token.ts b/backend/src/variables/token.ts index 2ced95d9ce..187e2534b0 100644 --- a/backend/src/variables/token.ts +++ b/backend/src/variables/token.ts @@ -1,4 +1,4 @@ -export const TOKEN_EMAIL_CONFIRMATION = 'emailConfirmation'; -export const TOKEN_EMAIL_MFA = 'emailMfa'; -export const TOKEN_EMAIL_ORG_INVITATION = 'organizationInvitation'; -export const TOKEN_EMAIL_PASSWORD_RESET = 'passwordReset'; \ No newline at end of file +export const TOKEN_EMAIL_CONFIRMATION = "emailConfirmation"; +export const TOKEN_EMAIL_MFA = "emailMfa"; +export const TOKEN_EMAIL_ORG_INVITATION = "organizationInvitation"; +export const TOKEN_EMAIL_PASSWORD_RESET = "passwordReset"; \ No newline at end of file diff --git a/backend/src/variables/user.ts b/backend/src/variables/user.ts index 7e5b53c4b4..a688b115d1 100644 --- a/backend/src/variables/user.ts +++ b/backend/src/variables/user.ts @@ -1 +1 @@ -export const MFA_METHOD_EMAIL = 'email'; \ No newline at end of file +export const MFA_METHOD_EMAIL = "email"; \ No newline at end of file diff --git a/backend/swagger/index.ts b/backend/swagger/index.ts index 051f9d64fb..35ed207901 100644 --- a/backend/swagger/index.ts +++ b/backend/swagger/index.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-var-requires */ -const swaggerAutogen = require('swagger-autogen')({ openapi: '3.0.0' }); -const fs = require('fs').promises; -const yaml = require('js-yaml'); +const swaggerAutogen = require("swagger-autogen")({ openapi: "3.0.0" }); +const fs = require("fs").promises; +const yaml = require("js-yaml"); /** * Generates OpenAPI specs for all Infisical API endpoints: @@ -11,216 +11,216 @@ const yaml = require('js-yaml'); const generateOpenAPISpec = async () => { const doc = { info: { - title: 'Infisical API', - description: 'List of all available APIs that can be consumed', + title: "Infisical API", + description: "List of all available APIs that can be consumed", }, - host: ['https://infisical.com'], + host: ["https://infisical.com"], servers: [ { - url: 'https://infisical.com', - description: 'Production server' + url: "https://infisical.com", + description: "Production server", }, { - url: 'http://localhost:8080', - description: 'Local server' - } + url: "http://localhost:8080", + description: "Local server", + }, ], securityDefinitions: { bearerAuth: { - type: 'http', - scheme: 'bearer', - bearerFormat: 'JWT', - description: "This security definition uses the HTTP 'bearer' scheme, which allows the client to authenticate using a JSON Web Token (JWT) that is passed in the Authorization header of the request." + type: "http", + scheme: "bearer", + bearerFormat: "JWT", + description: "This security definition uses the HTTP 'bearer' scheme, which allows the client to authenticate using a JSON Web Token (JWT) that is passed in the Authorization header of the request.", }, apiKeyAuth: { - type: 'apiKey', - in: 'header', - name: 'X-API-Key', - description: 'This security definition uses an API key, which is passed in the header of the request as the value of the "X-API-Key" header. The client must provide a valid key in order to access the API.' - } + type: "apiKey", + in: "header", + name: "X-API-Key", + description: 'This security definition uses an API key, which is passed in the header of the request as the value of the "X-API-Key" header. The client must provide a valid key in order to access the API.', + }, }, definitions: { CurrentUser: { - _id: '', - email: 'johndoe@gmail.com', - firstName: 'John', - lastName: 'Doe', - publicKey: 'johns_nacl_public_key', - encryptedPrivateKey: 'johns_enc_nacl_private_key', - iv: 'iv_of_enc_nacl_private_key', - tag: 'tag_of_enc_nacl_private_key', - updatedAt: '2023-01-13T14:16:12.210Z', - createdAt: '2023-01-13T14:16:12.210Z' + _id: "", + email: "johndoe@gmail.com", + firstName: "John", + lastName: "Doe", + publicKey: "johns_nacl_public_key", + encryptedPrivateKey: "johns_enc_nacl_private_key", + iv: "iv_of_enc_nacl_private_key", + tag: "tag_of_enc_nacl_private_key", + updatedAt: "2023-01-13T14:16:12.210Z", + createdAt: "2023-01-13T14:16:12.210Z", }, Membership: { user: { - _id: '', - email: 'johndoe@gmail.com', - firstName: 'John', - lastName: 'Doe', - publicKey: 'johns_nacl_public_key', - updatedAt: '2023-01-13T14:16:12.210Z', - createdAt: '2023-01-13T14:16:12.210Z' + _id: "", + email: "johndoe@gmail.com", + firstName: "John", + lastName: "Doe", + publicKey: "johns_nacl_public_key", + updatedAt: "2023-01-13T14:16:12.210Z", + createdAt: "2023-01-13T14:16:12.210Z", }, - workspace: '', - role: 'admin' + workspace: "", + role: "admin", }, MembershipOrg: { user: { - _id: '', - email: 'johndoe@gmail.com', - firstName: 'John', - lastName: 'Doe', - publicKey: 'johns_nacl_public_key', - updatedAt: '2023-01-13T14:16:12.210Z', - createdAt: '2023-01-13T14:16:12.210Z' + _id: "", + email: "johndoe@gmail.com", + firstName: "John", + lastName: "Doe", + publicKey: "johns_nacl_public_key", + updatedAt: "2023-01-13T14:16:12.210Z", + createdAt: "2023-01-13T14:16:12.210Z", }, - organization: '', - role: 'owner', - status: 'accepted' + organization: "", + role: "owner", + status: "accepted", }, Organization: { - _id: '', - name: 'Acme Corp.', - customerId: '' + _id: "", + name: "Acme Corp.", + customerId: "", }, Project: { - name: 'My Project', - organization: '', + name: "My Project", + organization: "", environments: [{ - name: 'development', - slug: 'dev' - }] + name: "development", + slug: "dev", + }], }, ProjectKey: { - encryptedkey: '', - nonce: '', + encryptedkey: "", + nonce: "", sender: { - publicKey: 'senders_nacl_public_key' + publicKey: "senders_nacl_public_key", }, - receiver: '', - workspace: '' + receiver: "", + workspace: "", }, CreateSecret: { - type: 'shared', - secretKeyCiphertext: '', - secretKeyIV: '', - secretKeyTag: '', - secretValueCiphertext: '', - secretValueIV: '', - secretValueTag: '', - secretCommentCiphertext: '', - secretCommentIV: '', - secretCommentTag: '' + type: "shared", + secretKeyCiphertext: "", + secretKeyIV: "", + secretKeyTag: "", + secretValueCiphertext: "", + secretValueIV: "", + secretValueTag: "", + secretCommentCiphertext: "", + secretCommentIV: "", + secretCommentTag: "", }, UpdateSecret: { - id: '', - secretKeyCiphertext: '', - secretKeyIV: '', - secretKeyTag: '', - secretValueCiphertext: '', - secretValueIV: '', - secretValueTag: '', - secretCommentCiphertext: '', - secretCommentIV: '', - secretCommentTag: '' + id: "", + secretKeyCiphertext: "", + secretKeyIV: "", + secretKeyTag: "", + secretValueCiphertext: "", + secretValueIV: "", + secretValueTag: "", + secretCommentCiphertext: "", + secretCommentIV: "", + secretCommentTag: "", }, Secret: { - _id: '', + _id: "", version: 1, - workspace : '', - type: 'shared', + workspace : "", + type: "shared", user: null, - secretKeyCiphertext: '', - secretKeyIV: '', - secretKeyTag: '', - secretValueCiphertext: '', - secretValueIV: '', - secretValueTag: '', - secretCommentCiphertext: '', - secretCommentIV: '', - secretCommentTag: '', - updatedAt: '2023-01-13T14:16:12.210Z', - createdAt: '2023-01-13T14:16:12.210Z' + secretKeyCiphertext: "", + secretKeyIV: "", + secretKeyTag: "", + secretValueCiphertext: "", + secretValueIV: "", + secretValueTag: "", + secretCommentCiphertext: "", + secretCommentIV: "", + secretCommentTag: "", + updatedAt: "2023-01-13T14:16:12.210Z", + createdAt: "2023-01-13T14:16:12.210Z", }, Log: { - _id: '', + _id: "", user: { - _id: '', - email: 'johndoe@gmail.com', - firstName: 'John', - lastName: 'Doe' + _id: "", + email: "johndoe@gmail.com", + firstName: "John", + lastName: "Doe", }, - workspace: '', + workspace: "", actionNames: [ - 'addSecrets' + "addSecrets", ], actions: [ { - name: 'addSecrets', - user: '', - workspace: '', + name: "addSecrets", + user: "", + workspace: "", payload: [ { - oldSecretVersion: '', - newSecretVersion: '' - } - ] - } + oldSecretVersion: "", + newSecretVersion: "", + }, + ], + }, ], - channel: 'cli', - ipAddress: '192.168.0.1', - updatedAt: '2023-01-13T14:16:12.210Z', - createdAt: '2023-01-13T14:16:12.210Z' + channel: "cli", + ipAddress: "192.168.0.1", + updatedAt: "2023-01-13T14:16:12.210Z", + createdAt: "2023-01-13T14:16:12.210Z", }, SecretSnapshot: { - workspace: '', + workspace: "", version: 1, secretVersions: [ { - _id: '' - } - ] + _id: "", + }, + ], }, SecretVersion: { - _id: '', - secret: '', + _id: "", + secret: "", version: 1, - workspace: '', - type: 'shared', - user: '', - environment: 'dev', - isDeleted: '', - secretKeyCiphertext: '', - secretKeyIV: '', - secretKeyTag: '', - secretValueCiphertext: '', - secretValueIV: '', - secretValueTag: '', + workspace: "", + type: "shared", + user: "", + environment: "dev", + isDeleted: "", + secretKeyCiphertext: "", + secretKeyIV: "", + secretKeyTag: "", + secretValueCiphertext: "", + secretValueIV: "", + secretValueTag: "", }, ServiceTokenData: { - _id: '', - name: '', - workspace: '', - environment: '', + _id: "", + name: "", + workspace: "", + environment: "", user: { - _id: '', - firstName: '', - lastName: '' + _id: "", + firstName: "", + lastName: "", }, - expiresAt: '2023-01-13T14:16:12.210Z', - encryptedKey: '', - iv: '', - tag: '', - updatedAt: '2023-01-13T14:16:12.210Z', - createdAt: '2023-01-13T14:16:12.210Z' - } - } + expiresAt: "2023-01-13T14:16:12.210Z", + encryptedKey: "", + iv: "", + tag: "", + updatedAt: "2023-01-13T14:16:12.210Z", + createdAt: "2023-01-13T14:16:12.210Z", + }, + }, }; - const outputJSONFile = '../spec.json'; - const outputYAMLFile = '../docs/spec.yaml'; - const endpointsFiles = ['../src/index.ts']; + const outputJSONFile = "../spec.json"; + const outputYAMLFile = "../docs/spec.yaml"; + const endpointsFiles = ["../src/index.ts"]; const spec = await swaggerAutogen(outputJSONFile, endpointsFiles, doc); await fs.writeFile(outputYAMLFile, yaml.dump(spec.data)); diff --git a/backend/tests/helper/helper.ts b/backend/tests/helper/helper.ts index d72a101c1f..510f5f3535 100644 --- a/backend/tests/helper/helper.ts +++ b/backend/tests/helper/helper.ts @@ -4,15 +4,15 @@ import axiosInstance from "../../src/config/request"; import { Secret } from "../../src/models"; import { testUserEmail, testUserPassword } from "../../src/utils/addDevelopmentUser"; // eslint-disable-next-line @typescript-eslint/no-var-requires -const crypto = require('crypto') +const crypto = require("crypto") // eslint-disable-next-line @typescript-eslint/no-var-requires -const jsrp = require('jsrp'); +const jsrp = require("jsrp"); // eslint-disable-next-line @typescript-eslint/no-var-requires -const axios = require('axios'); +const axios = require("axios"); import { plainTextWorkspaceKey, testWorkspaceId } from "../../src/utils/addDevelopmentUser"; import { - encryptSymmetric128BitHexKeyUTF8 -} from '../../src/utils/crypto'; + encryptSymmetric128BitHexKeyUTF8, +} from "../../src/utils/crypto"; interface TokenData { token: string; @@ -37,11 +37,11 @@ export const getJWTFromTestUser = (): Promise => { // POST: /login1 const reqBody = { email: EMAIL, - clientPublicKey + clientPublicKey, } - const loginOneRes = await axiosInstance.post('http://localhost:4000/api/v1/auth/login1', reqBody); + const loginOneRes = await axiosInstance.post("http://localhost:4000/api/v1/auth/login1", reqBody); const serverPublicKey = loginOneRes.data.serverPublicKey; const salt = loginOneRes.data.salt; @@ -53,10 +53,10 @@ export const getJWTFromTestUser = (): Promise => { // POST: /login2 const reqBody2 = { email: EMAIL, - clientProof + clientProof, } - const response2 = await axiosInstance.post('http://localhost:4000/api/v1/auth/login2', reqBody2); + const response2 = await axiosInstance.post("http://localhost:4000/api/v1/auth/login2", reqBody2); resolve(response2.data) }) @@ -65,25 +65,25 @@ export const getJWTFromTestUser = (): Promise => { export const getServiceTokenFromTestUser = async () => { const loggedInUserDetails = await getJWTFromTestUser() - const randomBytes = crypto.randomBytes(16).toString('hex'); + const randomBytes = crypto.randomBytes(16).toString("hex"); const { ciphertext, iv, tag } = encryptSymmetric128BitHexKeyUTF8({ plaintext: plainTextWorkspaceKey, key: randomBytes, }); - const newServiceToken = await axiosInstance.post('http://localhost:4000/api/v2/service-token/', { - 'name': "test service token", - 'workspaceId': testWorkspaceId, - 'environment': "dev", - 'encryptedKey': ciphertext, - 'iv': iv, - 'tag': tag, - 'expiresIn': Date.now() + 90000, - 'permissions': ["read"] + const newServiceToken = await axiosInstance.post("http://localhost:4000/api/v2/service-token/", { + "name": "test service token", + "workspaceId": testWorkspaceId, + "environment": "dev", + "encryptedKey": ciphertext, + "iv": iv, + "tag": tag, + "expiresIn": Date.now() + 90000, + "permissions": ["read"], }, { headers: { - 'Authorization': `Bearer ${loggedInUserDetails.token}` - } + "Authorization": `Bearer ${loggedInUserDetails.token}`, + }, }); return `${newServiceToken.data.serviceToken}.${randomBytes}` diff --git a/backend/tests/integration-tests/routes/v2/service-tokens.ts b/backend/tests/integration-tests/routes/v2/service-tokens.ts index b011db36f8..15d776bdd9 100644 --- a/backend/tests/integration-tests/routes/v2/service-tokens.ts +++ b/backend/tests/integration-tests/routes/v2/service-tokens.ts @@ -1,6 +1,6 @@ -import request from 'supertest' -import main from '../../../../src/index' -import { getServiceTokenFromTestUser } from '../../../helper/helper'; +import request from "supertest" +import main from "../../../../src/index" +import { getServiceTokenFromTestUser } from "../../../helper/helper"; let server: any; beforeAll(async () => { @@ -20,18 +20,18 @@ describe("GET /api/v2/service-token", () => { // get the service token details const serviceTokenDetails = await request(server) .get("/api/v2/service-token") - .set('Authorization', `Bearer ${serviceToken}`) + .set("Authorization", `Bearer ${serviceToken}`) expect(serviceTokenDetails.body).toMatchObject({ _id: expect.any(String), - name: 'test service token', - workspace: '63cefb15c8d3175601cfa989', - environment: 'dev', + name: "test service token", + workspace: "63cefb15c8d3175601cfa989", + environment: "dev", user: { - _id: '63cefa6ec8d3175601cfa980', - email: 'test@localhost.local', - firstName: 'Jake', - lastName: 'Moni', + _id: "63cefa6ec8d3175601cfa980", + email: "test@localhost.local", + firstName: "Jake", + lastName: "Moni", isMfaEnabled: false, mfaMethods: expect.any(Array), devices: [ @@ -49,7 +49,7 @@ describe("GET /api/v2/service-token", () => { encryptedKey: expect.any(String), iv: expect.any(String), tag: expect.any(String), - permissions: ['read'], + permissions: ["read"], createdAt: expect.any(String), updatedAt: expect.any(String), }); diff --git a/backend/tests/setupTests.ts b/backend/tests/setupTests.ts index 903347a2ac..ef30ce85a8 100644 --- a/backend/tests/setupTests.ts +++ b/backend/tests/setupTests.ts @@ -1,7 +1,7 @@ -import { Server } from 'http'; -import main from '../src'; -import { describe, expect, it, beforeAll, afterAll } from '@jest/globals'; -import request from 'supertest'; +import { Server } from "http"; +import main from "../src"; +import { afterAll, beforeAll, describe, expect, it } from "@jest/globals"; +import request from "supertest"; let server: Server; @@ -13,9 +13,9 @@ afterAll(async () => { server.close(); }); -describe('Healthcheck endpoint', () => { - it('GET /healthcheck should return OK', async () => { - const res = await request(server).get('/healthcheck'); +describe("Healthcheck endpoint", () => { + it("GET /healthcheck should return OK", async () => { + const res = await request(server).get("/healthcheck"); expect(res.status).toEqual(200); }); }); diff --git a/backend/tests/unit-tests/utils/crypto.test.ts b/backend/tests/unit-tests/utils/crypto.test.ts index d50b3057c9..f9f2aba01d 100644 --- a/backend/tests/unit-tests/utils/crypto.test.ts +++ b/backend/tests/unit-tests/utils/crypto.test.ts @@ -1,78 +1,78 @@ -import { describe, test, expect } from '@jest/globals'; +import { describe, expect, test } from "@jest/globals"; import { decryptAsymmetric, encryptAsymmetric, -} from '../../../src/utils/crypto'; +} from "../../../src/utils/crypto"; -describe('Crypto', () => { - describe('encryptAsymmetric', () => { - describe('given all valid publicKey, privateKey and plaintext', () => { - const publicKey = '6U5m6S5jlyazJ+R4z7Yf/Ah4th4JwKxDN8Wn7+upvzw='; - const privateKey = 'Z8W53YV+2ddjJCrFwzptjK96y2QsQI9oXuvfcx+qxz0='; - const plaintext = 'secret-message'; +describe("Crypto", () => { + describe("encryptAsymmetric", () => { + describe("given all valid publicKey, privateKey and plaintext", () => { + const publicKey = "6U5m6S5jlyazJ+R4z7Yf/Ah4th4JwKxDN8Wn7+upvzw="; + const privateKey = "Z8W53YV+2ddjJCrFwzptjK96y2QsQI9oXuvfcx+qxz0="; + const plaintext = "secret-message"; - test('should encrypt plain text', () => { + test("should encrypt plain text", () => { const result = encryptAsymmetric({ plaintext, publicKey, privateKey }); expect(result.ciphertext).toBeDefined(); expect(result.nonce).toBeDefined(); }); }); - describe('given empty/undefined publicKey', () => { + describe("given empty/undefined publicKey", () => { let publicKey: string; - const privateKey = 'Z8W53YV+2ddjJCrFwzptjK96y2QsQI9oXuvfcx+qxz0='; - const plaintext = 'secret-message'; + const privateKey = "Z8W53YV+2ddjJCrFwzptjK96y2QsQI9oXuvfcx+qxz0="; + const plaintext = "secret-message"; - test('should throw error if publicKey is undefined', () => { + test("should throw error if publicKey is undefined", () => { expect(() => { encryptAsymmetric({ plaintext, publicKey, privateKey }); - }).toThrowError('invalid encoding'); + }).toThrowError("invalid encoding"); }); - test('should throw error if publicKey is empty string', () => { - publicKey = ''; + test("should throw error if publicKey is empty string", () => { + publicKey = ""; expect(() => { encryptAsymmetric({ plaintext, publicKey, privateKey }); - }).toThrowError('bad public key size'); + }).toThrowError("bad public key size"); }); }); - describe('given empty/undefined privateKey', () => { - const publicKey = '6U5m6S5jlyazJ+R4z7Yf/Ah4th4JwKxDN8Wn7+upvzw='; + describe("given empty/undefined privateKey", () => { + const publicKey = "6U5m6S5jlyazJ+R4z7Yf/Ah4th4JwKxDN8Wn7+upvzw="; let privateKey: string; - const plaintext = 'secret-message'; + const plaintext = "secret-message"; - test('should throw error if privateKey is undefined', () => { + test("should throw error if privateKey is undefined", () => { expect(() => { encryptAsymmetric({ plaintext, publicKey, privateKey }); - }).toThrowError('invalid encoding'); + }).toThrowError("invalid encoding"); }); - test('should throw error if privateKey is empty string', () => { - privateKey = ''; + test("should throw error if privateKey is empty string", () => { + privateKey = ""; expect(() => { encryptAsymmetric({ plaintext, publicKey, privateKey }); - }).toThrowError('bad secret key size'); + }).toThrowError("bad secret key size"); }); }); - describe('given undefined/invalid plaint text', () => { - const publicKey = '6U5m6S5jlyazJ+R4z7Yf/Ah4th4JwKxDN8Wn7+upvzw='; - const privateKey = 'Z8W53YV+2ddjJCrFwzptjK96y2QsQI9oXuvfcx+qxz0='; + describe("given undefined/invalid plaint text", () => { + const publicKey = "6U5m6S5jlyazJ+R4z7Yf/Ah4th4JwKxDN8Wn7+upvzw="; + const privateKey = "Z8W53YV+2ddjJCrFwzptjK96y2QsQI9oXuvfcx+qxz0="; let plaintext: string; - test('should throw error if plaintext is undefined', () => { + test("should throw error if plaintext is undefined", () => { expect(() => { encryptAsymmetric({ plaintext, publicKey, privateKey }); - }).toThrowError('expected string'); + }).toThrowError("expected string"); }); - test('should encrypt plaintext containing special characters', () => { - plaintext = '131@#$%235!@#&*(&123sadfkjadjf'; + test("should encrypt plaintext containing special characters", () => { + plaintext = "131@#$%235!@#&*(&123sadfkjadjf"; const result = encryptAsymmetric({ plaintext, publicKey, - privateKey + privateKey, }); expect(result.ciphertext).toBeDefined(); expect(result.nonce).toBeDefined(); @@ -80,17 +80,17 @@ describe('Crypto', () => { }); }); - describe('decryptAsymmetric', () => { - describe('given all valid publicKey, privateKey and plaintext', () => { - const publicKey = '6U5m6S5jlyazJ+R4z7Yf/Ah4th4JwKxDN8Wn7+upvzw='; - const privateKey = 'Z8W53YV+2ddjJCrFwzptjK96y2QsQI9oXuvfcx+qxz0='; - const plaintext = 'secret-message'; + describe("decryptAsymmetric", () => { + describe("given all valid publicKey, privateKey and plaintext", () => { + const publicKey = "6U5m6S5jlyazJ+R4z7Yf/Ah4th4JwKxDN8Wn7+upvzw="; + const privateKey = "Z8W53YV+2ddjJCrFwzptjK96y2QsQI9oXuvfcx+qxz0="; + const plaintext = "secret-message"; - test('should decrypt the encrypted plaintext', () => { + test("should decrypt the encrypted plaintext", () => { const encryptedResult = encryptAsymmetric({ plaintext, publicKey, - privateKey + privateKey, }); const ciphertext = encryptedResult.ciphertext; const nonce = encryptedResult.nonce; @@ -99,7 +99,7 @@ describe('Crypto', () => { ciphertext, nonce, publicKey, - privateKey + privateKey, }); expect(decryptedResult).toBeDefined(); @@ -107,18 +107,18 @@ describe('Crypto', () => { }); }); - describe('given ciphertext or nonce is modified before decrypt', () => { - const publicKey = '6U5m6S5jlyazJ+R4z7Yf/Ah4th4JwKxDN8Wn7+upvzw='; - const privateKey = 'Z8W53YV+2ddjJCrFwzptjK96y2QsQI9oXuvfcx+qxz0='; - const plaintext = 'secret-message'; + describe("given ciphertext or nonce is modified before decrypt", () => { + const publicKey = "6U5m6S5jlyazJ+R4z7Yf/Ah4th4JwKxDN8Wn7+upvzw="; + const privateKey = "Z8W53YV+2ddjJCrFwzptjK96y2QsQI9oXuvfcx+qxz0="; + const plaintext = "secret-message"; - test('should throw error if ciphertext is modified', () => { + test("should throw error if ciphertext is modified", () => { const encryptedResult = encryptAsymmetric({ plaintext, publicKey, - privateKey + privateKey, }); - const ciphertext = '=12adfJ@#52af1231=123'; // modified + const ciphertext = "=12adfJ@#52af1231=123"; // modified const nonce = encryptedResult.nonce; expect(() => { @@ -126,28 +126,28 @@ describe('Crypto', () => { ciphertext, nonce, publicKey, - privateKey + privateKey, }); - }).toThrowError('invalid encoding'); + }).toThrowError("invalid encoding"); }); - test('should throw error if nonce is modified', () => { + test("should throw error if nonce is modified", () => { const encryptedResult = encryptAsymmetric({ plaintext, publicKey, - privateKey + privateKey, }); const ciphertext = encryptedResult.ciphertext; - const nonce = '=12adfJ@#52af1231=123'; // modified + const nonce = "=12adfJ@#52af1231=123"; // modified expect(() => { decryptAsymmetric({ ciphertext, nonce, publicKey, - privateKey + privateKey, }); - }).toThrowError('invalid encoding'); + }).toThrowError("invalid encoding"); }); }); }); diff --git a/backend/tests/unit-tests/utils/posthog.test.ts b/backend/tests/unit-tests/utils/posthog.test.ts index 9f202385c3..5c05684f4a 100644 --- a/backend/tests/unit-tests/utils/posthog.test.ts +++ b/backend/tests/unit-tests/utils/posthog.test.ts @@ -1,29 +1,29 @@ -import { describe, test, expect } from '@jest/globals'; -import { getChannelFromUserAgent } from '../../../src/utils/posthog'; +import { describe, expect, test } from "@jest/globals"; +import { getChannelFromUserAgent } from "../../../src/utils/posthog"; -describe('posthog getChannelFromUserAgent', () => { +describe("posthog getChannelFromUserAgent", () => { test("should return 'web' when userAgent includes 'mozilla'", () => { const userAgent = - 'Mozilla/5.0 (Linux; Android 10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.115 Mobile Safari/537.36'; + "Mozilla/5.0 (Linux; Android 10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.115 Mobile Safari/537.36"; const channel = getChannelFromUserAgent(userAgent); - expect(channel).toBe('web'); + expect(channel).toBe("web"); }); test("should return 'cli'", () => { - const userAgent = 'cli'; + const userAgent = "cli"; const channel = getChannelFromUserAgent(userAgent); - expect(channel).toBe('cli'); + expect(channel).toBe("cli"); }); test("should return 'k8-operator'", () => { - const userAgent = 'k8-operator'; + const userAgent = "k8-operator"; const channel = getChannelFromUserAgent(userAgent); - expect(channel).toBe('k8-operator'); + expect(channel).toBe("k8-operator"); }); - test('should return undefined if no userAgent', () => { + test("should return undefined if no userAgent", () => { const userAgent = undefined; const channel = getChannelFromUserAgent(userAgent); - expect(channel).toBe('other'); + expect(channel).toBe("other"); }); }); diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js index 155e6d6e88..e9cec0e24b 100644 --- a/frontend/.eslintrc.js +++ b/frontend/.eslintrc.js @@ -10,66 +10,68 @@ module.exports = { es2021: true }, extends: [ - 'airbnb', - 'airbnb-typescript', - 'airbnb/hooks', - 'plugin:react/recommended', - 'prettier', - 'plugin:storybook/recommended' + "airbnb", + "airbnb-typescript", + "airbnb/hooks", + "plugin:react/recommended", + "prettier", + "plugin:storybook/recommended" ], parserOptions: { - ecmaVersion: 'latest', - sourceType: 'module', - project: './tsconfig.json', + ecmaVersion: "latest", + sourceType: "module", + project: "./tsconfig.json", ecmaFeatures: { jsx: true }, tsconfigRootDir: __dirname }, - plugins: ['react', 'prettier', 'simple-import-sort', 'import'], + plugins: ["react", "prettier", "simple-import-sort", "import"], rules: { - 'react/react-in-jsx-scope': 'off', - 'import/prefer-default-export': 'off', - 'react-hooks/exhaustive-deps': 'off', - '@typescript-eslint/ban-ts-comment': 'warn', - 'react/jsx-props-no-spreading': 'off', // switched off for component building + quotes: ["error", "double", { avoidEscape: true }], + "comma-dangle": ["error", "only-multiline"], + "react/react-in-jsx-scope": "off", + "import/prefer-default-export": "off", + "react-hooks/exhaustive-deps": "off", + "@typescript-eslint/ban-ts-comment": "warn", + "react/jsx-props-no-spreading": "off", // switched off for component building // TODO: This rule will be switched ON after complete revamp of frontend - '@typescript-eslint/no-explicit-any': 'off', - 'no-console': 'off', - 'arrow-body-style': 'off', - 'no-underscore-dangle': [ - 'error', + "@typescript-eslint/no-explicit-any": "off", + "no-console": "off", + "arrow-body-style": "off", + "no-underscore-dangle": [ + "error", { - allow: ['_id'] + allow: ["_id"] } ], - 'jsx-a11y/anchor-is-valid': 'off', + "jsx-a11y/anchor-is-valid": "off", // all those tags must be converted to label or a p component // - 'react/require-default-props': 'off', - 'react/jsx-filename-extension': [ + "react/require-default-props": "off", + "react/jsx-filename-extension": [ 1, { - extensions: ['.tsx', '.ts'] + extensions: [".tsx", ".ts"] } ], // TODO: turn this rule ON after migration. everything should use arrow functions - 'react/function-component-definition': [ + "react/function-component-definition": [ 0, { - namedComponents: 'arrow-function' + namedComponents: "arrow-function" } ], - 'react/no-unknown-property': [ - 'error', + "react/no-unknown-property": [ + "error", { - ignore: ['jsx'] + ignore: ["jsx"] } ], - '@typescript-eslint/no-non-null-assertion': 'off', - 'simple-import-sort/exports': 'warn', - 'simple-import-sort/imports': [ - 'warn', + "@typescript-eslint/no-non-null-assertion": "off", + "simple-import-sort/exports": "warn", + "simple-import-sort/imports": [ + "warn", { groups: [ // Node.js builtins. You could also generate this regex if you use a `.js` config. @@ -77,26 +79,26 @@ module.exports = { // Note that if you use the `node:` prefix for Node.js builtins, // you can avoid this complexity: You can simply use "^node:". [ - '^(assert|buffer|child_process|cluster|console|constants|crypto|dgram|dns|domain|events|fs|http|https|module|net|os|path|punycode|querystring|readline|repl|stream|string_decoder|sys|timers|tls|tty|url|util|vm|zlib|freelist|v8|process|async_hooks|http2|perf_hooks)(/.*|$)' + "^(assert|buffer|child_process|cluster|console|constants|crypto|dgram|dns|domain|events|fs|http|https|module|net|os|path|punycode|querystring|readline|repl|stream|string_decoder|sys|timers|tls|tty|url|util|vm|zlib|freelist|v8|process|async_hooks|http2|perf_hooks)(/.*|$)" ], // Packages `react` related packages - ['^react', '^next', '^@?\\w'], - ['^@app'], + ["^react", "^next", "^@?\\w"], + ["^@app"], // Internal packages. - ['^~(/.*|$)'], + ["^~(/.*|$)"], // Relative imports - ['^\\.\\.(?!/?$)', '^\\.\\./?$', '^\\./(?=.*/)(?!/?$)', '^\\.(?!/?$)', '^\\./?$'], + ["^\\.\\.(?!/?$)", "^\\.\\./?$", "^\\./(?=.*/)(?!/?$)", "^\\.(?!/?$)", "^\\./?$"], // Style imports. - ['^.+\\.?(css|scss)$'] + ["^.+\\.?(css|scss)$"] ] } ] }, - ignorePatterns: ['next.config.js'], + ignorePatterns: ["next.config.js"], settings: { - 'import/resolver': { + "import/resolver": { typescript: { - project: ['./tsconfig.json'] + project: ["./tsconfig.json"] } } } diff --git a/frontend/.prettierrc b/frontend/.prettierrc index da5d26a535..0b8ef54d2f 100644 --- a/frontend/.prettierrc +++ b/frontend/.prettierrc @@ -1,5 +1,5 @@ { - "singleQuote": true, + "singleQuote": false, "printWidth": 100, "trailingComma": "none", "tabWidth": 2, diff --git a/frontend/package.json b/frontend/package.json index 9d5071736e..efe833849f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -6,7 +6,8 @@ "build": "next build", "start": "next start", "start:docker": "next build && next start", - "lint": "eslint --fix --ext js,ts,tsx ./src", + "lint": "eslint --ext js,ts,tsx ./src", + "lint-and-fix": "eslint --fix --ext js,ts,tsx ./src", "type-check": "tsc --project tsconfig.json", "storybook": "storybook dev -p 6006 -s ./public", "build-storybook": "storybook build" diff --git a/frontend/src/components/RouteGuard.tsx b/frontend/src/components/RouteGuard.tsx index 3b755341e8..5c874541af 100644 --- a/frontend/src/components/RouteGuard.tsx +++ b/frontend/src/components/RouteGuard.tsx @@ -1,8 +1,8 @@ -import { ReactNode, useEffect, useState } from 'react'; -import { useRouter } from 'next/router'; +import { ReactNode, useEffect, useState } from "react"; +import { useRouter } from "next/router"; -import { publicPaths } from '@app/const'; -import checkAuth from '@app/pages/api/auth/CheckAuth'; +import { publicPaths } from "@app/const"; +import checkAuth from "@app/pages/api/auth/CheckAuth"; // #TODO: finish spinner only when the data loads fully // #TODO: Redirect somewhere if the page does not exist @@ -21,7 +21,7 @@ export default function RouteGuard({ children }: Prop): JSX.Element { */ async function authCheck(url: string) { // Make sure that we don't redirect when the user is on the following pages. - const path = `/${url.split('?')[0].split('/')[1]}`; + const path = `/${url.split("?")[0].split("/")[1]}`; // Check if the user is authenticated const response = await checkAuth(); @@ -30,15 +30,15 @@ export default function RouteGuard({ children }: Prop): JSX.Element { if (!publicPaths.includes(path)) { try { if (response.status !== 200) { - router.push('/login'); - console.log('Unauthorized to access.'); + router.push("/login"); + console.log("Unauthorized to access."); setAuthorized(false); } else { setAuthorized(true); - console.log('Authorized to access.'); + console.log("Authorized to access."); } } catch (error) { - console.log('Error (probably the authCheck route is stuck again...):', error); + console.log("Error (probably the authCheck route is stuck again...):", error); } } } @@ -53,16 +53,16 @@ export default function RouteGuard({ children }: Prop): JSX.Element { // #TODO: add the loading page when not yet authorized. const hideContent = () => setAuthorized(false); // const onError = () => setAuthorized(true) - router.events.on('routeChangeStart', hideContent); + router.events.on("routeChangeStart", hideContent); // router.events.on("routeChangeError", onError); // on route change complete - run auth check - router.events.on('routeChangeComplete', authCheck); + router.events.on("routeChangeComplete", authCheck); // unsubscribe from events in useEffect return function return () => { - router.events.off('routeChangeStart', hideContent); - router.events.off('routeChangeComplete', authCheck); + router.events.off("routeChangeStart", hideContent); + router.events.off("routeChangeComplete", authCheck); // router.events.off("routeChangeError", onError); }; // eslint-disable-next-line react-hooks/exhaustive-deps diff --git a/frontend/src/components/analytics/posthog.ts b/frontend/src/components/analytics/posthog.ts index b6f3e4341f..706f795151 100644 --- a/frontend/src/components/analytics/posthog.ts +++ b/frontend/src/components/analytics/posthog.ts @@ -1,16 +1,16 @@ /* eslint-disable @typescript-eslint/ban-ts-comment */ /* eslint-disable no-undef */ -import posthog from 'posthog-js'; +import posthog from "posthog-js"; -import { ENV, POSTHOG_API_KEY, POSTHOG_HOST } from '../utilities/config'; +import { ENV, POSTHOG_API_KEY, POSTHOG_HOST } from "../utilities/config"; export const initPostHog = () => { // @ts-ignore console.log("Hi there 👋") try { - if (typeof window !== 'undefined') { + if (typeof window !== "undefined") { // @ts-ignore - if (ENV === 'production' && TELEMETRY_CAPTURING_ENABLED) { + if (ENV === "production" && TELEMETRY_CAPTURING_ENABLED) { posthog.init(POSTHOG_API_KEY, { api_host: POSTHOG_HOST }); diff --git a/frontend/src/components/basic/Error.tsx b/frontend/src/components/basic/Error.tsx index ab79fb24d2..bf892e03de 100644 --- a/frontend/src/components/basic/Error.tsx +++ b/frontend/src/components/basic/Error.tsx @@ -1,5 +1,5 @@ -import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faExclamationTriangle } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; const Error = ({ text }: { text: string }): JSX.Element => { return ( diff --git a/frontend/src/components/basic/EventFilter.tsx b/frontend/src/components/basic/EventFilter.tsx index 7c3a9dc258..46b2200f6a 100644 --- a/frontend/src/components/basic/EventFilter.tsx +++ b/frontend/src/components/basic/EventFilter.tsx @@ -1,5 +1,5 @@ -import React, { Fragment } from 'react'; -import { useTranslation } from 'react-i18next'; +import React, { Fragment } from "react"; +import { useTranslation } from "react-i18next"; import { faAngleDown, faEye, @@ -7,9 +7,9 @@ import { faShuffle, faTrash, faX -} from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Listbox, Transition } from '@headlessui/react'; +} from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Listbox, Transition } from "@headlessui/react"; interface ListBoxProps { selected: string; @@ -18,19 +18,19 @@ interface ListBoxProps { const eventOptions = [ { - name: 'addSecrets', + name: "addSecrets", icon: faPlus }, { - name: 'readSecrets', + name: "readSecrets", icon: faEye }, { - name: 'updateSecrets', + name: "updateSecrets", icon: faShuffle }, { - name: 'deleteSecrets', + name: "deleteSecrets", icon: faTrash } ]; @@ -48,13 +48,13 @@ const EventFilter = ({ selected, select }: ListBoxProps): JSX.Element => {
- {selected !== '' ? ( + {selected !== "" ? (

{t(`activity.event.${selected}`)}

) : ( -

{String(t('common.select-event'))}

+

{String(t("common.select-event"))}

)} - {selected !== '' ? ( - select('')} /> + {selected !== "" ? ( + select("")} /> ) : ( )} @@ -70,15 +70,15 @@ const EventFilter = ({ selected, select }: ListBoxProps): JSX.Element => { {({ selected: isSelected }) => ( - {' '} + {" "} {t(`activity.event.${event.name}`)} )} diff --git a/frontend/src/components/basic/InputField.tsx b/frontend/src/components/basic/InputField.tsx index df6dd14243..0bc01defc8 100644 --- a/frontend/src/components/basic/InputField.tsx +++ b/frontend/src/components/basic/InputField.tsx @@ -1,8 +1,8 @@ -import { memo, useState } from 'react'; -import { faCircle, faEye, faEyeSlash } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { memo, useState } from "react"; +import { faCircle, faEye, faEyeSlash } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import guidGenerator from '../utilities/randomId'; +import guidGenerator from "../utilities/randomId"; interface InputFieldProps { isStatic?: boolean; @@ -34,7 +34,7 @@ const InputField = ({ placeholder, isStatic, text -}: InputFieldProps & Pick) => { +}: InputFieldProps & Pick) => { const [passwordVisible, setPasswordVisible] = useState(false); if (isStatic === true) { @@ -64,28 +64,28 @@ const InputField = ({
onChangeHandler(e.target.value)} - type={passwordVisible === false ? type : 'text'} + type={passwordVisible === false ? type : "text"} placeholder={placeholder} value={value} required={isRequired} className={`${ blurred - ? 'text-bunker-800 group-hover:text-gray-400 focus:text-gray-400 active:text-gray-400' - : '' + ? "text-bunker-800 group-hover:text-gray-400 focus:text-gray-400 active:text-gray-400" + : "" } ${ - error ? 'focus:ring-red/50' : 'focus:ring-primary/50' + error ? "focus:ring-red/50" : "focus:ring-primary/50" } relative peer bg-mineshaft-900 rounded-md text-gray-400 text-md p-2 w-full min-w-16 outline-none focus:ring-4 duration-200`} name={name} spellCheck="false" autoComplete={autoComplete} id={id} /> - {label?.includes('Password') && ( + {label?.includes("Password") && (
diff --git a/frontend/src/components/basic/dialog/AddApiKeyDialog.tsx b/frontend/src/components/basic/dialog/AddApiKeyDialog.tsx index 5c2e262466..eeb0ca6b18 100644 --- a/frontend/src/components/basic/dialog/AddApiKeyDialog.tsx +++ b/frontend/src/components/basic/dialog/AddApiKeyDialog.tsx @@ -1,21 +1,21 @@ -import { Fragment, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { faCheck, faCopy } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Dialog, Transition } from '@headlessui/react'; +import { Fragment, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { faCheck, faCopy } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Dialog, Transition } from "@headlessui/react"; -import addAPIKey from '@app/pages/api/apiKey/addAPIKey'; +import addAPIKey from "@app/pages/api/apiKey/addAPIKey"; -import Button from '../buttons/Button'; -import InputField from '../InputField'; -import ListBox from '../Listbox'; +import Button from "../buttons/Button"; +import InputField from "../InputField"; +import ListBox from "../Listbox"; const expiryMapping = { - '1 day': 86400, - '7 days': 604800, - '1 month': 2592000, - '6 months': 15552000, - '12 months': 31104000 + "1 day": 86400, + "7 days": 604800, + "1 month": 2592000, + "6 months": 15552000, + "12 months": 31104000 }; type Props = { @@ -28,9 +28,9 @@ type Props = { // TODO: convert to TS const AddApiKeyDialog = ({ isOpen, closeModal, apiKeys, setApiKeys }: Props) => { - const [apiKey, setApiKey] = useState(''); - const [apiKeyName, setApiKeyName] = useState(''); - const [apiKeyExpiresIn, setApiKeyExpiresIn] = useState('1 day'); + const [apiKey, setApiKey] = useState(""); + const [apiKeyName, setApiKeyName] = useState(""); + const [apiKeyExpiresIn, setApiKeyExpiresIn] = useState("1 day"); const [apiKeyCopied, setApiKeyCopied] = useState(false); const { t } = useTranslation(); @@ -46,7 +46,7 @@ const AddApiKeyDialog = ({ isOpen, closeModal, apiKeys, setApiKeys }: Props) => function copyToClipboard() { // Get the text field - const copyText = document.getElementById('apiKey') as HTMLInputElement; + const copyText = document.getElementById("apiKey") as HTMLInputElement; // Select the text field copyText.select(); @@ -63,8 +63,8 @@ const AddApiKeyDialog = ({ isOpen, closeModal, apiKeys, setApiKeys }: Props) => const closeAddApiKeyModal = () => { closeModal(); - setApiKeyName(''); - setApiKey(''); + setApiKeyName(""); + setApiKey(""); }; return ( @@ -94,24 +94,24 @@ const AddApiKeyDialog = ({ isOpen, closeModal, apiKeys, setApiKeys }: Props) => leaveFrom="opacity-100 scale-100" leaveTo="opacity-0 scale-95" > - {apiKey === '' ? ( + {apiKey === "" ? ( - {t('section.api-key.add-dialog.title')} + {t("section.api-key.add-dialog.title")}

- {t('section.api-key.add-dialog.description')} + {t("section.api-key.add-dialog.description")}

@@ -133,10 +133,10 @@ const AddApiKeyDialog = ({ isOpen, closeModal, apiKeys, setApiKeys }: Props) =>
@@ -147,12 +147,12 @@ const AddApiKeyDialog = ({ isOpen, closeModal, apiKeys, setApiKeys }: Props) => as="h3" className="z-50 text-lg font-medium leading-6 text-gray-400" > - {t('section.api-key.add-dialog.copy-service-token')} + {t("section.api-key.add-dialog.copy-service-token")}

- {t('section.api-key.add-dialog.copy-service-token-description')} + {t("section.api-key.add-dialog.copy-service-token-description")}

@@ -181,7 +181,7 @@ const AddApiKeyDialog = ({ isOpen, closeModal, apiKeys, setApiKeys }: Props) => )} - {t('common.click-to-copy')} + {t("common.click-to-copy")} diff --git a/frontend/src/components/basic/dialog/AddIncidentContactDialog.tsx b/frontend/src/components/basic/dialog/AddIncidentContactDialog.tsx index 63535f2bef..e3e8acaa18 100644 --- a/frontend/src/components/basic/dialog/AddIncidentContactDialog.tsx +++ b/frontend/src/components/basic/dialog/AddIncidentContactDialog.tsx @@ -1,11 +1,11 @@ -import { Fragment, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { Dialog, Transition } from '@headlessui/react'; +import { Fragment, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { Dialog, Transition } from "@headlessui/react"; -import addIncidentContact from '@app/pages/api/organization/addIncidentContact'; +import addIncidentContact from "@app/pages/api/organization/addIncidentContact"; -import Button from '../buttons/Button'; -import InputField from '../InputField'; +import Button from "../buttons/Button"; +import InputField from "../InputField"; type Props = { isOpen: boolean; @@ -20,7 +20,7 @@ const AddIncidentContactDialog = ({ incidentContacts, setIncidentContacts }: Props) => { - const [incidentContactEmail, setIncidentContactEmail] = useState(''); + const [incidentContactEmail, setIncidentContactEmail] = useState(""); const { t } = useTranslation(); const submit = () => { @@ -29,7 +29,7 @@ const AddIncidentContactDialog = ({ ? incidentContacts.concat([incidentContactEmail]) : [incidentContactEmail] ); - addIncidentContact(localStorage.getItem('orgData.id') as string, incidentContactEmail); + addIncidentContact(localStorage.getItem("orgData.id") as string, incidentContactEmail); closeModal(); }; return ( @@ -61,16 +61,16 @@ const AddIncidentContactDialog = ({ > - {t('section.incident.add-dialog.title')} + {t("section.incident.add-dialog.title")}

- {t('section.incident.add-dialog.description')} + {t("section.incident.add-dialog.description")}

diff --git a/frontend/src/components/basic/dialog/AddProjectMemberDialog.tsx b/frontend/src/components/basic/dialog/AddProjectMemberDialog.tsx index aceeb9db9f..2a25c8be6d 100644 --- a/frontend/src/components/basic/dialog/AddProjectMemberDialog.tsx +++ b/frontend/src/components/basic/dialog/AddProjectMemberDialog.tsx @@ -1,10 +1,10 @@ -import { Fragment } from 'react'; -import { Trans, useTranslation } from 'react-i18next'; -import { useRouter } from 'next/router'; -import { Dialog, Transition } from '@headlessui/react'; +import { Fragment } from "react"; +import { Trans, useTranslation } from "react-i18next"; +import { useRouter } from "next/router"; +import { Dialog, Transition } from "@headlessui/react"; -import Button from '../buttons/Button'; -import ListBox from '../Listbox'; +import Button from "../buttons/Button"; +import ListBox from "../Listbox"; type Props = { isOpen: boolean; @@ -59,21 +59,21 @@ const AddProjectMemberDialog = ({ as="h3" className="z-50 text-lg font-medium leading-6 text-gray-400" > - {t('section.members.add-dialog.add-member-to-project')} + {t("section.members.add-dialog.add-member-to-project")} ) : ( - {t('section.members.add-dialog.already-all-invited')} + {t("section.members.add-dialog.already-all-invited")} )}
{data?.length > 0 ? (

- {t('section.members.add-dialog.user-will-email')} + {t("section.members.add-dialog.user-will-email")}

) : (

- {t('section.members.add-dialog.add-user-org-first')} + {t("section.members.add-dialog.add-user-org-first")}

)}
@@ -121,7 +121,7 @@ const AddProjectMemberDialog = ({
@@ -129,7 +129,7 @@ const AddProjectMemberDialog = ({
@@ -211,12 +211,12 @@ const AddServiceTokenDialog = ({ as="h3" className="z-50 text-lg font-medium leading-6 text-gray-400" > - {t('section.token.add-dialog.copy-service-token')} + {t("section.token.add-dialog.copy-service-token")}

- {t('section.token.add-dialog.copy-service-token-description')} + {t("section.token.add-dialog.copy-service-token-description")}

@@ -244,7 +244,7 @@ const AddServiceTokenDialog = ({ )} - {t('common.click-to-copy')} + {t("common.click-to-copy")} diff --git a/frontend/src/components/basic/dialog/AddUpdateEnvironmentDialog.tsx b/frontend/src/components/basic/dialog/AddUpdateEnvironmentDialog.tsx index 70e9b0f474..de5337ae69 100644 --- a/frontend/src/components/basic/dialog/AddUpdateEnvironmentDialog.tsx +++ b/frontend/src/components/basic/dialog/AddUpdateEnvironmentDialog.tsx @@ -1,8 +1,8 @@ -import { FormEventHandler, Fragment, useEffect, useState } from 'react'; -import { Dialog, Transition } from '@headlessui/react'; +import { FormEventHandler, Fragment, useEffect, useState } from "react"; +import { Dialog, Transition } from "@headlessui/react"; -import Button from '../buttons/Button'; -import InputField from '../InputField'; +import Button from "../buttons/Button"; +import InputField from "../InputField"; type FormFields = { name: string; slug: string }; @@ -31,14 +31,14 @@ export const AddUpdateEnvironmentDialog = ({ isEditMode, }: Props) => { const [formInput, setFormInput] = useState({ - name: '', - slug: '', + name: "", + slug: "", }); // This use effect can be removed when the unmount is happening from outside the component // When unmount happens outside state gets unmounted also useEffect(() => { - setFormInput(initialValues || { name: '', slug: '' }); + setFormInput(initialValues || { name: "", slug: "" }); }, [isOpen]); // REFACTOR: Move to react-hook-form with yup for better form management @@ -92,14 +92,14 @@ export const AddUpdateEnvironmentDialog = ({ className='text-lg font-medium leading-6 text-gray-400' > {isEditMode - ? 'Update environment' - : 'Create a new environment'} + ? "Update environment" + : "Create a new environment"}
onInputChange('name', val)} + onChangeHandler={(val) => onInputChange("name", val)} type='varName' value={formInput.name} placeholder='' @@ -111,7 +111,7 @@ export const AddUpdateEnvironmentDialog = ({
onInputChange('slug', val)} + onChangeHandler={(val) => onInputChange("slug", val)} type='varName' value={formInput.slug} placeholder='' @@ -128,8 +128,8 @@ export const AddUpdateEnvironmentDialog = ({ onButtonPressed={() => null} type='submit' color='mineshaft' - text={isEditMode ? 'Update' : 'Create'} - active={formInput.name !== '' && formInput.slug !== ''} + text={isEditMode ? "Update" : "Create"} + active={formInput.name !== "" && formInput.slug !== ""} size='md' />
diff --git a/frontend/src/components/basic/dialog/AddUserDialog.tsx b/frontend/src/components/basic/dialog/AddUserDialog.tsx index 68ce246968..b36c31d6c4 100644 --- a/frontend/src/components/basic/dialog/AddUserDialog.tsx +++ b/frontend/src/components/basic/dialog/AddUserDialog.tsx @@ -1,8 +1,8 @@ -import { Fragment } from 'react'; -import { Dialog, Transition } from '@headlessui/react'; +import { Fragment } from "react"; +import { Dialog, Transition } from "@headlessui/react"; -import Button from '../buttons/Button'; -import InputField from '../InputField'; +import Button from "../buttons/Button"; +import InputField from "../InputField"; type Props = { isOpen: boolean; diff --git a/frontend/src/components/basic/dialog/DeleteActionModal.tsx b/frontend/src/components/basic/dialog/DeleteActionModal.tsx index 05fd66a71f..7129466791 100644 --- a/frontend/src/components/basic/dialog/DeleteActionModal.tsx +++ b/frontend/src/components/basic/dialog/DeleteActionModal.tsx @@ -1,7 +1,7 @@ -import { Fragment, useEffect, useState } from 'react'; -import { Dialog, Transition } from '@headlessui/react'; +import { Fragment, useEffect, useState } from "react"; +import { Dialog, Transition } from "@headlessui/react"; -import InputField from '../InputField'; +import InputField from "../InputField"; // REFACTOR: Move all these modals into one reusable one type Props = { diff --git a/frontend/src/components/basic/dialog/DeleteEnvVar.tsx b/frontend/src/components/basic/dialog/DeleteEnvVar.tsx index 6daed29fdd..d2bcf5505e 100644 --- a/frontend/src/components/basic/dialog/DeleteEnvVar.tsx +++ b/frontend/src/components/basic/dialog/DeleteEnvVar.tsx @@ -47,11 +47,11 @@ export const DeleteEnvVar = ({ isOpen, onClose, onSubmit }: Props) => { > - {t('dashboard:sidebar.delete-key-dialog.title')} + {t("dashboard:sidebar.delete-key-dialog.title")}

- {t('dashboard:sidebar.delete-key-dialog.confirm-delete-message')} + {t("dashboard:sidebar.delete-key-dialog.confirm-delete-message")}

diff --git a/frontend/src/components/basic/dialog/DeleteUserDialog.tsx b/frontend/src/components/basic/dialog/DeleteUserDialog.tsx index 883e241c01..9b6ecf0126 100644 --- a/frontend/src/components/basic/dialog/DeleteUserDialog.tsx +++ b/frontend/src/components/basic/dialog/DeleteUserDialog.tsx @@ -1,5 +1,5 @@ -import { Fragment } from 'react'; -import { Dialog, Transition } from '@headlessui/react'; +import { Fragment } from "react"; +import { Dialog, Transition } from "@headlessui/react"; // #TODO: USE THIS. Currently it's not. Kinda complicated to set up because of state. diff --git a/frontend/src/components/basic/dialog/UpgradePlan.tsx b/frontend/src/components/basic/dialog/UpgradePlan.tsx index 95993c6a6e..2573036ebc 100644 --- a/frontend/src/components/basic/dialog/UpgradePlan.tsx +++ b/frontend/src/components/basic/dialog/UpgradePlan.tsx @@ -1,6 +1,6 @@ -import { Fragment } from 'react'; -import { useRouter } from 'next/router'; -import { Dialog, Transition } from '@headlessui/react'; +import { Fragment } from "react"; +import { useRouter } from "next/router"; +import { Dialog, Transition } from "@headlessui/react"; // REFACTOR: Move all these modals into one reusable one type Props = { diff --git a/frontend/src/components/basic/popups/BottomRightPopup.tsx b/frontend/src/components/basic/popups/BottomRightPopup.tsx index 58d8a498eb..9a2938ad61 100644 --- a/frontend/src/components/basic/popups/BottomRightPopup.tsx +++ b/frontend/src/components/basic/popups/BottomRightPopup.tsx @@ -1,5 +1,5 @@ -import { faXmark } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faXmark } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; interface PopupProps { buttonText: string; diff --git a/frontend/src/components/basic/table/ApiKeyTable.tsx b/frontend/src/components/basic/table/ApiKeyTable.tsx index 800ea7356c..1522df00d1 100644 --- a/frontend/src/components/basic/table/ApiKeyTable.tsx +++ b/frontend/src/components/basic/table/ApiKeyTable.tsx @@ -1,10 +1,10 @@ -import { faX } from '@fortawesome/free-solid-svg-icons'; +import { faX } from "@fortawesome/free-solid-svg-icons"; -import { useNotificationContext } from '@app/components/context/Notifications/NotificationProvider'; +import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider"; -import deleteAPIKey from '../../../pages/api/apiKey/deleteAPIKey'; -import guidGenerator from '../../utilities/randomId'; -import Button from '../buttons/Button'; +import deleteAPIKey from "../../../pages/api/apiKey/deleteAPIKey"; +import guidGenerator from "../../utilities/randomId"; +import Button from "../buttons/Button"; interface TokenProps { _id: string; @@ -58,7 +58,7 @@ const ApiKeyTable = ({ data, setApiKeys }: ServiceTokensProps) => { setApiKeys(data.filter((token) => token._id !== row._id)); createNotification({ text: `'${row.name}' API key has been revoked.`, - type: 'error' + type: "error" }); }} color="red" diff --git a/frontend/src/components/basic/table/EnvironmentsTable.tsx b/frontend/src/components/basic/table/EnvironmentsTable.tsx index 1a3ffe9065..b9c94534ad 100644 --- a/frontend/src/components/basic/table/EnvironmentsTable.tsx +++ b/frontend/src/components/basic/table/EnvironmentsTable.tsx @@ -1,13 +1,13 @@ -import { useEffect, useState } from 'react'; -import { faPencil, faPlus, faX } from '@fortawesome/free-solid-svg-icons'; -import { plans } from 'public/data/frequentConstants'; +import { useEffect, useState } from "react"; +import { faPencil, faPlus, faX } from "@fortawesome/free-solid-svg-icons"; +import { plans } from "public/data/frequentConstants"; -import { usePopUp } from '../../../hooks/usePopUp'; -import getOrganizationSubscriptions from '../../../pages/api/organization/GetOrgSubscription'; -import Button from '../buttons/Button'; -import { AddUpdateEnvironmentDialog } from '../dialog/AddUpdateEnvironmentDialog'; -import DeleteActionModal from '../dialog/DeleteActionModal'; -import UpgradePlanModal from '../dialog/UpgradePlan'; +import { usePopUp } from "../../../hooks/usePopUp"; +import getOrganizationSubscriptions from "../../../pages/api/organization/GetOrgSubscription"; +import Button from "../buttons/Button"; +import { AddUpdateEnvironmentDialog } from "../dialog/AddUpdateEnvironmentDialog"; +import DeleteActionModal from "../dialog/DeleteActionModal"; +import UpgradePlanModal from "../dialog/UpgradePlan"; type Env = { name: string; slug: string }; @@ -20,17 +20,17 @@ type Props = { const EnvironmentTable = ({ data = [], onCreateEnv, onDeleteEnv, onUpdateEnv }: Props) => { const { popUp, handlePopUpOpen, handlePopUpClose } = usePopUp([ - 'createUpdateEnv', - 'deleteEnv', - 'upgradePlan' + "createUpdateEnv", + "deleteEnv", + "upgradePlan" ] as const); - const [plan, setPlan] = useState(''); + const [plan, setPlan] = useState(""); const host = window.location.origin; useEffect(() => { // on initial load - run auth check (async () => { - const orgId = localStorage.getItem('orgData.id') as string; + const orgId = localStorage.getItem("orgData.id") as string; const subscriptions = await getOrganizationSubscriptions({ orgId }); @@ -44,7 +44,7 @@ const EnvironmentTable = ({ data = [], onCreateEnv, onDeleteEnv, onUpdateEnv }: const onEnvCreateCB = async (env: Env) => { try { await onCreateEnv(env); - handlePopUpClose('createUpdateEnv'); + handlePopUpClose("createUpdateEnv"); } catch (error) { console.error(error); } @@ -52,8 +52,8 @@ const EnvironmentTable = ({ data = [], onCreateEnv, onDeleteEnv, onUpdateEnv }: const onEnvUpdateCB = async (env: Env) => { try { - await onUpdateEnv((popUp.createUpdateEnv?.data as Pick)?.slug, env); - handlePopUpClose('createUpdateEnv'); + await onUpdateEnv((popUp.createUpdateEnv?.data as Pick)?.slug, env); + handlePopUpClose("createUpdateEnv"); } catch (error) { console.error(error); } @@ -61,8 +61,8 @@ const EnvironmentTable = ({ data = [], onCreateEnv, onDeleteEnv, onUpdateEnv }: const onEnvDeleteCB = async () => { try { - await onDeleteEnv((popUp.deleteEnv?.data as Pick)?.slug); - handlePopUpClose('deleteEnv'); + await onDeleteEnv((popUp.deleteEnv?.data as Pick)?.slug); + handlePopUpClose("deleteEnv"); } catch (error) { console.error(error); } @@ -85,10 +85,10 @@ const EnvironmentTable = ({ data = [], onCreateEnv, onDeleteEnv, onUpdateEnv }:
diff --git a/frontend/src/components/basic/table/ProjectUsersTable.tsx b/frontend/src/components/basic/table/ProjectUsersTable.tsx index 0f6df98d3b..a94d2b3136 100644 --- a/frontend/src/components/basic/table/ProjectUsersTable.tsx +++ b/frontend/src/components/basic/table/ProjectUsersTable.tsx @@ -1,22 +1,22 @@ -import { useEffect, useState } from 'react'; -import { useRouter } from 'next/router'; -import { faEye, faEyeSlash, faPenToSquare, faPlus, faX } from '@fortawesome/free-solid-svg-icons'; -import { plans } from 'public/data/frequentConstants'; +import { useEffect, useState } from "react"; +import { useRouter } from "next/router"; +import { faEye, faEyeSlash, faPenToSquare, faPlus, faX } from "@fortawesome/free-solid-svg-icons"; +import { plans } from "public/data/frequentConstants"; -import { useNotificationContext } from '@app/components/context/Notifications/NotificationProvider'; -import { Select, SelectItem } from '@app/components/v2'; -import updateUserProjectPermission from '@app/ee/api/memberships/UpdateUserProjectPermission'; -import getOrganizationSubscriptions from '@app/pages/api/organization/GetOrgSubscription'; -import changeUserRoleInWorkspace from '@app/pages/api/workspace/changeUserRoleInWorkspace'; -import deleteUserFromWorkspace from '@app/pages/api/workspace/deleteUserFromWorkspace'; -import getLatestFileKey from '@app/pages/api/workspace/getLatestFileKey'; -import getProjectInfo from '@app/pages/api/workspace/getProjectInfo'; -import uploadKeys from '@app/pages/api/workspace/uploadKeys'; +import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider"; +import { Select, SelectItem } from "@app/components/v2"; +import updateUserProjectPermission from "@app/ee/api/memberships/UpdateUserProjectPermission"; +import getOrganizationSubscriptions from "@app/pages/api/organization/GetOrgSubscription"; +import changeUserRoleInWorkspace from "@app/pages/api/workspace/changeUserRoleInWorkspace"; +import deleteUserFromWorkspace from "@app/pages/api/workspace/deleteUserFromWorkspace"; +import getLatestFileKey from "@app/pages/api/workspace/getLatestFileKey"; +import getProjectInfo from "@app/pages/api/workspace/getProjectInfo"; +import uploadKeys from "@app/pages/api/workspace/uploadKeys"; -import { decryptAssymmetric, encryptAssymmetric } from '../../utilities/cryptography/crypto'; -import guidGenerator from '../../utilities/randomId'; -import Button from '../buttons/Button'; -import UpgradePlanModal from '../dialog/UpgradePlan'; +import { decryptAssymmetric, encryptAssymmetric } from "../../utilities/cryptography/crypto"; +import guidGenerator from "../../utilities/randomId"; +import Button from "../buttons/Button"; +import UpgradePlanModal from "../dialog/UpgradePlan"; // const roles = ['admin', 'user']; // TODO: Set type for this @@ -45,8 +45,8 @@ const ProjectUsersTable = ({ userData, changeData, myUser, filter, isUserListLoa ); const host = window.location.origin; const router = useRouter(); - const [myRole, setMyRole] = useState('member'); - const [currentPlan, setCurrentPlan] = useState(''); + const [myRole, setMyRole] = useState("member"); + const [currentPlan, setCurrentPlan] = useState(""); const [workspaceEnvs, setWorkspaceEnvs] = useState([]); const [isUpgradeModalOpen, setIsUpgradeModalOpen] = useState(false); const { createNotification } = useNotificationContext(); @@ -87,8 +87,8 @@ const ProjectUsersTable = ({ userData, changeData, myUser, filter, isUserListLoa ...userData.slice(index + 1, userData?.length) ]); createNotification({ - text: `Successfully changed user role.`, - type: 'success' + text: "Successfully changed user role.", + type: "success" }); }; @@ -99,28 +99,28 @@ const ProjectUsersTable = ({ userData, changeData, myUser, filter, isUserListLoa slug: string ) => { let denials: { ability: string; environmentSlug: string }[]; - if (val === 'Read Only') { + if (val === "Read Only") { denials = [ { - ability: 'write', + ability: "write", environmentSlug: slug } ]; - } else if (val === 'No Access') { + } else if (val === "No Access") { denials = [ { - ability: 'write', + ability: "write", environmentSlug: slug }, { - ability: 'read', + ability: "read", environmentSlug: slug } ]; - } else if (val === 'Add Only') { + } else if (val === "Add Only") { denials = [ { - ability: 'read', + ability: "read", environmentSlug: slug } ]; @@ -128,7 +128,7 @@ const ProjectUsersTable = ({ userData, changeData, myUser, filter, isUserListLoa denials = []; } - if (currentPlan !== plans.professional && host === 'https://app.infisical.com' && workspaceId !== '63ea8121b6e2b0543ba79616') { + if (currentPlan !== plans.professional && host === "https://app.infisical.com" && workspaceId !== "63ea8121b6e2b0543ba79616") { setIsUpgradeModalOpen(true); } else { const allDenials = userData[index].deniedPermissions @@ -156,8 +156,8 @@ const ProjectUsersTable = ({ userData, changeData, myUser, filter, isUserListLoa ...userData.slice(index + 1, userData?.length) ]); createNotification({ - text: `Successfully changed user permissions.`, - type: 'success' + text: "Successfully changed user permissions.", + type: "success" }); } }; @@ -168,7 +168,7 @@ const ProjectUsersTable = ({ userData, changeData, myUser, filter, isUserListLoa const result = await getProjectInfo({ projectId: workspaceId }); setWorkspaceEnvs(result.environments); - const orgId = localStorage.getItem('orgData.id') as string; + const orgId = localStorage.getItem("orgData.id") as string; const subscriptions = await getOrganizationSubscriptions({ orgId }); @@ -181,7 +181,7 @@ const ProjectUsersTable = ({ userData, changeData, myUser, filter, isUserListLoa const grantAccess = async (id: string, publicKey: string) => { const result = await getLatestFileKey({ workspaceId }); - const PRIVATE_KEY = localStorage.getItem('PRIVATE_KEY') as string; + const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY") as string; // assymmetrically decrypt symmetric key with local private key const key = decryptAssymmetric({ @@ -261,13 +261,13 @@ const ProjectUsersTable = ({ userData, changeData, myUser, filter, isUserListLoa // open={isOpen} onValueChange={(e) => handleRoleUpdate(index, e)} value={row.role} - isDisabled={myRole !== 'admin' || myUser === row.email} + isDisabled={myRole !== "admin" || myUser === row.email} // onOpenChange={(open) => setIsOpen(open)} > Admin Member - {row.status === 'completed' && myUser !== row.email && ( + {row.status === "completed" && myUser !== row.email && (
)} - {row.status === 'completed' && myUser !== row.email && ( + {row.status === "completed" && myUser !== row.email && (