From f9e9c250ad7ca311fa09d6918db0d0fcb371f1e8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 7 Jul 2024 17:22:27 +0000 Subject: [PATCH 01/13] chore(deps-dev): bump eslint-plugin-jest from 28.5.0 to 28.6.0 (#7484) Bumps [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest) from 28.5.0 to 28.6.0. - [Release notes](https://github.com/jest-community/eslint-plugin-jest/releases) - [Changelog](https://github.com/jest-community/eslint-plugin-jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/jest-community/eslint-plugin-jest/compare/v28.5.0...v28.6.0) --- updated-dependencies: - dependency-name: eslint-plugin-jest dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2b303e2d09..36aaf3b020 100644 --- a/package-lock.json +++ b/package-lock.json @@ -168,7 +168,7 @@ "eslint": "^8.57.0", "eslint-config-prettier": "^8.10.0", "eslint-plugin-import": "^2.29.1", - "eslint-plugin-jest": "^28.2.0", + "eslint-plugin-jest": "^28.6.0", "eslint-plugin-playwright": "^1.6.0", "eslint-plugin-prettier": "^5.1.3", "eslint-plugin-simple-import-sort": "^12.1.0", @@ -14724,9 +14724,9 @@ } }, "node_modules/eslint-plugin-jest": { - "version": "28.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.5.0.tgz", - "integrity": "sha512-6np6DGdmNq/eBbA7HOUNV8fkfL86PYwBfwyb8n23FXgJNTR8+ot3smRHjza9LGsBBZRypK3qyF79vMjohIL8eQ==", + "version": "28.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.6.0.tgz", + "integrity": "sha512-YG28E1/MIKwnz+e2H7VwYPzHUYU4aMa19w0yGcwXnnmJH6EfgHahTJ2un3IyraUxNfnz/KUhJAFXNNwWPo12tg==", "dev": true, "dependencies": { "@typescript-eslint/utils": "^6.0.0 || ^7.0.0" diff --git a/package.json b/package.json index c9ebe57dc9..57a7268c34 100644 --- a/package.json +++ b/package.json @@ -214,7 +214,7 @@ "eslint": "^8.57.0", "eslint-config-prettier": "^8.10.0", "eslint-plugin-import": "^2.29.1", - "eslint-plugin-jest": "^28.2.0", + "eslint-plugin-jest": "^28.6.0", "eslint-plugin-playwright": "^1.6.0", "eslint-plugin-prettier": "^5.1.3", "eslint-plugin-simple-import-sort": "^12.1.0", From 34c550eb8633f3abd97451e78619f9363952f01b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 7 Jul 2024 17:23:08 +0000 Subject: [PATCH 02/13] fix(deps): bump fp-ts from 2.13.1 to 2.16.8 (#7485) Bumps [fp-ts](https://github.com/gcanti/fp-ts) from 2.13.1 to 2.16.8. - [Release notes](https://github.com/gcanti/fp-ts/releases) - [Changelog](https://github.com/gcanti/fp-ts/blob/master/CHANGELOG.md) - [Commits](https://github.com/gcanti/fp-ts/commits) --- updated-dependencies: - dependency-name: fp-ts dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 7 ++++--- package.json | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 36aaf3b020..fdefa56cd2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,7 +52,7 @@ "fetch-readablestream": "^0.2.0", "file-saver": "^2.0.5", "font-awesome": "4.7.0", - "fp-ts": "^2.13.1", + "fp-ts": "^2.16.8", "helmet": "^6.0.1", "hot-shots": "^9.3.0", "html-entities": "^2.3.3", @@ -16517,8 +16517,9 @@ } }, "node_modules/fp-ts": { - "version": "2.13.1", - "license": "MIT" + "version": "2.16.8", + "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-2.16.8.tgz", + "integrity": "sha512-nmDtNqmMZkOxu0M5hkrS9YA15/KPkYkILb6Axg9XBAoUoYEtzg+LFmVWqZrl9FNttsW0qIUpx9RCA9INbv+Bxw==" }, "node_modules/fraction.js": { "version": "4.3.7", diff --git a/package.json b/package.json index 57a7268c34..a03f65631c 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,7 @@ "fetch-readablestream": "^0.2.0", "file-saver": "^2.0.5", "font-awesome": "4.7.0", - "fp-ts": "^2.13.1", + "fp-ts": "^2.16.8", "helmet": "^6.0.1", "hot-shots": "^9.3.0", "html-entities": "^2.3.3", From aa947172b6d883a0341b37013242c8aa6bc2a226 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 7 Jul 2024 17:49:07 +0000 Subject: [PATCH 03/13] fix(deps): bump html-entities from 2.3.3 to 2.5.2 (#7489) Bumps [html-entities](https://github.com/mdevils/html-entities) from 2.3.3 to 2.5.2. - [Release notes](https://github.com/mdevils/html-entities/releases) - [Changelog](https://github.com/mdevils/html-entities/blob/master/CHANGELOG.md) - [Commits](https://github.com/mdevils/html-entities/compare/v2.3.3...v2.5.2) --- updated-dependencies: - dependency-name: html-entities dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 18 ++++++++++++++---- package.json | 2 +- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index fdefa56cd2..5781eb473f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55,7 +55,7 @@ "fp-ts": "^2.16.8", "helmet": "^6.0.1", "hot-shots": "^9.3.0", - "html-entities": "^2.3.3", + "html-entities": "^2.5.2", "html-escaper": "^3.0.3", "http-errors": "^2.0.0", "http-status-codes": "^2.3.0", @@ -17211,9 +17211,19 @@ } }, "node_modules/html-entities": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", - "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==" + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] }, "node_modules/html-escaper": { "version": "3.0.3", diff --git a/package.json b/package.json index a03f65631c..c20e2d84b1 100644 --- a/package.json +++ b/package.json @@ -101,7 +101,7 @@ "fp-ts": "^2.16.8", "helmet": "^6.0.1", "hot-shots": "^9.3.0", - "html-entities": "^2.3.3", + "html-entities": "^2.5.2", "html-escaper": "^3.0.3", "http-errors": "^2.0.0", "http-status-codes": "^2.3.0", From a8f83231cbebb6cc8247c560735fa3f344b30808 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 7 Jul 2024 17:50:34 +0000 Subject: [PATCH 04/13] chore(deps-dev): bump @types/sns-validator from 0.3.1 to 0.3.3 (#7491) Bumps [@types/sns-validator](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/sns-validator) from 0.3.1 to 0.3.3. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/sns-validator) --- updated-dependencies: - dependency-name: "@types/sns-validator" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 9 +++++---- package.json | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5781eb473f..aa91042d67 100644 --- a/package-lock.json +++ b/package-lock.json @@ -148,7 +148,7 @@ "@types/promise-retry": "^1.1.3", "@types/promise-timeout": "^1.3.0", "@types/puppeteer-core": "^5.4.0", - "@types/sns-validator": "^0.3.1", + "@types/sns-validator": "^0.3.3", "@types/spark-md5": "^3.0.2", "@types/supertest": "^2.0.12", "@types/triple-beam": "^1.3.2", @@ -9577,9 +9577,10 @@ } }, "node_modules/@types/sns-validator": { - "version": "0.3.1", - "dev": true, - "license": "MIT" + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@types/sns-validator/-/sns-validator-0.3.3.tgz", + "integrity": "sha512-v/3bN5dak8aDXn7bgTGu+1oGc+PQCP0qnfzUM6gzo7FnxiW4wpppkaIptPhRhJaiDItbUDK+YA4yDQuVs5Cq1Q==", + "dev": true }, "node_modules/@types/spark-md5": { "version": "3.0.2", diff --git a/package.json b/package.json index c20e2d84b1..395bab0dac 100644 --- a/package.json +++ b/package.json @@ -194,7 +194,7 @@ "@types/promise-retry": "^1.1.3", "@types/promise-timeout": "^1.3.0", "@types/puppeteer-core": "^5.4.0", - "@types/sns-validator": "^0.3.1", + "@types/sns-validator": "^0.3.3", "@types/spark-md5": "^3.0.2", "@types/supertest": "^2.0.12", "@types/triple-beam": "^1.3.2", From 174fb82aeac23bd39f290f7ceb895fee8100bb3a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 7 Jul 2024 17:51:56 +0000 Subject: [PATCH 05/13] chore(deps-dev): bump @types/ejs from 3.1.1 to 3.1.5 (#7492) Bumps [@types/ejs](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/ejs) from 3.1.1 to 3.1.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/ejs) --- updated-dependencies: - dependency-name: "@types/ejs" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 9 +++++---- package.json | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index aa91042d67..9d546edd8f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -127,7 +127,7 @@ "@types/convict": "^6.1.6", "@types/cookie-parser": "^1.4.7", "@types/dedent": "^0.7.0", - "@types/ejs": "^3.1.1", + "@types/ejs": "^3.1.5", "@types/express": "^4.17.21", "@types/express-request-id": "^1.4.3", "@types/express-session": "^1.18.0", @@ -9249,9 +9249,10 @@ "license": "MIT" }, "node_modules/@types/ejs": { - "version": "3.1.1", - "dev": true, - "license": "MIT" + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@types/ejs/-/ejs-3.1.5.tgz", + "integrity": "sha512-nv+GSx77ZtXiJzwKdsASqi+YQ5Z7vwHsTP0JY2SiQgjGckkBRKZnk8nIM+7oUZ1VCtuTz0+By4qVR7fqzp/Dfg==", + "dev": true }, "node_modules/@types/eslint": { "version": "8.56.10", diff --git a/package.json b/package.json index 395bab0dac..af7a9b5e67 100644 --- a/package.json +++ b/package.json @@ -173,7 +173,7 @@ "@types/convict": "^6.1.6", "@types/cookie-parser": "^1.4.7", "@types/dedent": "^0.7.0", - "@types/ejs": "^3.1.1", + "@types/ejs": "^3.1.5", "@types/express": "^4.17.21", "@types/express-request-id": "^1.4.3", "@types/express-session": "^1.18.0", From a79f783bf002bd777769949552f21e9bc3f25146 Mon Sep 17 00:00:00 2001 From: Xinyi <65388923+helloitsxinyi@users.noreply.github.com> Date: Mon, 8 Jul 2024 22:19:46 +0800 Subject: [PATCH 06/13] feat(i18n): replace hardcoded string values for AdminFormNavbar (#7456) feat(i18n): add en-sg translations and types for admin-form-navbar, use translations in AdminFormNavbar Co-authored-by: Ken Lee Shu Ming --- .../AdminFormNavbar/AdminFormNavbar.tsx | 30 +++++++++++-------- frontend/src/i18n/locales/en-sg.ts | 2 ++ .../features/admin-form-navbar/en-sg.ts | 18 +++++++++++ .../features/admin-form-navbar/index.ts | 18 +++++++++++ frontend/src/i18n/locales/features/index.ts | 1 + frontend/src/i18n/locales/types.ts | 3 +- 6 files changed, 58 insertions(+), 14 deletions(-) create mode 100644 frontend/src/i18n/locales/features/admin-form-navbar/en-sg.ts create mode 100644 frontend/src/i18n/locales/features/admin-form-navbar/index.ts diff --git a/frontend/src/features/admin-form/common/components/AdminFormNavbar/AdminFormNavbar.tsx b/frontend/src/features/admin-form/common/components/AdminFormNavbar/AdminFormNavbar.tsx index 0928649b39..4a9f01ff10 100644 --- a/frontend/src/features/admin-form/common/components/AdminFormNavbar/AdminFormNavbar.tsx +++ b/frontend/src/features/admin-form/common/components/AdminFormNavbar/AdminFormNavbar.tsx @@ -1,4 +1,5 @@ import { useCallback, useMemo } from 'react' +import { useTranslation } from 'react-i18next' import { BiDotsHorizontalRounded, BiShareAlt, @@ -72,6 +73,7 @@ export const AdminFormNavbar = ({ handleShareButtonClick, previewFormLink, }: AdminFormNavbarProps): JSX.Element => { + const { t } = useTranslation() const { ref, onMouseDown } = useDraggable() const { isOpen, onClose, onOpen } = useDisclosure() const { pathname } = useLocation() @@ -182,7 +184,7 @@ export const AdminFormNavbar = ({ to={ADMINFORM_BUILD_SUBROUTE} isActive={checkTabActive(ADMINFORM_BUILD_SUBROUTE)} > - Create + {t('features.adminFormNavbar.tabs.create')} } /> @@ -235,26 +237,28 @@ export const AdminFormNavbar = ({ {renderLastModified} - + } /> - + } /> - - + + @@ -278,21 +282,21 @@ export const AdminFormNavbar = ({ {...mobileDrawerExtraButtonProps} leftIcon={} > - Preview form + {t('features.adminFormNavbar.previewForm')} diff --git a/frontend/src/i18n/locales/en-sg.ts b/frontend/src/i18n/locales/en-sg.ts index 7de737cdaa..0ea5173347 100644 --- a/frontend/src/i18n/locales/en-sg.ts +++ b/frontend/src/i18n/locales/en-sg.ts @@ -1,3 +1,4 @@ +import { enSG as adminFormNavbar } from './features/admin-form-navbar' import { enSG as common } from './features/common' import { enSG as login } from './features/login' import { enSG as publicForm } from './features/public-form' @@ -6,6 +7,7 @@ import { FallbackTranslation } from './types' export const enSG: FallbackTranslation = { translation: { features: { + adminFormNavbar, common, login, publicForm, diff --git a/frontend/src/i18n/locales/features/admin-form-navbar/en-sg.ts b/frontend/src/i18n/locales/features/admin-form-navbar/en-sg.ts new file mode 100644 index 0000000000..6a0e22567e --- /dev/null +++ b/frontend/src/i18n/locales/features/admin-form-navbar/en-sg.ts @@ -0,0 +1,18 @@ +import { AdminFormNavbar } from '.' + +export const enSG: AdminFormNavbar = { + tabs: { + create: 'Create', + settings: 'Settings', + results: 'Results', + routing: 'Routing', + }, + manageCollaborators: 'Manage collaborators', + previewForm: 'Preview form', + formActions: 'Form actions', + shareBtn: { + text: 'Share', + textMobile: 'Share form link', + tooltip: 'Share your form link', + }, +} diff --git a/frontend/src/i18n/locales/features/admin-form-navbar/index.ts b/frontend/src/i18n/locales/features/admin-form-navbar/index.ts new file mode 100644 index 0000000000..d3450f4668 --- /dev/null +++ b/frontend/src/i18n/locales/features/admin-form-navbar/index.ts @@ -0,0 +1,18 @@ +export * from './en-sg' + +export interface AdminFormNavbar { + tabs: { + create: string + settings: string + results: string + routing: string + } + manageCollaborators: string + previewForm: string + formActions: string + shareBtn: { + text: string + textMobile: string + tooltip: string + } +} diff --git a/frontend/src/i18n/locales/features/index.ts b/frontend/src/i18n/locales/features/index.ts index 2655fa02a0..37a22a867d 100644 --- a/frontend/src/i18n/locales/features/index.ts +++ b/frontend/src/i18n/locales/features/index.ts @@ -1,3 +1,4 @@ +export { type AdminFormNavbar } from './admin-form-navbar' export { type Common } from './common' export { type Login } from './login' export { type PublicForm } from './public-form' diff --git a/frontend/src/i18n/locales/types.ts b/frontend/src/i18n/locales/types.ts index c18f85894b..c075cf4841 100644 --- a/frontend/src/i18n/locales/types.ts +++ b/frontend/src/i18n/locales/types.ts @@ -1,8 +1,9 @@ -import { Common, Login, PublicForm } from './features' +import { AdminFormNavbar, Common, Login, PublicForm } from './features' interface Translation { translation: { features: { + adminFormNavbar?: AdminFormNavbar common?: Common publicForm?: PublicForm login?: Login From 43e659b7dd651876ff56a72e52224a07627db629 Mon Sep 17 00:00:00 2001 From: g-tejas Date: Wed, 10 Jul 2024 15:46:06 +0800 Subject: [PATCH 07/13] fix: fix issue where attachments would fail locally --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 9cee64c88b..26dcce4e89 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -33,7 +33,7 @@ services: - AWS_ACCESS_KEY_ID=fakeKey - AWS_SECRET_ACCESS_KEY=fakeSecret - SESSION_SECRET=thisisasecret - - AWS_ENDPOINT=http://localhost:4566 + - AWS_ENDPOINT=http://127.0.0.1:4566 - SECRET_ENV=development - SUBMISSIONS_RATE_LIMIT=200 - SEND_AUTH_OTP_RATE_LIMIT=60 From d3a1344023f21f5fbe413044bdb53657eb7769d6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jul 2024 11:25:01 +0800 Subject: [PATCH 08/13] fix(deps): bump hot-shots from 9.3.0 to 10.0.0 (#7490) Bumps [hot-shots](https://github.com/brightcove/hot-shots) from 9.3.0 to 10.0.0. - [Changelog](https://github.com/brightcove/hot-shots/blob/master/CHANGES.md) - [Commits](https://github.com/brightcove/hot-shots/compare/v9.3.0...v10.0.0) --- updated-dependencies: - dependency-name: hot-shots dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 9 +++++---- package.json | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 469748b372..ba2e63b8f5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -54,7 +54,7 @@ "font-awesome": "4.7.0", "fp-ts": "^2.16.8", "helmet": "^6.0.1", - "hot-shots": "^9.3.0", + "hot-shots": "^10.0.0", "html-entities": "^2.5.2", "html-escaper": "^3.0.3", "http-errors": "^2.0.0", @@ -17192,10 +17192,11 @@ } }, "node_modules/hot-shots": { - "version": "9.3.0", - "license": "MIT", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/hot-shots/-/hot-shots-10.0.0.tgz", + "integrity": "sha512-uy/uGpuJk7yuyiKRfZMBNkF1GAOX5O2ifO9rDCaX9jw8fu6eW9QeWC7WRPDI+O98frW1HQgV3+xwjWsZPECIzQ==", "engines": { - "node": ">=6.0.0" + "node": ">=10.0.0" }, "optionalDependencies": { "unix-dgram": "2.x" diff --git a/package.json b/package.json index 5c9ab57769..c5b59f57ad 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "font-awesome": "4.7.0", "fp-ts": "^2.16.8", "helmet": "^6.0.1", - "hot-shots": "^9.3.0", + "hot-shots": "^10.0.0", "html-entities": "^2.5.2", "html-escaper": "^3.0.3", "http-errors": "^2.0.0", From 929a166b93b38f09c104beddf967992603a6f5fd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jul 2024 11:32:01 +0800 Subject: [PATCH 09/13] chore(deps-dev): bump supertest-session from 4.1.0 to 5.0.1 (#7493) Bumps [supertest-session](https://github.com/rjz/supertest-session) from 4.1.0 to 5.0.1. - [Commits](https://github.com/rjz/supertest-session/compare/v4.1.0...v5.0.1) --- updated-dependencies: - dependency-name: supertest-session dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 7 ++++--- package.json | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index ba2e63b8f5..249184464e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -189,7 +189,7 @@ "rimraf": "^5.0.5", "stripe-event-types": "^3.1.0", "supertest": "^6.3.3", - "supertest-session": "^4.1.0", + "supertest-session": "^5.0.1", "ts-jest": "^29.1.2", "ts-loader": "^8.2.0", "ts-node": "^10.9.2", @@ -27456,9 +27456,10 @@ } }, "node_modules/supertest-session": { - "version": "4.1.0", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/supertest-session/-/supertest-session-5.0.1.tgz", + "integrity": "sha512-RpR8tGQZGreQsOCiW3YMSPKMwPlAB8lA0Jyat+8VUSJaYvLHTMqhMW6gooJ2htzjr3w/kgqJTQDnmuFenzA9JA==", "dev": true, - "license": "MIT", "dependencies": { "cookiejar": "^2.1.2", "methods": "^1.1.2", diff --git a/package.json b/package.json index c5b59f57ad..4d2f2de2d3 100644 --- a/package.json +++ b/package.json @@ -235,7 +235,7 @@ "rimraf": "^5.0.5", "stripe-event-types": "^3.1.0", "supertest": "^6.3.3", - "supertest-session": "^4.1.0", + "supertest-session": "^5.0.1", "ts-jest": "^29.1.2", "ts-loader": "^8.2.0", "ts-node": "^10.9.2", From 4896690d1996d2baa3a44b515aca79722435291d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jul 2024 11:33:56 +0800 Subject: [PATCH 10/13] chore(deps-dev): bump lint-staged from 13.1.0 to 15.2.7 (#7487) Bumps [lint-staged](https://github.com/okonet/lint-staged) from 13.1.0 to 15.2.7. - [Release notes](https://github.com/okonet/lint-staged/releases) - [Changelog](https://github.com/lint-staged/lint-staged/blob/master/CHANGELOG.md) - [Commits](https://github.com/okonet/lint-staged/compare/v13.1.0...v15.2.7) --- updated-dependencies: - dependency-name: lint-staged dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 604 ++++++++++++++++++++++++++++------------------ package.json | 2 +- 2 files changed, 366 insertions(+), 240 deletions(-) diff --git a/package-lock.json b/package-lock.json index 249184464e..652ff4c506 100644 --- a/package-lock.json +++ b/package-lock.json @@ -181,7 +181,7 @@ "jest-extended": "^3.2.4", "jest-localstorage-mock": "^2.4.26", "jest-mock-axios": "^4.7.2", - "lint-staged": "^13.1.0", + "lint-staged": "^15.2.7", "maildev": "^2.1.0", "mockdate": "^3.0.5", "prettier": "^3.3.2", @@ -10574,18 +10574,6 @@ "node": ">= 6.0.0" } }, - "node_modules/aggregate-error": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/ajv": { "version": "6.12.6", "license": "MIT", @@ -11812,10 +11800,11 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "license": "MIT", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -12308,14 +12297,6 @@ "node": ">=0.10.0" } }, - "node_modules/clean-stack": { - "version": "2.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -12339,15 +12320,16 @@ } }, "node_modules/cli-truncate": { - "version": "3.1.0", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", "dev": true, - "license": "MIT", "dependencies": { "slice-ansi": "^5.0.0", - "string-width": "^5.0.0" + "string-width": "^7.0.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -12355,8 +12337,9 @@ }, "node_modules/cli-truncate/node_modules/ansi-regex": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -12365,9 +12348,10 @@ } }, "node_modules/cli-truncate/node_modules/ansi-styles": { - "version": "6.1.0", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -12376,14 +12360,16 @@ } }, "node_modules/cli-truncate/node_modules/emoji-regex": { - "version": "9.2.2", - "dev": true, - "license": "MIT" + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true }, "node_modules/cli-truncate/node_modules/is-fullwidth-code-point": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -12393,8 +12379,9 @@ }, "node_modules/cli-truncate/node_modules/slice-ansi": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^6.0.0", "is-fullwidth-code-point": "^4.0.0" @@ -12407,25 +12394,27 @@ } }, "node_modules/cli-truncate/node_modules/string-width": { - "version": "5.1.2", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "dev": true, - "license": "MIT", "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cli-truncate/node_modules/strip-ansi": { - "version": "7.0.1", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, - "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -16185,8 +16174,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "license": "MIT", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -16737,6 +16727,18 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-east-asian-width": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", + "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-intrinsic": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", @@ -17550,6 +17552,15 @@ "node": ">= 6" } }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, "node_modules/humanize": { "version": "0.0.9", "engines": { @@ -17678,14 +17689,6 @@ "node": ">=0.8.19" } }, - "node_modules/indent-string": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/infer-owner": { "version": "1.0.4", "dev": true, @@ -18053,7 +18056,8 @@ }, "node_modules/is-number": { "version": "7.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "engines": { "node": ">=0.12.0" } @@ -21142,12 +21146,14 @@ "integrity": "sha512-HeTsOrDF/hWhEiKqZVwg9Cqlep5x2T+IYDENvT2VRj3iX8JQ7Y+omENv+AIn0vC8m6GYhivfCed5Cgfw27r5SA==" }, "node_modules/lilconfig": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", - "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==", - "dev": true, + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", "engines": { - "node": ">=10" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" } }, "node_modules/limiter": { @@ -21159,89 +21165,93 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "node_modules/lint-staged": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.1.0.tgz", - "integrity": "sha512-pn/sR8IrcF/T0vpWLilih8jmVouMlxqXxKuAojmbiGX5n/gDnz+abdPptlj0vYnbfE0SQNl3CY/HwtM0+yfOVQ==", - "dev": true, - "dependencies": { - "cli-truncate": "^3.1.0", - "colorette": "^2.0.19", - "commander": "^9.4.1", - "debug": "^4.3.4", - "execa": "^6.1.0", - "lilconfig": "2.0.6", - "listr2": "^5.0.5", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "object-inspect": "^1.12.2", - "pidtree": "^0.6.0", - "string-argv": "^0.3.1", - "yaml": "^2.1.3" + "version": "15.2.7", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.7.tgz", + "integrity": "sha512-+FdVbbCZ+yoh7E/RosSdqKJyUM2OEjTciH0TFNkawKgvFp1zbGlEC39RADg+xKBG1R4mhoH2j85myBQZ5wR+lw==", + "dev": true, + "dependencies": { + "chalk": "~5.3.0", + "commander": "~12.1.0", + "debug": "~4.3.4", + "execa": "~8.0.1", + "lilconfig": "~3.1.1", + "listr2": "~8.2.1", + "micromatch": "~4.0.7", + "pidtree": "~0.6.0", + "string-argv": "~0.3.2", + "yaml": "~2.4.2" }, "bin": { "lint-staged": "bin/lint-staged.js" }, "engines": { - "node": "^14.13.1 || >=16.0.0" + "node": ">=18.12.0" }, "funding": { "url": "https://opencollective.com/lint-staged" } }, + "node_modules/lint-staged/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/lint-staged/node_modules/commander": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz", - "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==", + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", "dev": true, "engines": { - "node": "^12.20.0 || >=14" + "node": ">=18" } }, "node_modules/lint-staged/node_modules/execa": { - "version": "6.1.0", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, - "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^3.0.1", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", "is-stream": "^3.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^5.1.0", "onetime": "^6.0.0", - "signal-exit": "^3.0.7", + "signal-exit": "^4.1.0", "strip-final-newline": "^3.0.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=16.17" }, "funding": { "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, "node_modules/lint-staged/node_modules/get-stream": { - "version": "6.0.1", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, - "license": "MIT", "engines": { - "node": ">=10" + "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lint-staged/node_modules/human-signals": { - "version": "3.0.1", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.20.0" - } - }, "node_modules/lint-staged/node_modules/is-stream": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, - "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -21251,8 +21261,9 @@ }, "node_modules/lint-staged/node_modules/mimic-fn": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -21261,9 +21272,10 @@ } }, "node_modules/lint-staged/node_modules/npm-run-path": { - "version": "5.1.0", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, - "license": "MIT", "dependencies": { "path-key": "^4.0.0" }, @@ -21274,10 +21286,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lint-staged/node_modules/npm-run-path/node_modules/path-key": { - "version": "4.0.0", + "node_modules/lint-staged/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, - "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, "engines": { "node": ">=12" }, @@ -21285,13 +21301,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lint-staged/node_modules/onetime": { - "version": "6.0.0", + "node_modules/lint-staged/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^4.0.0" - }, "engines": { "node": ">=12" }, @@ -21299,10 +21313,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lint-staged/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/lint-staged/node_modules/strip-final-newline": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -21311,10 +21338,13 @@ } }, "node_modules/lint-staged/node_modules/yaml": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.1.3.tgz", - "integrity": "sha512-AacA8nRULjKMX2DvWvOAdBZMOfQlypSFkjcOcu9FalllIDJ1kvlREzcdIZmidQUqqeMv7jorHjq2HlLv/+c2lg==", + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", + "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", "dev": true, + "bin": { + "yaml": "bin.mjs" + }, "engines": { "node": ">= 14" } @@ -21329,93 +21359,105 @@ } }, "node_modules/listr2": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-5.0.6.tgz", - "integrity": "sha512-u60KxKBy1BR2uLJNTWNptzWQ1ob/gjMzIJPZffAENzpZqbMZ/5PrXXOomDcevIS/+IB7s1mmCEtSlT2qHWMqag==", - "dev": true, - "dependencies": { - "cli-truncate": "^2.1.0", - "colorette": "^2.0.19", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rfdc": "^1.3.0", - "rxjs": "^7.5.7", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.3.tgz", + "integrity": "sha512-Lllokma2mtoniUOS94CcOErHWAug5iu7HOmDrvWgpw8jyQH2fomgB+7lZS4HWZxytUuQwkGOwe49FvwVaA85Xw==", + "dev": true, + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.0.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" }, "engines": { - "node": "^14.13.1 || >=16.0.0" - }, - "peerDependencies": { - "enquirer": ">= 2.3.0 < 3" + "node": ">=18.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" }, - "peerDependenciesMeta": { - "enquirer": { - "optional": true - } + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/listr2/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==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, "engines": { - "node": ">=8" + "node": ">=12" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/listr2/node_modules/cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "node_modules/listr2/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "node_modules/listr2/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, + "node_modules/listr2/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "dev": true, "dependencies": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/listr2/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==", + "node_modules/listr2/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "dependencies": { - "color-name": "~1.1.4" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">=7.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/listr2/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/listr2/node_modules/slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", "dev": true, "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/load-json-file": { @@ -21723,68 +21765,175 @@ } }, "node_modules/log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz", + "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==", "dev": true, "dependencies": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" + "ansi-escapes": "^6.2.0", + "cli-cursor": "^4.0.0", + "slice-ansi": "^7.0.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-update/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==", + "node_modules/log-update/node_modules/ansi-escapes": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz", + "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==", "dev": true, - "dependencies": { - "color-convert": "^2.0.1" + "engines": { + "node": ">=14.16" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/log-update/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==", + "node_modules/log-update/node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", "dev": true, "dependencies": { - "color-name": "~1.1.4" + "restore-cursor": "^4.0.0" }, "engines": { - "node": ">=7.0.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-update/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/log-update/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", "dev": true }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, + "dependencies": { + "get-east-asian-width": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/log-update/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", "dev": true, "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/logform": { @@ -22247,11 +22396,11 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -23788,20 +23937,6 @@ "node": ">=8" } }, - "node_modules/p-map": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/p-queue": { "version": "6.6.2", "license": "MIT", @@ -24424,17 +24559,6 @@ } } }, - "node_modules/postcss-load-config/node_modules/lilconfig": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", - "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, "node_modules/postcss-load-config/node_modules/yaml": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.2.tgz", @@ -25862,9 +25986,9 @@ } }, "node_modules/rfdc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", "dev": true }, "node_modules/rimraf": { @@ -27081,9 +27205,10 @@ "license": "MIT" }, "node_modules/string-argv": { - "version": "0.3.1", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.6.19" } @@ -27965,7 +28090,8 @@ }, "node_modules/to-regex-range": { "version": "5.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dependencies": { "is-number": "^7.0.0" }, diff --git a/package.json b/package.json index 4d2f2de2d3..00525b527a 100644 --- a/package.json +++ b/package.json @@ -227,7 +227,7 @@ "jest-extended": "^3.2.4", "jest-localstorage-mock": "^2.4.26", "jest-mock-axios": "^4.7.2", - "lint-staged": "^13.1.0", + "lint-staged": "^15.2.7", "maildev": "^2.1.0", "mockdate": "^3.0.5", "prettier": "^3.3.2", From c222ba0f0379fade86b9367199cc492c7a804245 Mon Sep 17 00:00:00 2001 From: Tejas G Date: Thu, 11 Jul 2024 14:41:46 +0800 Subject: [PATCH 11/13] feat(errors): revamp business logic error codes (#7443) * feat(errors): revamp business logic error codes * feat: refactor existing error objects to use new error codes * fix: change gogov error object constructor * fix: fix webhook error obj * fix: fix failing backend lint * feat: add error code span tagging to some controllers * feat: add unauthorized error * docs: remove unncessary comment * fix: remove error codes from sms.* * refactor: organise into block groups based on origin * fix: make error code names SCREAMING_SNAKE_CASE * fix: make auth middleware create error object * fix: rename all error codes to screaming snake case * fix: fix test:backend failing with prefixed message * fix: rename remaining error code to screaming snake case * fix: fix failing tests due to wrong err msg * fix: remove dd tag setting from controllers * tests: add tests for error codes * fix: fix spacing --- .../admin-feedback/admin-feedback.errors.ts | 4 +- src/app/modules/auth/auth.errors.ts | 16 +- src/app/modules/auth/auth.middlewares.ts | 6 +- src/app/modules/auth/auth.utils.ts | 1 + src/app/modules/billing/billing.errors.ts | 4 +- src/app/modules/bounce/bounce.errors.ts | 10 +- .../core/__tests__/core.errors.spec.ts | 28 ++ src/app/modules/core/core.errors.ts | 278 ++++++++++++++++-- src/app/modules/datadog/datadog.utils.ts | 15 + src/app/modules/feedback/feedback.errors.ts | 6 +- .../form/admin-form/admin-form.errors.ts | 29 +- src/app/modules/form/form.errors.ts | 18 +- src/app/modules/myinfo/myinfo.errors.ts | 26 +- .../modules/payments/payment-proof.errors.ts | 8 +- src/app/modules/payments/payments.errors.ts | 16 +- src/app/modules/payments/stripe.errors.ts | 34 ++- src/app/modules/sgid/sgid.errors.ts | 18 +- src/app/modules/spcp/spcp.errors.ts | 20 +- .../modules/spcp/spcp.oidc.client.errors.ts | 22 +- .../email-submission.errors.ts | 4 +- .../encrypt-submission.errors.ts | 6 +- .../submission/receiver/receiver.errors.ts | 10 +- .../modules/submission/submission.errors.ts | 63 ++-- .../modules/submission/submission.service.ts | 2 +- .../modules/submission/submission.utils.ts | 2 +- src/app/modules/user/user.errors.ts | 6 +- .../verification/verification.errors.ts | 34 ++- .../verified-content.errors.ts | 6 +- src/app/modules/webhook/webhook.errors.ts | 23 +- src/app/modules/workspace/workspace.errors.ts | 6 +- src/app/services/captcha/captcha.errors.ts | 8 +- src/app/services/mail/mail.errors.ts | 6 +- .../postman-sms/postman-sms.errors.ts | 6 +- .../services/turnstile/turnstile.errors.ts | 8 +- 34 files changed, 542 insertions(+), 207 deletions(-) create mode 100644 src/app/modules/core/__tests__/core.errors.spec.ts diff --git a/src/app/modules/admin-feedback/admin-feedback.errors.ts b/src/app/modules/admin-feedback/admin-feedback.errors.ts index 27356e67a1..303b3b0d2a 100644 --- a/src/app/modules/admin-feedback/admin-feedback.errors.ts +++ b/src/app/modules/admin-feedback/admin-feedback.errors.ts @@ -1,7 +1,7 @@ -import { ApplicationError } from '../core/core.errors' +import { ApplicationError, ErrorCodes } from '../core/core.errors' export class MissingAdminFeedbackError extends ApplicationError { constructor(message = 'Admin feedback not found') { - super(message) + super(message, undefined, ErrorCodes.ADMIN_FEEDBACK_MISSING) } } diff --git a/src/app/modules/auth/auth.errors.ts b/src/app/modules/auth/auth.errors.ts index 30945a54a0..1c8a9b0c1d 100644 --- a/src/app/modules/auth/auth.errors.ts +++ b/src/app/modules/auth/auth.errors.ts @@ -1,27 +1,33 @@ -import { ApplicationError } from '../core/core.errors' +import { ApplicationError, ErrorCodes } from '../core/core.errors' export class InvalidDomainError extends ApplicationError { constructor( message = 'This is not a whitelisted public service email domain. Please log in with your official government or government-linked email address.', ) { - super(message) + super(message, undefined, ErrorCodes.AUTH_INVALID_DOMAIN) } } export class InvalidOtpError extends ApplicationError { constructor(message = 'OTP has expired. Please request for a new OTP.') { - super(message) + super(message, undefined, ErrorCodes.AUTH_INVALID_OTP) } } export class InvalidTokenError extends ApplicationError { constructor(message = 'Invalid API Key') { - super(message) + super(message, undefined, ErrorCodes.AUTH_INVALID_TOKEN) } } export class MissingTokenError extends ApplicationError { constructor(message = "User's API Key not found") { - super(message) + super(message, undefined, ErrorCodes.AUTH_MISSING_TOKEN) + } +} + +export class UnauthorizedError extends ApplicationError { + constructor(message = 'User is unauthorized.') { + super(message, undefined, ErrorCodes.AUTH_UNAUTHORIZED) } } diff --git a/src/app/modules/auth/auth.middlewares.ts b/src/app/modules/auth/auth.middlewares.ts index e1e632dda3..b1a691be34 100644 --- a/src/app/modules/auth/auth.middlewares.ts +++ b/src/app/modules/auth/auth.middlewares.ts @@ -8,6 +8,7 @@ import { ControllerHandler } from '../core/core.types' import { UNAUTHORIZED_USER_MESSAGE } from '../user/user.constant' import * as UserService from '../user/user.service' +import { UnauthorizedError } from './auth.errors' import { getUserByApiKey } from './auth.service' import { getUserIdFromSession, @@ -29,10 +30,9 @@ export const withUserAuthentication: ControllerHandler = (req, res, next) => { if (isUserInSession(req.session)) { return next() } + const { errorMessage, statusCode } = mapRouteError(new UnauthorizedError()) - return res - .status(StatusCodes.UNAUTHORIZED) - .json({ message: 'User is unauthorized.' }) + return res.status(statusCode).json({ message: errorMessage }) } /** diff --git a/src/app/modules/auth/auth.utils.ts b/src/app/modules/auth/auth.utils.ts index 10964d532a..b8b786f724 100644 --- a/src/app/modules/auth/auth.utils.ts +++ b/src/app/modules/auth/auth.utils.ts @@ -22,6 +22,7 @@ const logger = createLoggerWithLabel(module) */ export const mapRouteError: MapRouteError = (error, coreErrorMessage) => { switch (error.constructor) { + case AuthErrors.UnauthorizedError: case AuthErrors.InvalidDomainError: return { statusCode: StatusCodes.UNAUTHORIZED, diff --git a/src/app/modules/billing/billing.errors.ts b/src/app/modules/billing/billing.errors.ts index 4883be0cbe..b4a487dd88 100644 --- a/src/app/modules/billing/billing.errors.ts +++ b/src/app/modules/billing/billing.errors.ts @@ -1,4 +1,4 @@ -import { ApplicationError } from '../core/core.errors' +import { ApplicationError, ErrorCodes } from '../core/core.errors' /** * Attempt to add Login record for form without authentication enabled. @@ -7,6 +7,6 @@ export class FormHasNoAuthError extends ApplicationError { constructor( message = 'Attempted to add Login record for form with no authentication', ) { - super(message) + super(message, undefined, ErrorCodes.BILLING_FORM_HAS_NO_AUTH) } } diff --git a/src/app/modules/bounce/bounce.errors.ts b/src/app/modules/bounce/bounce.errors.ts index 5e067ce695..eae9ffccac 100644 --- a/src/app/modules/bounce/bounce.errors.ts +++ b/src/app/modules/bounce/bounce.errors.ts @@ -2,14 +2,14 @@ import { InvalidNumberError, SmsSendError, } from '../../services/postman-sms/postman-sms.errors' -import { ApplicationError } from '../core/core.errors' +import { ApplicationError, ErrorCodes } from '../core/core.errors' /** * Unexpected shape of request body. */ export class InvalidNotificationError extends ApplicationError { constructor(message = 'Notification from AWS could not be validated') { - super(message) + super(message, undefined, ErrorCodes.BOUNCE_INVALID_NOTIFCATION) } } @@ -27,7 +27,7 @@ export class SendBounceSmsNotificationError extends ApplicationError { contact: string, message = 'Error while sending bounce notification via SMS', ) { - super(message) + super(message, undefined, ErrorCodes.BOUNCE_SEND_BOUNCE_SMS_NOTIFICATION) this.meta = { contact, originalError, @@ -42,7 +42,7 @@ export class MissingEmailHeadersError extends ApplicationError { constructor( message = 'Email is missing custom header containing form or submission ID', ) { - super(message) + super(message, undefined, ErrorCodes.BOUNCE_MISSING_EMAIL_HEADERS) } } @@ -51,6 +51,6 @@ export class MissingEmailHeadersError extends ApplicationError { */ export class ParseNotificationError extends ApplicationError { constructor(message = 'Could not parse SNS notification') { - super(message) + super(message, undefined, ErrorCodes.BOUNCE_PARSE_NOTIFICATION) } } diff --git a/src/app/modules/core/__tests__/core.errors.spec.ts b/src/app/modules/core/__tests__/core.errors.spec.ts new file mode 100644 index 0000000000..c43272b639 --- /dev/null +++ b/src/app/modules/core/__tests__/core.errors.spec.ts @@ -0,0 +1,28 @@ +import { ErrorCodes } from '../core.errors' + +describe('core', () => { + describe('error codes', () => { + it('should be 6 digits long', () => { + // iterate through the enum values and verify that they are 6 digits + // not the value but the length of the number representation + const errorCodeValues = Object.values(ErrorCodes).filter( + (value) => typeof value === 'number', + ) as number[] + + errorCodeValues.forEach((errorCode) => { + expect(String(errorCode).length).toBe(6) + }) + }) + + it('should follow SCREAMING_SNAKE_CASE', () => { + const isScreamingSnakeCase = /^[A-Z0-9]+(_[A-Z0-9]+)*$/ + + // TS enums put both the key and the value in the enum object + const keys = Object.keys(ErrorCodes).filter((v) => isNaN(Number(v))) + + keys.forEach((key) => { + expect(key).toMatch(isScreamingSnakeCase) + }) + }) + }) +}) diff --git a/src/app/modules/core/core.errors.ts b/src/app/modules/core/core.errors.ts index 995fe73015..d73eec917a 100644 --- a/src/app/modules/core/core.errors.ts +++ b/src/app/modules/core/core.errors.ts @@ -1,3 +1,235 @@ +import { setErrorCode } from '../datadog/datadog.utils' + +/** + * Global Error Code Registry + * + * - [10xxxx] FormSG Errors + * - [11xxxx] Auth Errors + * - [12xxxx] Database Errors + * - [13xxxx] Payment Errors + * - [14xxxx] Communication Channel Errors + * - [15xxxx] Verification Errors + * - [19xxxx] Other Errors + * Group in general categories for easy datadog queries + * Group in sub groups for easy allocation, identification with screaming snake case prefix of the module + */ +export enum ErrorCodes { + // [10xxxx] FormSG Errors ---------------------------------------------------- + // [100000 - 100099] General Form Errors (/modules/form) + FORM_PRIVATE_FORM = 100000, + FORM_NOT_FOUND = 100001, + FORM_DELETED = 100002, + FORM_FORBIDDEN_FORM = 100003, + FORM_TRANSFER_OWNERSHIP = 100004, + FORM_LOGIC_NOT_FOUND = 100005, + FORM_AUTH_TYPE_MISMATCH = 100006, + FORM_AUTH_NO_ESRVC_ID = 100007, + ADMIN_FORM_INVALID_FILE_TYPE = 100100, + ADMIN_FORM_EDIT_FIELD = 100101, + ADMIN_FORM_FIELD_NOT_FOUND = 100102, + ADMIN_FORM_INVALID_COLLABORATOR = 100103, + ADMIN_FORM_PAYMENT_CHANNEL_NOT_FOUND = 100104, + ADMIN_FORM_GOGOV = 100105, + ADMIN_FORM_GOGOV_VALIDATION = 100106, + ADMIN_FORM_GOGOV_ALREADY_EXIST = 100107, + ADMIN_FORM_GOGOV_REQUEST_LIMIT = 100108, + ADMIN_FORM_GOGOV_BAD_GATEWAY = 100109, + ADMIN_FORM_GOGOV_SERVER = 100110, + // [100200 - 100299] Submission Errors (/modules/submission) + SUBMISSION_CONFLICT = 100200, + SUBMISSION_NOT_FOUND = 100201, + SUBMISSION_PENDING_NOT_FOUND = 100202, + SUBMISSION_INVALID_TYPE = 100203, + SUBMISSION_INVALID_ENCODING = 100204, + SUBMISSION_PROCESSING = 100205, + SUBMISSION_VALIDATE_FIELD = 100206, + SUBMISSION_SEND_EMAIL_CONFIRMATION = 100207, + SUBMISSION_WRONG_RESPONSE_MODE = 100208, + SUBMISSION_ATTACHMENT_TOO_LARGE = 100209, + SUBMISSION_INVALID_FILE_EXTENSION = 100210, + SUBMISSION_FAILED = 100211, + SUBMISSION_INVALID_FIELD_ID = 100212, + SUBMISSION_ATTACHMENT_SIZE_LIMIT_EXCEEDED = 100213, + SUBMISSION_FEATURE_DISABLED = 100214, + SUBMISSION_INVALID_FILE_KEY = 100215, + SUBMISSION_VIRUS_SCAN_FAILED = 100216, + SUBMISSION_JSON_PARSE_FAILED = 100217, + SUBMISSION_DOWNLOAD_CLEAN_FILE_FAILED = 100218, + SUBMISSION_PARSE_VIRUS_SCANNER_LAMBDA_PAYLOAD = 100219, + SUBMISSION_MALICIOUS_FILE_DETECTED = 100220, + SUBMISSION_INVALID_WORKFLOW_TYPE = 100221, + SUBMISSION_ATTACHMENT_UPLOAD = 100222, + // Email Submission Errors (email mode deprecated soon) + EMAIL_SUBMISSION_HASH = 100223, + // [100300 - 100399] Receiver Errors (/modules/submission/receiver) + RECEIVER_INITIALISE_MULTIPART_RECEIVER = 100301, + RECEIVER_MULTIPART_CONTENT_LIMIT = 100302, + RECEIVER_MULTIPART_CONTENT_PARSING = 100303, + RECEIVER_MULTIPART_ERROR = 100304, + // [100400 - 100499] Encrypt Submission Errors (/modules/submission/encrypt-submission) + ENCRYPT_FORMSG_REQ_BODY_EXISTS = 100400, + ENCRYPT_ENCRYPTED_PAYLOAD_EXISTS = 100401, + // [100500 - 100599] Feedback Errors (/modules/feedback) + FEEDBACK_INVALID_SUBMISSION_ID = 100500, + FEEDBACK_DUPLICATE_SUBMISSION = 100501, + // [100600 - 100699] Admin Feedback Errors (/modules/admin-feedback) + ADMIN_FEEDBACK_MISSING = 100600, + // [100700 - 100799] Workspace Errors (/modules/workspace) + WORKSPACE_NOT_FOUND = 100700, + WORKSPACE_FORBIDDEN = 100701, + // End FormSG Errors --------------------------------------------------------- + + // [11xxxx] Auth Errors ------------------------------------------------------ + // [110000 - 110099] General Auth Errors (/modules/auth) + AUTH_INVALID_DOMAIN = 110000, + AUTH_INVALID_OTP = 110001, + AUTH_INVALID_TOKEN = 110002, + AUTH_MISSING_TOKEN = 110003, + AUTH_UNAUTHORIZED = 110004, + // [110100 - 110199] SPCP Errors (/modules/spcp) + SPCP_CREATE_REDIRECT_URL = 110100, + SPCP_VERIFY_JWT = 110101, + SPCP_MISSING_ATTRIBUTES = 110102, + SPCP_INVALID_JWT = 110103, + SPCP_MISSING_JWT = 110104, + SPCP_INVALID_ID_TOKEN = 110105, + SPCP_INVALID_STATE = 110106, + SPCP_CREATE_JWT = 110107, + SPCP_EXCHANGE_AUTH_TOKEN = 110108, + // [110200 - 110299] SPCP OIDC Errors (/modules/spcp) + SPCP_OIDC_CREATE_AUTHORISATION_URL = 110200, + SPCP_OIDC_CREATE_JWT = 110201, + SPCP_OIDC_GET_SIGNING_KEY = 110202, + SPCP_OIDC_GET_DECRYPTION_KEY = 110203, + SPCP_OIDC_GET_VERIFICATION_KEY = 110204, + SPCP_OIDC_INVALID_ID_TOKEN = 110205, + SPCP_OIDC_JWK_SHAPE_INVALID = 110206, + SPCP_OIDC_MISSING_ID_TOKEN = 110207, + SPCP_OIDC_INVALID_VERIFICATION_KEY = 110208, + SPCP_OIDC_EXCHANGE_AUTH_TOKEN = 110209, + // [110300 - 110399] MyInfo Errors (/modules/myinfo) + MYINFO_CIRCUIT_BREAKER = 110300, + MYINFO_FETCH = 110301, + MYINFO_HASHING = 110302, + MYINFO_MISSING_HASH = 110303, + MYINFO_HASH_DID_NOT_MATCH = 110304, + MYINFO_PARSE_RELAY_STATE = 110305, + MYINFO_MISSING_LOGIN_COOKIE = 110306, + MYINFO_INVALID_LOGIN_COOKIE = 110307, + MYINFO_INVALID_AUTH_CODE_COOKIE = 110308, + MYINFO_COOKIE_STATE = 110309, + // [110400 - 110499] Sgid Errors (/modules/sgid) + SGID_CREATE_REDIRECT_URL = 110400, + SGID_INVALID_STATE = 110401, + SGID_FETCH_ACCESS_TOKEN = 110402, + SGID_FETCH_USER_INFO = 110403, + SGID_MALFORMED_MYINFO_COOKIE = 110404, + SGID_VERIFY_JWT = 110405, + SGID_INVALID_JWT = 110406, + SGID_MISSING_JWT = 110407, + // End of Auth Errors -------------------------------------------------------- + + // [12xxxx] Database Errors (/modules/core) ---------------------------------- + DATABASE_ERROR = 120000, + DATABASE_VALIDATION = 120001, + DATABASE_CONFLICT = 120002, + DATABASE_PAYLOAD_SIZE = 120003, + DATABASE_DUPLICATE_KEY = 120004, + DATABASE_WRITE_CONFLICT = 120005, + // End of Database Errors ---------------------------------------------------- + + // [13xxxx] Payment Errors --------------------------------------------------- + // [130000 - 130099] General Payment Errors (/modules/payments) + PAYMENT_INVALID_AMOUNT = 130000, + PAYMENT_NOT_FOUND = 130001, + PAYMENT_CONFIRMED_PAYMENT_NOT_FOUND = 130002, + PAYMENT_ALREADY_CONFIRMED = 130003, + PAYMENT_ACCOUNT_INFORMATION = 130004, + PAYMENT_INVALID_PAYMENT_PRODUCTS = 130005, + PAYMENT_CONFIGURATION = 130006, + // [130100 - 130199] Stripe Errors (/modules/payments) + PAYMENT_STRIPE_SUCCESSFUL_CHARGE_NOT_FOUND = 130100, + PAYMENT_STRIPE_TRANSACTION_FEE_NOT_FOUND = 130101, + PAYMENT_STRIPE_MALFORMED_CHARGE_OBJECT = 130102, + PAYMENT_STRIPE_MALFORMED_EVENT_OBJECT = 130103, + PAYMENT_STRIPE_METADATA_INVALID = 130104, + PAYMENT_STRIPE_METADATA_VALID_PAYMENT_ID_NOT_FOUND = 130105, + PAYMENT_STRIPE_METADATA_INCORRECT_ENV = 130106, + PAYMENT_STRIPE_FETCH_ERROR = 130107, + PAYMENT_STRIPE_ACCOUNT_ERROR = 130108, + PAYMENT_STRIPE_COMPUTE_PAYMENT_STATE = 130109, + // [130200 - 130299] Payment Proof Errors (/modules/payments) + PAYMENT_PROOF_INVOICE_PDF_GENERATION = 130200, + PAYMENT_PROOF_UPLOAD_S3 = 130201, + PAYMENT_PROOF_PRESIGN_S3 = 130202, + // [130300 - 130399] Billing Errors (/modules/billing) + BILLING_FORM_HAS_NO_AUTH = 130300, + // End of Payment Errors ----------------------------------------------------- + + // [14xxxx] Communication Channel Errors (SMS, Email, Webhook) --------------- + // [140000 - 140099] SMS Errors (/services/postman-sms) + POSTMAN_SMS_SEND = 140000, + POSTMAN_INVALID_NUMBER = 140001, + // [140100 - 140199] Mail Errors (/services/mail) + MAIL_SEND_ERROR = 140100, + MAIL_GENERATION_ERROR = 140101, + // [140200 - 140299] Webhook Errors (/modules/webhook) + WEBHOOK_VALIDATION = 140200, + WEBHOOK_FAILED_WITH_PRESIGNED_URL_GENERATION = 140201, + WEBHOOK_FAILED_WITH_UNKNOWN_ERROR = 140202, + WEBHOOK_FAILED_WITH_AXIOS_ERROR = 140203, + WEBHOOK_QUEUE_MESSAGE_PARSING_ERROR = 140204, + WEBHOOK_NO_MORE_RETRIES = 140205, + WEBHOOK_PUSH_TO_QUEUE = 140206, + WEBHOOK_RETRIES_NOT_ENABLED = 140207, + // [140300 - 140399] Bounce Errors (/modules/bounce) + BOUNCE_INVALID_NOTIFCATION = 140300, + BOUNCE_SEND_BOUNCE_SMS_NOTIFICATION = 140301, + BOUNCE_MISSING_EMAIL_HEADERS = 140302, + BOUNCE_PARSE_NOTIFICATION = 140303, + // End of Communication Channel Errors --------------------------------------- + + // [15xxxx] Verification Errors ---------------------------------------------- + // [150000 - 150099] General Verification Errors (/modules/verification) + VERIFICATION_TRANSACTION_NOT_FOUND = 150000, + VERIFICATION_FIELD_NOT_FOUND_IN_TRANSACTION = 150001, + VERIFICATION_TRANSACTION_EXPIRED = 150002, + VERIFICATION_OTP_EXPIRED = 150003, + VERIFICATION_MISSING_HASH_DATA = 150004, + VERIFICATION_OTP_RETRY_EXCEEDED = 150005, + VERIFICATION_WRONG_OTP = 150006, + VERIFICATION_WAIT_FOR_OTP = 150007, + VERIFICATION_OTP_REQUEST_COUNT_EXCEEDED = 150008, + VERIFICATION_NON_VERIFIED_FIELD_TYPE = 150009, + VERIFICATION_SMS_LIMIT_EXCEEDED = 150010, + VERIFICATION_OTP_REQUEST_ERROR = 150011, + // [150100 - 150199] Captcha Errors (/services/captcha) + CAPTCHA_CONNECTION = 150100, + CAPTCHA_VERIFY = 150101, + CAPTCHA_MISSING = 150102, + // [150200 - 150299] Turnstile Errors (/services/turnstile) + TURNSTILE_CONNECTION = 150200, + TURNSTILE_RESPONSE_ERROR = 150201, + TURNSTILE_MISSING = 150202, + // End of Verification Errors ------------------------------------------------ + + // [19xxxx] Other Errors ----------------------------------------------------- + // [190000 - 190099] Core Errors (/modules/core) + MALFORMED_PARAMETERS = 190000, + EMPTY_ERROR_FIELD = 190001, + SECRETS_MANAGER = 190002, + SECRETS_MANAGER_NOT_FOUND = 190003, + SECRETS_MANAGER_CONFLICT = 190004, + TWILIO_CACHE = 190005, + // [190100 - 190199] User Errors (/modules/user) + USER_INVALID_OTP = 190100, + USER_MISSING = 190101, + // [190200 - 190299] Verified Content Errors (/modules/verified-content) + VERIFIED_CONTENT_MALFORMED = 190200, + VERIFIED_CONTENT_ENCRYPT_FAILURE = 190201, + // End of Other Errors ------------------------------------------------------- +} + /** * A custom base error class that encapsulates the name, message, status code, * and logging meta string (if any) for the error. @@ -7,77 +239,82 @@ export class ApplicationError extends Error { * Meta object to be logged by the application logger, if any. */ meta?: unknown + // FormSG Business Logic errors, not to be confused with HTTP Status Codes + code?: number - constructor(message?: string, meta?: unknown) { + constructor(message?: string, meta?: unknown, errorCode?: number) { super() - Error.captureStackTrace(this, this.constructor) - this.name = this.constructor.name - this.message = message || 'Something went wrong. Please try again.' + Error.captureStackTrace(this, this.constructor) this.meta = meta + this.code = errorCode + + if (this.code) { + setErrorCode(this) + } } } export class DatabaseError extends ApplicationError { constructor(message?: string) { - super(message) + super(message, undefined, ErrorCodes.DATABASE_ERROR) } } export class DatabaseValidationError extends ApplicationError { constructor(message: string) { - super(message) + super(message, undefined, ErrorCodes.DATABASE_VALIDATION) } } export class DatabaseConflictError extends ApplicationError { constructor(message: string) { - super(message) + super(message, undefined, ErrorCodes.DATABASE_CONFLICT) } } export class DatabasePayloadSizeError extends ApplicationError { constructor(message: string) { - super(message) + super(message, undefined, ErrorCodes.DATABASE_PAYLOAD_SIZE) } } export class DatabaseDuplicateKeyError extends ApplicationError { constructor(message: string) { - super(message) + super(message, undefined, ErrorCodes.DATABASE_DUPLICATE_KEY) } } export class DatabaseWriteConflictError extends ApplicationError { constructor(message: string) { - super(message) + super(message, undefined, ErrorCodes.DATABASE_WRITE_CONFLICT) } } export class SecretsManagerError extends ApplicationError { constructor(message?: string) { - super(message) + super(message, undefined, ErrorCodes.SECRETS_MANAGER) } } export class SecretsManagerNotFoundError extends ApplicationError { constructor(message: string) { - super(message) + super(message, undefined, ErrorCodes.SECRETS_MANAGER_NOT_FOUND) } } export class SecretsManagerConflictError extends ApplicationError { constructor(message: string) { - super(message) + super(message, undefined, ErrorCodes.SECRETS_MANAGER_CONFLICT) } } export class TwilioCacheError extends ApplicationError { constructor(message?: string) { - super(message) + super(message, undefined, ErrorCodes.TWILIO_CACHE) } } @@ -94,16 +331,7 @@ export type PossibleDatabaseError = export class MalformedParametersError extends ApplicationError { constructor(message: string, meta?: unknown) { - super(message, meta) - } -} - -/** - * Error thrown when attachment upload fails - */ -export class AttachmentUploadError extends ApplicationError { - constructor(message = 'Error while uploading encrypted attachments to S3') { - super(message) + super(message, meta, ErrorCodes.MALFORMED_PARAMETERS) } } @@ -113,6 +341,6 @@ export class AttachmentUploadError extends ApplicationError { */ export class EmptyErrorFieldError extends ApplicationError { constructor(message = 'Errors were returned but list is empty.') { - super(message) + super(message, undefined, ErrorCodes.EMPTY_ERROR_FIELD) } } diff --git a/src/app/modules/datadog/datadog.utils.ts b/src/app/modules/datadog/datadog.utils.ts index 5ddde55bba..4e0975f946 100644 --- a/src/app/modules/datadog/datadog.utils.ts +++ b/src/app/modules/datadog/datadog.utils.ts @@ -1,6 +1,7 @@ import tracer from 'dd-trace' import { IPopulatedForm } from '../../../types' +import { ApplicationError } from '../core/core.errors' export const setFormTags = (form: IPopulatedForm) => { const span = tracer.scope().active() @@ -12,3 +13,17 @@ export const setFormTags = (form: IPopulatedForm) => { span.setTag('form.agency.shortname', `${form.admin.agency.shortName}`) } } + +/** + * Sets the tags for the current active span. Should be called by a top-level + * controller. + * @param error The error to set the tags for + */ +export const setErrorCode = (error: ApplicationError) => { + const span = tracer.scope().active() + if (span && error.code) { + span.setTag('error.type', error.code) + span.setTag('error.message', error.message) + if (error.stack) span.setTag('error.stack', `${error.stack}`) + } +} diff --git a/src/app/modules/feedback/feedback.errors.ts b/src/app/modules/feedback/feedback.errors.ts index 024fa33ec1..55e525cda8 100644 --- a/src/app/modules/feedback/feedback.errors.ts +++ b/src/app/modules/feedback/feedback.errors.ts @@ -1,8 +1,8 @@ -import { ApplicationError } from '../core/core.errors' +import { ApplicationError, ErrorCodes } from '../core/core.errors' export class InvalidSubmissionIdError extends ApplicationError { constructor(message = 'Sorry, something went wrong. Please try again.') { - super(message) + super(message, undefined, ErrorCodes.FEEDBACK_INVALID_SUBMISSION_ID) } } @@ -10,6 +10,6 @@ export class DuplicateFeedbackSubmissionError extends ApplicationError { constructor( message = 'You have already submitted feedback for this submission. To provide additional feedback, please contact the form administrator.', ) { - super(message) + super(message, undefined, ErrorCodes.FEEDBACK_DUPLICATE_SUBMISSION) } } diff --git a/src/app/modules/form/admin-form/admin-form.errors.ts b/src/app/modules/form/admin-form/admin-form.errors.ts index 1cefcd45b2..1f692f32e8 100644 --- a/src/app/modules/form/admin-form/admin-form.errors.ts +++ b/src/app/modules/form/admin-form/admin-form.errors.ts @@ -2,29 +2,29 @@ import { GO_ALREADY_EXIST_ERROR_MESSAGE, GO_VALIDATION_ERROR_MESSAGE, } from '../../../../../shared/constants' -import { ApplicationError } from '../../core/core.errors' +import { ApplicationError, ErrorCodes } from '../../core/core.errors' export class InvalidFileTypeError extends ApplicationError { constructor(message = 'Unsupported file type') { - super(message) + super(message, undefined, ErrorCodes.ADMIN_FORM_INVALID_FILE_TYPE) } } export class EditFieldError extends ApplicationError { constructor(message: string) { - super(message) + super(message, undefined, ErrorCodes.ADMIN_FORM_EDIT_FIELD) } } export class FieldNotFoundError extends ApplicationError { constructor(message = 'Field to modify not found') { - super(message) + super(message, undefined, ErrorCodes.ADMIN_FORM_FIELD_NOT_FOUND) } } export class InvalidCollaboratorError extends ApplicationError { constructor(message: string) { - super(message) + super(message, undefined, ErrorCodes.ADMIN_FORM_INVALID_COLLABORATOR) } } @@ -32,44 +32,47 @@ export class PaymentChannelNotFoundError extends ApplicationError { constructor( message = 'Please ensure that you have connected your Stripe account in settings to save this field', ) { - super(message) + super(message, undefined, ErrorCodes.ADMIN_FORM_PAYMENT_CHANNEL_NOT_FOUND) } } // Family of GoGov Errors from GoGov Integration export class GoGovError extends ApplicationError { - constructor(message = 'Error occurred when claiming GoGov link') { - super(message) + constructor( + message = 'Error occurred when claiming GoGov link', + errorCode?: ErrorCodes, + ) { + super(message, undefined, errorCode || ErrorCodes.ADMIN_FORM_GOGOV) } } export class GoGovValidationError extends GoGovError { constructor(message = GO_VALIDATION_ERROR_MESSAGE) { - super(message) + super(message, ErrorCodes.ADMIN_FORM_GOGOV_VALIDATION) } } export class GoGovAlreadyExistError extends GoGovError { constructor(message = GO_ALREADY_EXIST_ERROR_MESSAGE) { - super(message) + super(message, ErrorCodes.ADMIN_FORM_GOGOV_ALREADY_EXIST) } } export class GoGovRequestLimitError extends GoGovError { constructor(message = 'GoGov request limit exceeded') { - super(message) + super(message, ErrorCodes.ADMIN_FORM_GOGOV_REQUEST_LIMIT) } } export class GoGovBadGatewayError extends GoGovError { constructor(message = 'GoGov request failed') { - super(message) + super(message, ErrorCodes.ADMIN_FORM_GOGOV_BAD_GATEWAY) } } export class GoGovServerError extends GoGovError { // Default error message will be shown if not AxiosError constructor(message = 'Unexpected error occured when claiming GoGov link') { - super(message) + super(message, ErrorCodes.ADMIN_FORM_GOGOV_SERVER) } } diff --git a/src/app/modules/form/form.errors.ts b/src/app/modules/form/form.errors.ts index 5ef8cdc8cc..e7cfc87e68 100644 --- a/src/app/modules/form/form.errors.ts +++ b/src/app/modules/form/form.errors.ts @@ -1,15 +1,15 @@ import { FormAuthType } from '../../../../shared/types' -import { ApplicationError } from '../core/core.errors' +import { ApplicationError, ErrorCodes } from '../core/core.errors' export class FormNotFoundError extends ApplicationError { constructor(message = 'Form not found') { - super(message) + super(message, undefined, ErrorCodes.FORM_NOT_FOUND) } } export class FormDeletedError extends ApplicationError { constructor(message = 'This form is no longer active') { - super(message) + super(message, undefined, ErrorCodes.FORM_DELETED) } } @@ -29,7 +29,7 @@ export class PrivateFormError extends ApplicationError { message = 'If you think this is a mistake, please contact the agency that gave you the form link.', formTitle: string, ) { - super(message) + super(message, undefined, ErrorCodes.FORM_PRIVATE_FORM) this.formTitle = formTitle } } @@ -40,7 +40,7 @@ export class PrivateFormError extends ApplicationError { */ export class ForbiddenFormError extends ApplicationError { constructor(message: string) { - super(message) + super(message, undefined, ErrorCodes.FORM_FORBIDDEN_FORM) } } @@ -49,7 +49,7 @@ export class ForbiddenFormError extends ApplicationError { */ export class TransferOwnershipError extends ApplicationError { constructor(message: string) { - super(message) + super(message, undefined, ErrorCodes.FORM_TRANSFER_OWNERSHIP) } } @@ -58,7 +58,7 @@ export class TransferOwnershipError extends ApplicationError { */ export class LogicNotFoundError extends ApplicationError { constructor(message = 'logicId does not exist on form') { - super(message) + super(message, undefined, ErrorCodes.FORM_LOGIC_NOT_FOUND) } } @@ -69,6 +69,8 @@ export class AuthTypeMismatchError extends ApplicationError { constructor(attemptedAuthType: FormAuthType, formAuthType?: FormAuthType) { super( `Attempted authentication type ${attemptedAuthType} did not match form auth type ${formAuthType}`, + undefined, + ErrorCodes.FORM_AUTH_TYPE_MISMATCH, ) } } @@ -81,6 +83,8 @@ export class FormAuthNoEsrvcIdError extends ApplicationError { constructor(formId: string) { super( `Attempted to validate form ${formId} which did not have an eServiceId`, + undefined, + ErrorCodes.FORM_AUTH_NO_ESRVC_ID, ) } } diff --git a/src/app/modules/myinfo/myinfo.errors.ts b/src/app/modules/myinfo/myinfo.errors.ts index 97ff66b63b..a5cc1db22b 100644 --- a/src/app/modules/myinfo/myinfo.errors.ts +++ b/src/app/modules/myinfo/myinfo.errors.ts @@ -1,11 +1,11 @@ -import { ApplicationError } from '../core/core.errors' +import { ApplicationError, ErrorCodes } from '../core/core.errors' /** * Circuit breaker is open */ export class MyInfoCircuitBreakerError extends ApplicationError { constructor(message = 'Circuit breaker tripped') { - super(message) + super(message, undefined, ErrorCodes.MYINFO_CIRCUIT_BREAKER) } } @@ -14,7 +14,7 @@ export class MyInfoCircuitBreakerError extends ApplicationError { */ export class MyInfoFetchError extends ApplicationError { constructor(message = 'Error while requesting MyInfo data') { - super(message) + super(message, undefined, ErrorCodes.MYINFO_FETCH) } } @@ -23,7 +23,7 @@ export class MyInfoFetchError extends ApplicationError { */ export class MyInfoHashingError extends ApplicationError { constructor(message = 'Error occurred while hashing data') { - super(message) + super(message, undefined, ErrorCodes.MYINFO_HASHING) } } @@ -32,7 +32,7 @@ export class MyInfoHashingError extends ApplicationError { */ export class MyInfoMissingHashError extends ApplicationError { constructor(message = 'Requested hashes not found in database') { - super(message) + super(message, undefined, ErrorCodes.MYINFO_MISSING_HASH) } } @@ -41,7 +41,7 @@ export class MyInfoMissingHashError extends ApplicationError { */ export class MyInfoHashDidNotMatchError extends ApplicationError { constructor(message = 'Responses did not match hashed values') { - super(message) + super(message, undefined, ErrorCodes.MYINFO_HASH_DID_NOT_MATCH) } } @@ -52,7 +52,7 @@ export class MyInfoParseRelayStateError extends ApplicationError { constructor( message = 'Relay state received from MyInfo had incorrect format', ) { - super(message) + super(message, undefined, ErrorCodes.MYINFO_PARSE_RELAY_STATE) } } @@ -61,7 +61,7 @@ export class MyInfoParseRelayStateError extends ApplicationError { */ export class MyInfoMissingLoginCookieError extends ApplicationError { constructor(message = 'Login cookie not present on MyInfo submission') { - super(message) + super(message, undefined, ErrorCodes.MYINFO_MISSING_LOGIN_COOKIE) } } @@ -70,7 +70,7 @@ export class MyInfoMissingLoginCookieError extends ApplicationError { */ export class MyInfoInvalidLoginCookieError extends ApplicationError { constructor(message = 'Login cookie could not be verified') { - super(message) + super(message, undefined, ErrorCodes.MYINFO_INVALID_LOGIN_COOKIE) } } @@ -79,7 +79,11 @@ export class MyInfoInvalidLoginCookieError extends ApplicationError { */ export class MyInfoInvalidAuthCodeCookieError extends ApplicationError { constructor(cookie: unknown, message = 'Auth code cookie is malformed') { - super(`${message}: ${cookie}`) + super( + `${message}: ${cookie}`, + undefined, + ErrorCodes.MYINFO_INVALID_AUTH_CODE_COOKIE, + ) } } @@ -88,6 +92,6 @@ export class MyInfoInvalidAuthCodeCookieError extends ApplicationError { */ export class MyInfoCookieStateError extends ApplicationError { constructor(message = 'MyInfo cookie is in error state') { - super(message) + super(message, undefined, ErrorCodes.MYINFO_COOKIE_STATE) } } diff --git a/src/app/modules/payments/payment-proof.errors.ts b/src/app/modules/payments/payment-proof.errors.ts index 63972b00c9..12f68aac5a 100644 --- a/src/app/modules/payments/payment-proof.errors.ts +++ b/src/app/modules/payments/payment-proof.errors.ts @@ -1,19 +1,19 @@ -import { ApplicationError } from '../core/core.errors' +import { ApplicationError, ErrorCodes } from '../core/core.errors' export class InvoicePdfGenerationError extends ApplicationError { constructor(message = 'Error while generating invoice pdf') { - super(message) + super(message, undefined, ErrorCodes.PAYMENT_PROOF_INVOICE_PDF_GENERATION) } } export class PaymentProofUploadS3Error extends ApplicationError { constructor(message = "Can't upload payment proof to S3") { - super(message) + super(message, undefined, ErrorCodes.PAYMENT_PROOF_UPLOAD_S3) } } export class PaymentProofPresignS3Error extends ApplicationError { constructor(message = "Can't generate payment proof presign url from S3") { - super(message) + super(message, undefined, ErrorCodes.PAYMENT_PROOF_PRESIGN_S3) } } diff --git a/src/app/modules/payments/payments.errors.ts b/src/app/modules/payments/payments.errors.ts index ffbbfbd1c2..932ce11212 100644 --- a/src/app/modules/payments/payments.errors.ts +++ b/src/app/modules/payments/payments.errors.ts @@ -1,44 +1,44 @@ -import { ApplicationError } from '../core/core.errors' +import { ApplicationError, ErrorCodes } from '../core/core.errors' export class InvalidPaymentAmountError extends ApplicationError { constructor(message = 'Invalid payment amount') { - super(message) + super(message, undefined, ErrorCodes.PAYMENT_INVALID_AMOUNT) } } export class PaymentNotFoundError extends ApplicationError { constructor(message = 'Payment not found') { - super(message) + super(message, undefined, ErrorCodes.PAYMENT_NOT_FOUND) } } export class ConfirmedPaymentNotFoundError extends ApplicationError { constructor(message = 'Confirmed payment not found') { - super(message) + super(message, undefined, ErrorCodes.PAYMENT_CONFIRMED_PAYMENT_NOT_FOUND) } } export class PaymentAlreadyConfirmedError extends ApplicationError { constructor(message = 'Payment has already been confirmed') { - super(message) + super(message, undefined, ErrorCodes.PAYMENT_ALREADY_CONFIRMED) } } export class PaymentAccountInformationError extends ApplicationError { constructor(message = 'Missing payment account information') { - super(message) + super(message, undefined, ErrorCodes.PAYMENT_ACCOUNT_INFORMATION) } } export class InvalidPaymentProductsError extends ApplicationError { constructor(message = 'Invalid payment submission') { - super(message) + super(message, undefined, ErrorCodes.PAYMENT_INVALID_PAYMENT_PRODUCTS) } } // TODO: Should remove once email notifications for payment forms are supported export class PaymentConfigurationError extends ApplicationError { constructor(message = 'Invalid payment configuration') { - super(message) + super(message, undefined, ErrorCodes.PAYMENT_CONFIGURATION) } } diff --git a/src/app/modules/payments/stripe.errors.ts b/src/app/modules/payments/stripe.errors.ts index 02ed87106a..79351e0c47 100644 --- a/src/app/modules/payments/stripe.errors.ts +++ b/src/app/modules/payments/stripe.errors.ts @@ -1,61 +1,73 @@ -import { ApplicationError } from '../core/core.errors' +import { ApplicationError, ErrorCodes } from '../core/core.errors' export class SuccessfulChargeNotFoundError extends ApplicationError { constructor(message = 'Successful charge not found from Stripe API') { - super(message) + super( + message, + undefined, + ErrorCodes.PAYMENT_STRIPE_SUCCESSFUL_CHARGE_NOT_FOUND, + ) } } export class StripeTransactionFeeNotFoundError extends ApplicationError { constructor(message = 'Transaction fee not found from Stripe API') { - super(message) + super( + message, + undefined, + ErrorCodes.PAYMENT_STRIPE_TRANSACTION_FEE_NOT_FOUND, + ) } } export class MalformedStripeChargeObjectError extends ApplicationError { constructor(message = 'Data missing from charge object') { - super(message) + super(message, undefined, ErrorCodes.PAYMENT_STRIPE_MALFORMED_CHARGE_OBJECT) } } export class MalformedStripeEventObjectError extends ApplicationError { constructor(message = 'Data missing from event object') { - super(message) + super(message, undefined, ErrorCodes.PAYMENT_STRIPE_MALFORMED_EVENT_OBJECT) } } export class StripeMetadataInvalidError extends ApplicationError { constructor(message = 'Invalid shape found for Stripe metadata') { - super(message) + super(message, undefined, ErrorCodes.PAYMENT_STRIPE_METADATA_INVALID) } } export class StripeMetadataValidPaymentIdNotFoundError extends ApplicationError { constructor(message = 'Valid payment id not found in Stripe metadata') { - super(message) + super( + message, + undefined, + ErrorCodes.PAYMENT_STRIPE_METADATA_VALID_PAYMENT_ID_NOT_FOUND, + ) } } export class StripeMetadataIncorrectEnvError extends ApplicationError { constructor(message = 'Stripe webhook sent to incorrect application') { - super(message) + super(message, undefined, ErrorCodes.PAYMENT_STRIPE_METADATA_INCORRECT_ENV) } } export class StripeFetchError extends ApplicationError { constructor(message = 'Error while requesting Stripe data') { - super(message) + super(message, undefined, ErrorCodes.PAYMENT_STRIPE_FETCH_ERROR) } } export class StripeAccountError extends ApplicationError { constructor(message = 'Error when processing Stripe account') { - super(message) + super(message, undefined, ErrorCodes.PAYMENT_STRIPE_ACCOUNT_ERROR) } } export class ComputePaymentStateError extends ApplicationError { constructor(message = 'Error while computing payment state') { - super(message) + super(message, undefined, ErrorCodes.PAYMENT_STRIPE_COMPUTE_PAYMENT_STATE) } } diff --git a/src/app/modules/sgid/sgid.errors.ts b/src/app/modules/sgid/sgid.errors.ts index 7860f1c9ab..ac9ae4249e 100644 --- a/src/app/modules/sgid/sgid.errors.ts +++ b/src/app/modules/sgid/sgid.errors.ts @@ -1,32 +1,32 @@ -import { ApplicationError } from '../../modules/core/core.errors' +import { ApplicationError, ErrorCodes } from '../../modules/core/core.errors' export class SgidCreateRedirectUrlError extends ApplicationError { constructor(message = 'Error while creating redirect URL') { - super(message) + super(message, undefined, ErrorCodes.SGID_CREATE_REDIRECT_URL) } } export class SgidInvalidStateError extends ApplicationError { constructor(message = 'State given by sgID is malformed') { - super(message) + super(message, undefined, ErrorCodes.SGID_INVALID_STATE) } } export class SgidFetchAccessTokenError extends ApplicationError { constructor(message = 'Error while fetching access token') { - super(message) + super(message, undefined, ErrorCodes.SGID_FETCH_ACCESS_TOKEN) } } export class SgidFetchUserInfoError extends ApplicationError { constructor(message = 'Error while fetching user info') { - super(message) + super(message, undefined, ErrorCodes.SGID_FETCH_USER_INFO) } } export class SgidMalformedMyInfoCookieError extends ApplicationError { constructor(message = 'SGID MyInfo cookie is malformed') { - super(message) + super(message, undefined, ErrorCodes.SGID_MALFORMED_MYINFO_COOKIE) } } @@ -35,7 +35,7 @@ export class SgidMalformedMyInfoCookieError extends ApplicationError { */ export class SgidVerifyJwtError extends ApplicationError { constructor(message = 'Invalid JWT') { - super(message) + super(message, undefined, ErrorCodes.SGID_VERIFY_JWT) } } @@ -44,7 +44,7 @@ export class SgidVerifyJwtError extends ApplicationError { */ export class SgidInvalidJwtError extends ApplicationError { constructor(message = 'Decoded JWT did not contain the correct attributes') { - super(message) + super(message, undefined, ErrorCodes.SGID_INVALID_JWT) } } @@ -53,6 +53,6 @@ export class SgidInvalidJwtError extends ApplicationError { */ export class SgidMissingJwtError extends ApplicationError { constructor(message = 'No JWT present in cookies') { - super(message) + super(message, undefined, ErrorCodes.SGID_MISSING_JWT) } } diff --git a/src/app/modules/spcp/spcp.errors.ts b/src/app/modules/spcp/spcp.errors.ts index a743eaf5f2..ab05ad2fe0 100644 --- a/src/app/modules/spcp/spcp.errors.ts +++ b/src/app/modules/spcp/spcp.errors.ts @@ -1,11 +1,11 @@ -import { ApplicationError } from '../../modules/core/core.errors' +import { ApplicationError, ErrorCodes } from '../../modules/core/core.errors' /** * Error while creating redirect URL */ export class CreateRedirectUrlError extends ApplicationError { constructor(message = 'Error while creating redirect URL') { - super(message) + super(message, undefined, ErrorCodes.SPCP_CREATE_REDIRECT_URL) } } @@ -14,7 +14,7 @@ export class CreateRedirectUrlError extends ApplicationError { */ export class VerifyJwtError extends ApplicationError { constructor(message = 'Invalid JWT') { - super(message) + super(message, undefined, ErrorCodes.SPCP_VERIFY_JWT) } } @@ -25,7 +25,7 @@ export class MissingAttributesError extends ApplicationError { constructor( message = 'Attributes given by SP/CP did not contain NRIC or entity ID/UID.', ) { - super(message) + super(message, undefined, ErrorCodes.SPCP_MISSING_ATTRIBUTES) } } @@ -36,7 +36,7 @@ export class InvalidJwtError extends ApplicationError { constructor( message = 'Decoded JWT did not contain the correct SPCP attributes', ) { - super(message) + super(message, undefined, ErrorCodes.SPCP_INVALID_JWT) } } @@ -45,7 +45,7 @@ export class InvalidJwtError extends ApplicationError { */ export class MissingJwtError extends ApplicationError { constructor(message = 'No JWT present in cookies') { - super(message) + super(message, undefined, ErrorCodes.SPCP_MISSING_JWT) } } @@ -54,7 +54,7 @@ export class MissingJwtError extends ApplicationError { */ export class InvalidIdTokenError extends ApplicationError { constructor(message = 'idToken has invalid shape') { - super(message) + super(message, undefined, ErrorCodes.SPCP_INVALID_ID_TOKEN) } } @@ -63,7 +63,7 @@ export class InvalidIdTokenError extends ApplicationError { */ export class InvalidStateError extends ApplicationError { constructor(message = 'Unable to parse invalid state') { - super(message) + super(message, undefined, ErrorCodes.SPCP_INVALID_STATE) } } @@ -72,7 +72,7 @@ export class InvalidStateError extends ApplicationError { */ export class CreateJwtError extends ApplicationError { constructor(message = 'Create JWT failed') { - super(message) + super(message, undefined, ErrorCodes.SPCP_CREATE_JWT) } } @@ -81,6 +81,6 @@ export class CreateJwtError extends ApplicationError { */ export class ExchangeAuthTokenError extends ApplicationError { constructor(message = 'Exchange auth code for nric failed') { - super(message) + super(message, undefined, ErrorCodes.SPCP_EXCHANGE_AUTH_TOKEN) } } diff --git a/src/app/modules/spcp/spcp.oidc.client.errors.ts b/src/app/modules/spcp/spcp.oidc.client.errors.ts index f9a7255be6..9b78be43c8 100644 --- a/src/app/modules/spcp/spcp.oidc.client.errors.ts +++ b/src/app/modules/spcp/spcp.oidc.client.errors.ts @@ -1,11 +1,11 @@ -import { ApplicationError } from '../core/core.errors' +import { ApplicationError, ErrorCodes } from '../core/core.errors' /** * Error while creating Authorisation URL */ export class CreateAuthorisationUrlError extends ApplicationError { constructor(message = 'Error while creating Authorisation URL') { - super(message) + super(message, undefined, ErrorCodes.SPCP_OIDC_CREATE_AUTHORISATION_URL) } } @@ -14,7 +14,7 @@ export class CreateAuthorisationUrlError extends ApplicationError { */ export class CreateJwtError extends ApplicationError { constructor(message = 'Create JWT failed') { - super(message) + super(message, undefined, ErrorCodes.SPCP_OIDC_CREATE_JWT) } } @@ -23,7 +23,7 @@ export class CreateJwtError extends ApplicationError { */ export class GetSigningKeyError extends ApplicationError { constructor(message = 'Failed to get signing key') { - super(message) + super(message, undefined, ErrorCodes.SPCP_OIDC_GET_SIGNING_KEY) } } @@ -32,7 +32,7 @@ export class GetSigningKeyError extends ApplicationError { */ export class GetDecryptionKeyError extends ApplicationError { constructor(message = 'Failed to get decryption key') { - super(message) + super(message, undefined, ErrorCodes.SPCP_OIDC_GET_DECRYPTION_KEY) } } @@ -41,7 +41,7 @@ export class GetDecryptionKeyError extends ApplicationError { */ export class GetVerificationKeyError extends ApplicationError { constructor(message = 'Failed to get verification key') { - super(message) + super(message, undefined, ErrorCodes.SPCP_OIDC_GET_VERIFICATION_KEY) } } @@ -50,7 +50,7 @@ export class GetVerificationKeyError extends ApplicationError { */ export class InvalidIdTokenError extends ApplicationError { constructor(message = 'idToken has invalid shape') { - super(message) + super(message, undefined, ErrorCodes.SPCP_OIDC_INVALID_ID_TOKEN) } } @@ -59,7 +59,7 @@ export class InvalidIdTokenError extends ApplicationError { */ export class JwkError extends ApplicationError { constructor(message = 'Jwk has invalid shape') { - super(message) + super(message, undefined, ErrorCodes.SPCP_OIDC_JWK_SHAPE_INVALID) } } @@ -68,7 +68,7 @@ export class JwkError extends ApplicationError { */ export class MissingIdTokenError extends ApplicationError { constructor(message = 'Missing id token in tokenset') { - super(message) + super(message, undefined, ErrorCodes.SPCP_OIDC_MISSING_ID_TOKEN) } } @@ -77,7 +77,7 @@ export class MissingIdTokenError extends ApplicationError { */ export class VerificationKeyError extends ApplicationError { constructor(message = 'Verification key invalid') { - super(message) + super(message, undefined, ErrorCodes.SPCP_OIDC_INVALID_VERIFICATION_KEY) } } @@ -86,6 +86,6 @@ export class VerificationKeyError extends ApplicationError { */ export class ExchangeAuthTokenError extends ApplicationError { constructor(message = 'Exchange auth code for nric failed') { - super(message) + super(message, undefined, ErrorCodes.SPCP_OIDC_EXCHANGE_AUTH_TOKEN) } } diff --git a/src/app/modules/submission/email-submission/email-submission.errors.ts b/src/app/modules/submission/email-submission/email-submission.errors.ts index 8cc4c320f9..105d3e78a5 100644 --- a/src/app/modules/submission/email-submission/email-submission.errors.ts +++ b/src/app/modules/submission/email-submission/email-submission.errors.ts @@ -1,7 +1,7 @@ -import { ApplicationError } from '../../core/core.errors' +import { ApplicationError, ErrorCodes } from '../../core/core.errors' export class SubmissionHashError extends ApplicationError { constructor(message = 'Error occurred while attempting to hash submission') { - super(message) + super(message, undefined, ErrorCodes.EMAIL_SUBMISSION_HASH) } } diff --git a/src/app/modules/submission/encrypt-submission/encrypt-submission.errors.ts b/src/app/modules/submission/encrypt-submission/encrypt-submission.errors.ts index 28a3295fad..c4acd2e0a7 100644 --- a/src/app/modules/submission/encrypt-submission/encrypt-submission.errors.ts +++ b/src/app/modules/submission/encrypt-submission/encrypt-submission.errors.ts @@ -1,10 +1,10 @@ -import { ApplicationError } from '../../core/core.errors' +import { ApplicationError, ErrorCodes } from '../../core/core.errors' export class FormsgReqBodyExistsError extends ApplicationError { constructor( message = 'The formsg key already exists in request. Please check that you are not overwriting it.', ) { - super(message) + super(message, undefined, ErrorCodes.ENCRYPT_FORMSG_REQ_BODY_EXISTS) } } @@ -12,6 +12,6 @@ export class EncryptedPayloadExistsError extends ApplicationError { constructor( message = 'Encrypted payload already exists in req.formsg. Please check that you are not overwriting it.', ) { - super(message) + super(message, undefined, ErrorCodes.ENCRYPT_ENCRYPTED_PAYLOAD_EXISTS) } } diff --git a/src/app/modules/submission/receiver/receiver.errors.ts b/src/app/modules/submission/receiver/receiver.errors.ts index 2ebc31e8d2..0efa106cbe 100644 --- a/src/app/modules/submission/receiver/receiver.errors.ts +++ b/src/app/modules/submission/receiver/receiver.errors.ts @@ -1,11 +1,11 @@ -import { ApplicationError } from '../../core/core.errors' +import { ApplicationError, ErrorCodes } from '../../core/core.errors' /** * Error in headers passed to Busboy constructor */ export class InitialiseMultipartReceiverError extends ApplicationError { constructor(message = 'Error while initialising multipart receiver') { - super(message) + super(message, undefined, ErrorCodes.RECEIVER_INITIALISE_MULTIPART_RECEIVER) } } @@ -14,7 +14,7 @@ export class InitialiseMultipartReceiverError extends ApplicationError { */ export class MultipartContentLimitError extends ApplicationError { constructor(message = 'Multipart content size limit exceeded') { - super(message) + super(message, undefined, ErrorCodes.RECEIVER_MULTIPART_CONTENT_LIMIT) } } @@ -23,12 +23,12 @@ export class MultipartContentLimitError extends ApplicationError { */ export class MultipartContentParsingError extends ApplicationError { constructor(message = 'Could not parse multipart form content') { - super(message) + super(message, undefined, ErrorCodes.RECEIVER_MULTIPART_CONTENT_PARSING) } } export class MultipartError extends ApplicationError { constructor(message = 'Error while receiving multipart content') { - super(message) + super(message, undefined, ErrorCodes.RECEIVER_MULTIPART_ERROR) } } diff --git a/src/app/modules/submission/submission.errors.ts b/src/app/modules/submission/submission.errors.ts index fc3be556ef..53fce4dae4 100644 --- a/src/app/modules/submission/submission.errors.ts +++ b/src/app/modules/submission/submission.errors.ts @@ -1,5 +1,5 @@ import { FormResponseMode } from '../../../../shared/types' -import { ApplicationError } from '../core/core.errors' +import { ApplicationError, ErrorCodes } from '../core/core.errors' /** * A custom error class thrown by the submission controllers @@ -7,25 +7,25 @@ import { ApplicationError } from '../core/core.errors' */ export class ConflictError extends ApplicationError { constructor(message: string, meta?: unknown) { - super(message, meta) + super(message, meta, ErrorCodes.SUBMISSION_CONFLICT) } } export class SubmissionNotFoundError extends ApplicationError { constructor(message = 'Submission not found for given ID') { - super(message) + super(message, undefined, ErrorCodes.SUBMISSION_NOT_FOUND) } } export class PendingSubmissionNotFoundError extends ApplicationError { constructor(message = 'Pending submission not found for given ID') { - super(message) + super(message, undefined, ErrorCodes.SUBMISSION_PENDING_NOT_FOUND) } } export class InvalidSubmissionTypeError extends ApplicationError { constructor(message = 'Unexpected submission type encountered.') { - super(message) + super(message, undefined, ErrorCodes.SUBMISSION_INVALID_TYPE) } } @@ -34,7 +34,7 @@ export class InvalidSubmissionTypeError extends ApplicationError { */ export class InvalidEncodingError extends ApplicationError { constructor(message = 'Error with encoding.') { - super(message) + super(message, undefined, ErrorCodes.SUBMISSION_INVALID_ENCODING) } } @@ -43,7 +43,7 @@ export class InvalidEncodingError extends ApplicationError { */ export class ProcessingError extends ApplicationError { constructor(message = 'Error processing response.') { - super(message) + super(message, undefined, ErrorCodes.SUBMISSION_PROCESSING) } } @@ -52,7 +52,7 @@ export class ProcessingError extends ApplicationError { */ export class ValidateFieldError extends ApplicationError { constructor(message = 'Error validating field.', status = 400) { - super(message, status) + super(message, status, ErrorCodes.SUBMISSION_VALIDATE_FIELD) } } @@ -61,7 +61,7 @@ export class ValidateFieldError extends ApplicationError { */ export class SendEmailConfirmationError extends ApplicationError { constructor(message = 'Error while sending confirmation emails') { - super(message) + super(message, undefined, ErrorCodes.SUBMISSION_SEND_EMAIL_CONFIRMATION) } } @@ -75,6 +75,8 @@ export class ResponseModeError extends ApplicationError { ) { super( `Attempted to submit ${formResponseMode} form to ${attemptedResponseMode} endpoint`, + undefined, + ErrorCodes.SUBMISSION_WRONG_RESPONSE_MODE, ) } } @@ -84,7 +86,7 @@ export class ResponseModeError extends ApplicationError { */ export class AttachmentTooLargeError extends ApplicationError { constructor(message = 'Attachment size limit exceeded') { - super(message) + super(message, undefined, ErrorCodes.SUBMISSION_ATTACHMENT_TOO_LARGE) } } @@ -93,7 +95,7 @@ export class AttachmentTooLargeError extends ApplicationError { */ export class InvalidFileExtensionError extends ApplicationError { constructor(message = 'Invalid file extension found in attachment') { - super(message) + super(message, undefined, ErrorCodes.SUBMISSION_INVALID_FILE_EXTENSION) } } @@ -101,7 +103,7 @@ export class SubmissionFailedError extends ApplicationError { constructor( message = 'The form submission could not be processed. Please try again.', ) { - super(message) + super(message, undefined, ErrorCodes.SUBMISSION_FAILED) } } @@ -109,7 +111,7 @@ export class InvalidFieldIdError extends ApplicationError { constructor( message = 'Invalid field id. Field id should be a valid MongoDB ObjectId.', ) { - super(message) + super(message, undefined, ErrorCodes.SUBMISSION_INVALID_FIELD_ID) } } @@ -117,31 +119,35 @@ export class AttachmentSizeLimitExceededError extends ApplicationError { constructor( message = `Total attachment size exceeds maximum file size limit. Please reduce your total attachment size and try again.`, ) { - super(message) + super( + message, + undefined, + ErrorCodes.SUBMISSION_ATTACHMENT_SIZE_LIMIT_EXCEEDED, + ) } } export class FeatureDisabledError extends ApplicationError { constructor(message = 'This feature is disabled.') { - super(message) + super(message, undefined, ErrorCodes.SUBMISSION_FEATURE_DISABLED) } } export class InvalidFileKeyError extends ApplicationError { constructor(message = 'Invalid file key. File keys should be valid UUIDs.') { - super(message) + super(message, undefined, ErrorCodes.SUBMISSION_INVALID_FILE_KEY) } } export class VirusScanFailedError extends ApplicationError { constructor(message = 'Virus scan failed. Please try again.') { - super(message) + super(message, undefined, ErrorCodes.SUBMISSION_VIRUS_SCAN_FAILED) } } export class JsonParseFailedError extends ApplicationError { constructor(message = 'JSON parsing failed. Please try again.') { - super(message) + super(message, undefined, ErrorCodes.SUBMISSION_JSON_PARSE_FAILED) } } @@ -149,13 +155,17 @@ export class DownloadCleanFileFailedError extends ApplicationError { constructor( message = 'Attempt to download clean file failed. Please try again.', ) { - super(message) + super(message, undefined, ErrorCodes.SUBMISSION_DOWNLOAD_CLEAN_FILE_FAILED) } } export class ParseVirusScannerLambdaPayloadError extends ApplicationError { constructor(message = 'Unexpected payload from virus scanning lambda.') { - super(message) + super( + message, + undefined, + ErrorCodes.SUBMISSION_PARSE_VIRUS_SCANNER_LAMBDA_PAYLOAD, + ) } } @@ -165,6 +175,8 @@ export class MaliciousFileDetectedError extends ApplicationError { `Your ${ filename ? `file "${filename}"` : 'attachments(s)' } has failed our virus scan. Try to create and upload it again.`, + undefined, + ErrorCodes.SUBMISSION_MALICIOUS_FILE_DETECTED, ) } } @@ -173,6 +185,15 @@ export class InvalidWorkflowTypeError extends ApplicationError { constructor( message = 'Invalid workflow type encountered. Please contact the form admin and try again later.', ) { - super(message) + super(message, undefined, ErrorCodes.SUBMISSION_INVALID_WORKFLOW_TYPE) + } +} + +/** + * Error thrown when attachment upload fails + */ +export class AttachmentUploadError extends ApplicationError { + constructor(message = 'Error while uploading encrypted attachments to S3') { + super(message, undefined, ErrorCodes.SUBMISSION_ATTACHMENT_UPLOAD) } } diff --git a/src/app/modules/submission/submission.service.ts b/src/app/modules/submission/submission.service.ts index db23ec3ca8..d704910dbb 100644 --- a/src/app/modules/submission/submission.service.ts +++ b/src/app/modules/submission/submission.service.ts @@ -51,7 +51,6 @@ import { transformMongoError, } from '../../utils/handle-mongo-error' import { - AttachmentUploadError, DatabaseDuplicateKeyError, DatabaseError, MalformedParametersError, @@ -64,6 +63,7 @@ import { PRESIGNED_ATTACHMENT_POST_EXPIRY_SECS } from './submission.constants' import { AttachmentSizeLimitExceededError, AttachmentTooLargeError, + AttachmentUploadError, DownloadCleanFileFailedError, InvalidFieldIdError, InvalidFileExtensionError, diff --git a/src/app/modules/submission/submission.utils.ts b/src/app/modules/submission/submission.utils.ts index 1cb5fc5698..f64a0e0fc1 100644 --- a/src/app/modules/submission/submission.utils.ts +++ b/src/app/modules/submission/submission.utils.ts @@ -65,7 +65,6 @@ import { import { CreatePresignedPostError } from '../../utils/aws-s3' import { genericMapRouteErrorTransform } from '../../utils/error' import { - AttachmentUploadError, DatabaseConflictError, DatabaseError, DatabasePayloadSizeError, @@ -112,6 +111,7 @@ import { ResponseFormattedForEmail } from './email-submission/email-submission.t import { AttachmentSizeLimitExceededError, AttachmentTooLargeError, + AttachmentUploadError, ConflictError, DownloadCleanFileFailedError, FeatureDisabledError, diff --git a/src/app/modules/user/user.errors.ts b/src/app/modules/user/user.errors.ts index 2dd756ac92..0b2d14614a 100644 --- a/src/app/modules/user/user.errors.ts +++ b/src/app/modules/user/user.errors.ts @@ -1,13 +1,13 @@ -import { ApplicationError } from '../core/core.errors' +import { ApplicationError, ErrorCodes } from '../core/core.errors' export class InvalidOtpError extends ApplicationError { constructor(message: string) { - super(message) + super(message, undefined, ErrorCodes.USER_INVALID_OTP) } } export class MissingUserError extends ApplicationError { constructor(message = 'User not found') { - super(message) + super(message, undefined, ErrorCodes.USER_MISSING) } } diff --git a/src/app/modules/verification/verification.errors.ts b/src/app/modules/verification/verification.errors.ts index 137dd33078..8e64717b73 100644 --- a/src/app/modules/verification/verification.errors.ts +++ b/src/app/modules/verification/verification.errors.ts @@ -1,11 +1,11 @@ -import { ApplicationError } from '../core/core.errors' +import { ApplicationError, ErrorCodes } from '../core/core.errors' /** * Transaction with given ID not found. */ export class TransactionNotFoundError extends ApplicationError { constructor(message = 'Transaction with given ID not found') { - super(message) + super(message, undefined, ErrorCodes.VERIFICATION_TRANSACTION_NOT_FOUND) } } @@ -14,7 +14,11 @@ export class TransactionNotFoundError extends ApplicationError { */ export class FieldNotFoundInTransactionError extends ApplicationError { constructor(message = 'Field with given ID not found in the transaction') { - super(message) + super( + message, + undefined, + ErrorCodes.VERIFICATION_FIELD_NOT_FOUND_IN_TRANSACTION, + ) } } @@ -23,7 +27,7 @@ export class FieldNotFoundInTransactionError extends ApplicationError { */ export class TransactionExpiredError extends ApplicationError { constructor(message = 'Transaction is expired') { - super(message) + super(message, undefined, ErrorCodes.VERIFICATION_TRANSACTION_EXPIRED) } } @@ -32,7 +36,7 @@ export class TransactionExpiredError extends ApplicationError { */ export class OtpExpiredError extends ApplicationError { constructor(message = 'OTP is expired') { - super(message) + super(message, undefined, ErrorCodes.VERIFICATION_OTP_EXPIRED) } } @@ -41,7 +45,7 @@ export class OtpExpiredError extends ApplicationError { */ export class MissingHashDataError extends ApplicationError { constructor(message = 'Field is missing information on hashed OTP') { - super(message) + super(message, undefined, ErrorCodes.VERIFICATION_MISSING_HASH_DATA) } } @@ -50,7 +54,7 @@ export class MissingHashDataError extends ApplicationError { */ export class OtpRetryExceededError extends ApplicationError { constructor(message = 'Too many invalid attempts to enter OTP') { - super(message) + super(message, undefined, ErrorCodes.VERIFICATION_OTP_RETRY_EXCEEDED) } } @@ -59,7 +63,7 @@ export class OtpRetryExceededError extends ApplicationError { */ export class WrongOtpError extends ApplicationError { constructor(message = 'Wrong OTP entered') { - super(message) + super(message, undefined, ErrorCodes.VERIFICATION_WRONG_OTP) } } @@ -68,7 +72,7 @@ export class WrongOtpError extends ApplicationError { */ export class WaitForOtpError extends ApplicationError { constructor(message = 'OTP requested too soon after previous OTP') { - super(message) + super(message, undefined, ErrorCodes.VERIFICATION_WAIT_FOR_OTP) } } @@ -77,7 +81,11 @@ export class WaitForOtpError extends ApplicationError { */ export class OtpRequestCountExceededError extends ApplicationError { constructor(message = 'Max OTP request count exceeded') { - super(message) + super( + message, + undefined, + ErrorCodes.VERIFICATION_OTP_REQUEST_COUNT_EXCEEDED, + ) } } @@ -88,6 +96,8 @@ export class NonVerifiedFieldTypeError extends ApplicationError { constructor(unsupportedFieldType: string) { super( `Unsupported field type for OTP verification: ${unsupportedFieldType}`, + undefined, + ErrorCodes.VERIFICATION_NON_VERIFIED_FIELD_TYPE, ) } } @@ -99,7 +109,7 @@ export class SmsLimitExceededError extends ApplicationError { constructor( message = 'You have exceeded the free sms limit. Please refresh and try again.', ) { - super(message) + super(message, undefined, ErrorCodes.VERIFICATION_SMS_LIMIT_EXCEEDED) } } @@ -110,6 +120,6 @@ export class OtpRequestError extends ApplicationError { constructor( message = 'Please ensure that the form you are trying to request OTP for has the feature enabled.', ) { - super(message) + super(message, undefined, ErrorCodes.VERIFICATION_OTP_REQUEST_ERROR) } } diff --git a/src/app/modules/verified-content/verified-content.errors.ts b/src/app/modules/verified-content/verified-content.errors.ts index df44fad3b9..b3316c6da2 100644 --- a/src/app/modules/verified-content/verified-content.errors.ts +++ b/src/app/modules/verified-content/verified-content.errors.ts @@ -1,11 +1,11 @@ -import { ApplicationError } from '../core/core.errors' +import { ApplicationError, ErrorCodes } from '../core/core.errors' /** * Verified content has the wrong shape */ export class MalformedVerifiedContentError extends ApplicationError { constructor(message = 'Verified content is malformed') { - super(message) + super(message, undefined, ErrorCodes.VERIFIED_CONTENT_MALFORMED) } } @@ -14,6 +14,6 @@ export class MalformedVerifiedContentError extends ApplicationError { */ export class EncryptVerifiedContentError extends ApplicationError { constructor(message = 'Failed to encrypt verified content') { - super(message) + super(message, undefined, ErrorCodes.VERIFIED_CONTENT_ENCRYPT_FAILURE) } } diff --git a/src/app/modules/webhook/webhook.errors.ts b/src/app/modules/webhook/webhook.errors.ts index 6ecc52f3d7..826aaeb0fd 100644 --- a/src/app/modules/webhook/webhook.errors.ts +++ b/src/app/modules/webhook/webhook.errors.ts @@ -1,6 +1,6 @@ import { AxiosError } from 'axios' -import { ApplicationError } from '../core/core.errors' +import { ApplicationError, ErrorCodes } from '../core/core.errors' /** * A custom error class thrown by the webhook server controller @@ -8,7 +8,7 @@ import { ApplicationError } from '../core/core.errors' */ export class WebhookValidationError extends ApplicationError { constructor(message = 'Webhook URL is non-HTTPS or points to private IP') { - super(message) + super(message, undefined, ErrorCodes.WEBHOOK_VALIDATION) } } @@ -21,7 +21,11 @@ export class WebhookFailedWithPresignedUrlGenerationError extends ApplicationErr } constructor(error: unknown, message = 'Presigned Url Generation failed') { - super(message) + super( + message, + undefined, + ErrorCodes.WEBHOOK_FAILED_WITH_PRESIGNED_URL_GENERATION, + ) this.meta = { originalError: error } } } @@ -35,7 +39,7 @@ export class WebhookFailedWithUnknownError extends ApplicationError { } constructor(error: unknown, message = 'Webhook POST failed') { - super(message) + super(message, undefined, ErrorCodes.WEBHOOK_FAILED_WITH_UNKNOWN_ERROR) this.meta = { originalError: error } } } @@ -47,9 +51,8 @@ export class WebhookFailedWithAxiosError extends ApplicationError { meta: { originalError: AxiosError } - constructor(error: AxiosError, message = 'Webhook POST failed') { - super(message) + super(message, undefined, ErrorCodes.WEBHOOK_FAILED_WITH_AXIOS_ERROR) this.meta = { originalError: error } } } @@ -66,7 +69,7 @@ export class WebhookQueueMessageParsingError extends ApplicationError { error: unknown, message = 'Unable to parse body of webhook queue message', ) { - super(message) + super(message, undefined, ErrorCodes.WEBHOOK_QUEUE_MESSAGE_PARSING_ERROR) this.meta = { originalError: error } } } @@ -76,7 +79,7 @@ export class WebhookQueueMessageParsingError extends ApplicationError { */ export class WebhookNoMoreRetriesError extends ApplicationError { constructor(message = 'Maximum retries exceeded for webhook') { - super(message) + super(message, undefined, ErrorCodes.WEBHOOK_NO_MORE_RETRIES) } } @@ -85,7 +88,7 @@ export class WebhookNoMoreRetriesError extends ApplicationError { */ export class WebhookPushToQueueError extends ApplicationError { constructor(message = 'Failed to push webhook to message queue') { - super(message) + super(message, undefined, ErrorCodes.WEBHOOK_PUSH_TO_QUEUE) } } @@ -104,7 +107,7 @@ export class WebhookRetriesNotEnabledError extends ApplicationError { isRetryEnabled: boolean, message = 'Unable to send webhook as form has no webhook URL or does not have retries enabled', ) { - super(message) + super(message, undefined, ErrorCodes.WEBHOOK_RETRIES_NOT_ENABLED) this.meta = { webhookUrl, isRetryEnabled, diff --git a/src/app/modules/workspace/workspace.errors.ts b/src/app/modules/workspace/workspace.errors.ts index 710f10a0f8..a2563c0e3e 100644 --- a/src/app/modules/workspace/workspace.errors.ts +++ b/src/app/modules/workspace/workspace.errors.ts @@ -1,8 +1,8 @@ -import { ApplicationError } from '../core/core.errors' +import { ApplicationError, ErrorCodes } from '../core/core.errors' export class WorkspaceNotFoundError extends ApplicationError { constructor(message = 'Workspace not found for the given user') { - super(message) + super(message, undefined, ErrorCodes.WORKSPACE_NOT_FOUND) } } @@ -10,6 +10,6 @@ export class ForbiddenWorkspaceError extends ApplicationError { constructor( message = "You don't have permissions to delete or update this workspace", ) { - super(message) + super(message, undefined, ErrorCodes.WORKSPACE_FORBIDDEN) } } diff --git a/src/app/services/captcha/captcha.errors.ts b/src/app/services/captcha/captcha.errors.ts index 1ea2ee2e57..73f21e8de7 100644 --- a/src/app/services/captcha/captcha.errors.ts +++ b/src/app/services/captcha/captcha.errors.ts @@ -1,11 +1,11 @@ -import { ApplicationError } from '../../modules/core/core.errors' +import { ApplicationError, ErrorCodes } from '../../modules/core/core.errors' /** * Error connecting to captcha server */ export class CaptchaConnectionError extends ApplicationError { constructor(message = 'Error while connecting to Captcha server') { - super(message) + super(message, undefined, ErrorCodes.CAPTCHA_CONNECTION) } } @@ -14,7 +14,7 @@ export class CaptchaConnectionError extends ApplicationError { */ export class VerifyCaptchaError extends ApplicationError { constructor(message = 'Incorrect Captcha response') { - super(message) + super(message, undefined, ErrorCodes.CAPTCHA_VERIFY) } } @@ -23,6 +23,6 @@ export class VerifyCaptchaError extends ApplicationError { */ export class MissingCaptchaError extends ApplicationError { constructor(message = 'Missing Captcha response') { - super(message) + super(message, undefined, ErrorCodes.CAPTCHA_MISSING) } } diff --git a/src/app/services/mail/mail.errors.ts b/src/app/services/mail/mail.errors.ts index 07250ed0a4..5153894f34 100644 --- a/src/app/services/mail/mail.errors.ts +++ b/src/app/services/mail/mail.errors.ts @@ -1,16 +1,16 @@ -import { ApplicationError } from '../../modules/core/core.errors' +import { ApplicationError, ErrorCodes } from '../../modules/core/core.errors' export class MailSendError extends ApplicationError { constructor( message = 'Error sending OTP. Please try again later and if the problem persists, contact us.', meta?: unknown, ) { - super(message, meta) + super(message, meta, ErrorCodes.MAIL_SEND_ERROR) } } export class MailGenerationError extends ApplicationError { constructor(message: string) { - super(message) + super(message, undefined, ErrorCodes.MAIL_GENERATION_ERROR) } } diff --git a/src/app/services/postman-sms/postman-sms.errors.ts b/src/app/services/postman-sms/postman-sms.errors.ts index 2f38ac4434..88cfd09d80 100644 --- a/src/app/services/postman-sms/postman-sms.errors.ts +++ b/src/app/services/postman-sms/postman-sms.errors.ts @@ -1,16 +1,16 @@ -import { ApplicationError } from '../../modules/core/core.errors' +import { ApplicationError, ErrorCodes } from '../../modules/core/core.errors' export class SmsSendError extends ApplicationError { constructor( message = 'Error sending OTP. Please try again later and if the problem persists, contact us.', meta?: unknown, ) { - super(message, meta) + super(message, meta, ErrorCodes.POSTMAN_SMS_SEND) } } export class InvalidNumberError extends ApplicationError { constructor(message = 'Please enter a valid phone number') { - super(message) + super(message, undefined, ErrorCodes.POSTMAN_INVALID_NUMBER) } } diff --git a/src/app/services/turnstile/turnstile.errors.ts b/src/app/services/turnstile/turnstile.errors.ts index 232bb1ae9f..e8ec4eebb8 100644 --- a/src/app/services/turnstile/turnstile.errors.ts +++ b/src/app/services/turnstile/turnstile.errors.ts @@ -1,11 +1,11 @@ -import { ApplicationError } from '../../modules/core/core.errors' +import { ApplicationError, ErrorCodes } from '../../modules/core/core.errors' /** * Error connecting to captcha server */ export class TurnstileConnectionError extends ApplicationError { constructor(message = 'Error while connecting to Turnstile server.') { - super(message) + super(message, undefined, ErrorCodes.TURNSTILE_CONNECTION) } } @@ -14,7 +14,7 @@ export class TurnstileConnectionError extends ApplicationError { */ export class VerifyTurnstileError extends ApplicationError { constructor(message = 'Incorrect Turnstile response.') { - super(message) + super(message, undefined, ErrorCodes.TURNSTILE_RESPONSE_ERROR) } } @@ -23,6 +23,6 @@ export class VerifyTurnstileError extends ApplicationError { */ export class MissingTurnstileError extends ApplicationError { constructor(message = 'Missing Turnstile response.') { - super(message) + super(message, undefined, ErrorCodes.TURNSTILE_MISSING) } } From 0e85520fa619b571a25db828a0356ee56fd166c9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jul 2024 15:14:00 +0800 Subject: [PATCH 12/13] fix(deps): bump helmet from 6.0.1 to 7.1.0 (#7242) * fix(deps): bump helmet from 6.0.1 to 7.1.0 Bumps [helmet](https://github.com/helmetjs/helmet) from 6.0.1 to 7.1.0. - [Changelog](https://github.com/helmetjs/helmet/blob/main/CHANGELOG.md) - [Commits](https://github.com/helmetjs/helmet/compare/v6.0.1...v7.1.0) --- updated-dependencies: - dependency-name: helmet dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * fix: typing on helmet --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Ken --- package-lock.json | 10 +++++----- package.json | 2 +- src/app/loaders/express/helmet.ts | 14 ++++++-------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 652ff4c506..f4b44de0a8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -53,7 +53,7 @@ "file-saver": "^2.0.5", "font-awesome": "4.7.0", "fp-ts": "^2.16.8", - "helmet": "^6.0.1", + "helmet": "^7.1.0", "hot-shots": "^10.0.0", "html-entities": "^2.5.2", "html-escaper": "^3.0.3", @@ -17168,11 +17168,11 @@ } }, "node_modules/helmet": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/helmet/-/helmet-6.0.1.tgz", - "integrity": "sha512-8wo+VdQhTMVBMCITYZaGTbE4lvlthelPYSvoyNvk4RECTmrVjMerp9RfUOQXZWLvCcAn1pKj7ZRxK4lI9Alrcw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-7.1.0.tgz", + "integrity": "sha512-g+HZqgfbpXdCkme/Cd/mZkV0aV3BZZZSugecH03kl38m/Kmdx8jKjBikpDj2cr+Iynv4KpYEviojNdTJActJAg==", "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/hexoid": { diff --git a/package.json b/package.json index 00525b527a..f7e82a7cea 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,7 @@ "file-saver": "^2.0.5", "font-awesome": "4.7.0", "fp-ts": "^2.16.8", - "helmet": "^6.0.1", + "helmet": "^7.1.0", "hot-shots": "^10.0.0", "html-entities": "^2.5.2", "html-escaper": "^3.0.3", diff --git a/src/app/loaders/express/helmet.ts b/src/app/loaders/express/helmet.ts index f9a6440b86..a81f6c96ac 100644 --- a/src/app/loaders/express/helmet.ts +++ b/src/app/loaders/express/helmet.ts @@ -1,6 +1,5 @@ import { RequestHandler } from 'express' import helmet from 'helmet' -import { ContentSecurityPolicyOptions } from 'helmet/dist/types/middlewares/content-security-policy' import config from '../../config/config' @@ -28,14 +27,13 @@ const helmetMiddlewares = () => { policy: 'strict-origin-when-cross-origin', }) - const cspCoreDirectives: ContentSecurityPolicyOptions['directives'] = - CSP_CORE_DIRECTIVES + const cspCoreDirectives = CSP_CORE_DIRECTIVES - const cspOptionalDirectives: ContentSecurityPolicyOptions['directives'] = {} - - // Remove upgradeInsecureRequest CSP header if config.isDev - // See https://github.com/helmetjs/helmet for use of null to disable default - if (config.isDev) cspOptionalDirectives.upgradeInsecureRequests = null + const cspOptionalDirectives = config.isDev + ? // Remove upgradeInsecureRequest CSP header if config.isDev + // See https://github.com/helmetjs/helmet for use of null to disable default + { upgradeInsecureRequests: null } + : null const contentSecurityPolicyMiddleware = helmet.contentSecurityPolicy({ useDefaults: true, From 8d773908d028ce0d4d1352887dfd4cd4c41551b2 Mon Sep 17 00:00:00 2001 From: g-tejas Date: Thu, 11 Jul 2024 15:23:51 +0800 Subject: [PATCH 13/13] chore: bump version to v6.134.0 --- CHANGELOG.md | 20 ++++++++++++++++++++ frontend/package-lock.json | 4 ++-- frontend/package.json | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cfa5fd30c..29409164f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,27 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [v6.134.0](https://github.com/opengovsg/FormSG/compare/v6.133.0...v6.134.0) + +- fix(deps): bump helmet from 6.0.1 to 7.1.0 [`#7242`](https://github.com/opengovsg/FormSG/pull/7242) +- feat(errors): revamp business logic error codes [`#7443`](https://github.com/opengovsg/FormSG/pull/7443) +- chore(deps-dev): bump lint-staged from 13.1.0 to 15.2.7 [`#7487`](https://github.com/opengovsg/FormSG/pull/7487) +- chore(deps-dev): bump supertest-session from 4.1.0 to 5.0.1 [`#7493`](https://github.com/opengovsg/FormSG/pull/7493) +- fix(deps): bump hot-shots from 9.3.0 to 10.0.0 [`#7490`](https://github.com/opengovsg/FormSG/pull/7490) +- fix: fix issue where attachments would fail locally [`#7496`](https://github.com/opengovsg/FormSG/pull/7496) +- feat(i18n): replace hardcoded string values for AdminFormNavbar [`#7456`](https://github.com/opengovsg/FormSG/pull/7456) +- build: merge release v6.133.0 to develop [`#7494`](https://github.com/opengovsg/FormSG/pull/7494) +- build: release v6.133.0 [`#7483`](https://github.com/opengovsg/FormSG/pull/7483) +- chore(deps-dev): bump @types/ejs from 3.1.1 to 3.1.5 [`#7492`](https://github.com/opengovsg/FormSG/pull/7492) +- chore(deps-dev): bump @types/sns-validator from 0.3.1 to 0.3.3 [`#7491`](https://github.com/opengovsg/FormSG/pull/7491) +- fix(deps): bump html-entities from 2.3.3 to 2.5.2 [`#7489`](https://github.com/opengovsg/FormSG/pull/7489) +- fix(deps): bump fp-ts from 2.13.1 to 2.16.8 [`#7485`](https://github.com/opengovsg/FormSG/pull/7485) +- chore(deps-dev): bump eslint-plugin-jest from 28.5.0 to 28.6.0 [`#7484`](https://github.com/opengovsg/FormSG/pull/7484) + #### [v6.133.0](https://github.com/opengovsg/FormSG/compare/v6.132.0...v6.133.0) +> 7 July 2024 + - feat(btn): frm 1723 internal flow postman [`#7343`](https://github.com/opengovsg/FormSG/pull/7343) - chore(deps): bump next and react-email in /react-email-preview [`#7375`](https://github.com/opengovsg/FormSG/pull/7375) - feat: rename placeholder for logic and mrf components [`#7482`](https://github.com/opengovsg/FormSG/pull/7482) @@ -24,6 +43,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - build: release v6.132.0 [`#7473`](https://github.com/opengovsg/FormSG/pull/7473) - add reddot to mrf workflow [`a044b80`](https://github.com/opengovsg/FormSG/commit/a044b805076b6ad14b44fd7baf7c2d73ba73bddc) - handle old last seen route [`d883952`](https://github.com/opengovsg/FormSG/commit/d883952df327928e92d007c46fae427851a5dc7a) +- chore: bump version to v6.133.0 [`0c7086b`](https://github.com/opengovsg/FormSG/commit/0c7086b46cf7e162dff1f3815c2104b7d32925f4) #### [v6.132.0](https://github.com/opengovsg/FormSG/compare/v6.131.0...v6.132.0) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 704a20cdfc..784ee281d3 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "form-frontend", - "version": "6.133.0", + "version": "6.134.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "form-frontend", - "version": "6.133.0", + "version": "6.134.0", "hasInstallScript": true, "dependencies": { "@chakra-ui/react": "^1.8.6", diff --git a/frontend/package.json b/frontend/package.json index 4d7bd36ac1..2a2e52bfc2 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "form-frontend", - "version": "6.133.0", + "version": "6.134.0", "homepage": ".", "private": true, "dependencies": { diff --git a/package-lock.json b/package-lock.json index f4b44de0a8..c19d51c770 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "FormSG", - "version": "6.133.0", + "version": "6.134.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "FormSG", - "version": "6.133.0", + "version": "6.134.0", "hasInstallScript": true, "dependencies": { "@aws-sdk/client-cloudwatch-logs": "^3.536.0", diff --git a/package.json b/package.json index f7e82a7cea..1515ccf825 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "FormSG", "description": "Form Manager for Government", - "version": "6.133.0", + "version": "6.134.0", "homepage": "https://form.gov.sg", "authors": [ "FormSG "