From 5030a06e816af7c05fd386942847865ad9be67a7 Mon Sep 17 00:00:00 2001 From: Ken Jin <119096102+kenjin-work@users.noreply.github.com> Date: Thu, 20 Jul 2023 17:16:12 +0800 Subject: [PATCH 01/10] fix: github warning about unused import (#6558) --- frontend/src/utils/fieldValidation.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/utils/fieldValidation.ts b/frontend/src/utils/fieldValidation.ts index 14b2bb6b76..5427a9c40d 100644 --- a/frontend/src/utils/fieldValidation.ts +++ b/frontend/src/utils/fieldValidation.ts @@ -48,7 +48,6 @@ import { import { DATE_PARSE_FORMAT } from '~templates/Field/Date/DateField' import { CheckboxFieldValues, - ChildrenCompoundFieldValues, SingleAnswerValue, VerifiableFieldValues, } from '~templates/Field/types' From 1ba72f75471e69a572a28580e517957479f0bfa6 Mon Sep 17 00:00:00 2001 From: Lin Huiqing <37061143+LinHuiqing@users.noreply.github.com> Date: Tue, 25 Jul 2023 10:32:46 +0800 Subject: [PATCH 02/10] feat: react router params validator for mongo ids (#6561) * feat: react router params validator for mongo ids - refactor: rename FORMID_REGEX as MONGODB_ID_REGEX * refactor: isInvalidMongoId check --- frontend/src/app/AppRouter.tsx | 39 ++++++++++++++++--- frontend/src/app/ParamIdValidator.tsx | 26 +++++++++++++ frontend/src/constants/routes.ts | 2 +- .../src/features/admin-form/common/queries.ts | 6 +-- .../public-form/PublicFormProvider.tsx | 4 +- frontend/src/features/public-form/queries.ts | 4 +- 6 files changed, 67 insertions(+), 14 deletions(-) create mode 100644 frontend/src/app/ParamIdValidator.tsx diff --git a/frontend/src/app/AppRouter.tsx b/frontend/src/app/AppRouter.tsx index b34717e646..9cab6884ec 100644 --- a/frontend/src/app/AppRouter.tsx +++ b/frontend/src/app/AppRouter.tsx @@ -40,6 +40,7 @@ import { FormPaymentPage } from '~features/public-form/components/FormPaymentPag import { BillingPage } from '~features/user/billing' import { HashRouterElement } from './HashRouterElement' +import { ParamIdValidator } from './ParamIdValidator' import { PrivateElement } from './PrivateElement' import { PublicElement } from './PublicElement' @@ -109,20 +110,38 @@ export const AppRouter = (): JSX.Element => { } />} + element={ + } />} + /> + } /> } />} + element={ + } /> + } + /> + } /> } />} + element={ + } />} + /> + } /> } />} + element={ + } />} + /> + } > } /> }> @@ -147,11 +166,19 @@ export const AppRouter = (): JSX.Element => { } />} + element={ + } />} + /> + } /> } />} + element={ + } />} + /> + } /> } /> diff --git a/frontend/src/app/ParamIdValidator.tsx b/frontend/src/app/ParamIdValidator.tsx new file mode 100644 index 0000000000..34a381f61d --- /dev/null +++ b/frontend/src/app/ParamIdValidator.tsx @@ -0,0 +1,26 @@ +import { useParams } from 'react-router-dom' + +import { MONGODB_ID_REGEX } from '~constants/routes' + +import NotFoundErrorPage from '~pages/NotFoundError' + +interface ParamIdValidatorProps { + element: React.ReactElement +} + +export const ParamIdValidator = ({ element }: ParamIdValidatorProps) => { + const { formId, submissionId, paymentId } = useParams() + + const isInvalidMongoId = (id?: string) => id && !id.match(MONGODB_ID_REGEX) + + // Bootstrap route validation as suggested by React Router Docs: + // https://reactrouter.com/en/main/start/faq#what-happened-to-regexp-routes-paths + if ( + isInvalidMongoId(formId) || + isInvalidMongoId(submissionId) || + isInvalidMongoId(paymentId) + ) + return + + return element +} diff --git a/frontend/src/constants/routes.ts b/frontend/src/constants/routes.ts index 7c56f70e51..24e9ef6577 100644 --- a/frontend/src/constants/routes.ts +++ b/frontend/src/constants/routes.ts @@ -13,7 +13,7 @@ export const BILLING_ROUTE = '/billing' // the regex in PublicFormPage. export const PUBLICFORM_ROUTE = '/:formId' export const USE_TEMPLATE_REDIRECT_SUBROUTE = 'use-template' -export const FORMID_REGEX = /^([a-fA-F0-9]{24})$/ +export const MONGODB_ID_REGEX = /^([a-fA-F0-9]{24})$/ export const ADMINFORM_ROUTE = '/admin/form' /** Build tab has no subroute, its the index admin form route. */ diff --git a/frontend/src/features/admin-form/common/queries.ts b/frontend/src/features/admin-form/common/queries.ts index fb0db5c058..37d638b91f 100644 --- a/frontend/src/features/admin-form/common/queries.ts +++ b/frontend/src/features/admin-form/common/queries.ts @@ -6,7 +6,7 @@ import { AdminFormDto, PreviewFormViewDto } from '~shared/types/form/form' import { ApiError } from '~typings/core' -import { FORMID_REGEX } from '~constants/routes' +import { MONGODB_ID_REGEX } from '~constants/routes' import { useUser } from '~features/user/queries' @@ -134,7 +134,7 @@ export const usePreviewForm = ( { // Treat preview form as static on load. staleTime: Infinity, - enabled: FORMID_REGEX.test(formId) && enabled, + enabled: MONGODB_ID_REGEX.test(formId) && enabled, }, ) } @@ -150,7 +150,7 @@ export const useFormTemplate = ( { // Treat preview form as static on load. staleTime: Infinity, - enabled: FORMID_REGEX.test(formId) && enabled, + enabled: MONGODB_ID_REGEX.test(formId) && enabled, }, ) } diff --git a/frontend/src/features/public-form/PublicFormProvider.tsx b/frontend/src/features/public-form/PublicFormProvider.tsx index 4ec473826a..545020a875 100644 --- a/frontend/src/features/public-form/PublicFormProvider.tsx +++ b/frontend/src/features/public-form/PublicFormProvider.tsx @@ -28,7 +28,7 @@ import { PublicFormDto, } from '~shared/types/form' -import { FORMID_REGEX } from '~constants/routes' +import { MONGODB_ID_REGEX } from '~constants/routes' import { useBrowserStm } from '~hooks/payments' import { useTimeout } from '~hooks/useTimeout' import { useToast } from '~hooks/useToast' @@ -93,7 +93,7 @@ export function useCommonFormProvider(formId: string) { return vfnTransaction.transactionId }, [createTransactionMutation, vfnTransaction]) - const isNotFormId = useMemo(() => !FORMID_REGEX.test(formId), [formId]) + const isNotFormId = useMemo(() => !MONGODB_ID_REGEX.test(formId), [formId]) const expiryInMs = useMemo(() => { if (!vfnTransaction?.expireAt) return null diff --git a/frontend/src/features/public-form/queries.ts b/frontend/src/features/public-form/queries.ts index c246ce9f43..c6f5bb2dc3 100644 --- a/frontend/src/features/public-form/queries.ts +++ b/frontend/src/features/public-form/queries.ts @@ -4,7 +4,7 @@ import { PublicFormViewDto } from '~shared/types/form/form' import { ApiError } from '~typings/core' -import { FORMID_REGEX } from '~constants/routes' +import { MONGODB_ID_REGEX } from '~constants/routes' import { getPublicFormView } from './PublicFormService' @@ -26,7 +26,7 @@ export const usePublicFormView = ( { // Treat form as static on load. staleTime: Infinity, - enabled: FORMID_REGEX.test(formId) && enabled, + enabled: MONGODB_ID_REGEX.test(formId) && enabled, }, ) } From 9afa247a7a64c3845abdc94b3c8c21eed2e13448 Mon Sep 17 00:00:00 2001 From: Ken Jin <119096102+kenjin-work@users.noreply.github.com> Date: Tue, 25 Jul 2023 11:31:40 +0800 Subject: [PATCH 03/10] fix: subtle bugs in MyInfo Child and UI copyedits (#6562) --- .../EditMyInfoChildren/EditMyInfoChildren.tsx | 4 +- .../create/builder-and-design/constants.ts | 3 ++ .../ChildrenCompoundField.tsx | 43 +++++++++++-------- shared/constants/field/myinfo/index.ts | 2 +- src/app/modules/myinfo/myinfo.util.ts | 3 ++ 5 files changed, 32 insertions(+), 23 deletions(-) diff --git a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditMyInfoChildren/EditMyInfoChildren.tsx b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditMyInfoChildren/EditMyInfoChildren.tsx index 22e674c320..9706cb9a69 100644 --- a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditMyInfoChildren/EditMyInfoChildren.tsx +++ b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditMyInfoChildren/EditMyInfoChildren.tsx @@ -97,9 +97,7 @@ export const EditMyInfoChildren = ({ - - Collect the following child information - + Collect the following child data e !== MyInfoChildAttributes.ChildName) + // TODO awaiting approval from MyInfo to get child vaccination status. + // Disabling in the frontend for now. + .filter((e) => e !== MyInfoChildAttributes.ChildVaxxStatus) .map((value) => { return { value, diff --git a/frontend/src/templates/Field/ChildrenCompound/ChildrenCompoundField.tsx b/frontend/src/templates/Field/ChildrenCompound/ChildrenCompoundField.tsx index e331d9cd8e..b7a195d8ea 100644 --- a/frontend/src/templates/Field/ChildrenCompound/ChildrenCompoundField.tsx +++ b/frontend/src/templates/Field/ChildrenCompound/ChildrenCompoundField.tsx @@ -124,24 +124,27 @@ export const ChildrenCompoundField = ({ aria-describedby={`children-desc-${schema._id}`} aria-labelledby={`${schema._id}-label`} > - - {fields.map((field, currChildBodyIdx) => ( - - ))} - + <> + + + {fields.map((field, currChildBodyIdx) => ( + + ))} + + {schema.allowMultiple ? (