diff --git a/.ebextensions/env-file-creation.config b/.ebextensions/env-file-creation.config index 2d6b460e14..e31140a634 100644 --- a/.ebextensions/env-file-creation.config +++ b/.ebextensions/env-file-creation.config @@ -46,6 +46,7 @@ files: aws ssm get-parameter --name "${ENV_TYPE}-ndi" --with-decryption --region $AWS_REGION | jq -r '.Parameter.Value' >> $TARGET_DIR/.env aws ssm get-parameter --name "${ENV_TYPE}-verified-fields" --with-decryption --region $AWS_REGION | jq -r '.Parameter.Value' >> $TARGET_DIR/.env aws ssm get-parameter --name "${ENV_TYPE}-webhook-verified-content" --with-decryption --region $AWS_REGION | jq -r '.Parameter.Value' >> $TARGET_DIR/.env + aws ssm get-parameter --name "${ENV_TYPE}-wogaa" --with-decryption --region $AWS_REGION | jq -r '.Parameter.Value' >> $TARGET_DIR/.env aws ssm get-parameter --name "${ENV_SITE_NAME}-sgid" --with-decryption --region $AWS_REGION | jq -r '.Parameter.Value' >> $TARGET_DIR/.env aws ssm get-parameter --name "${ENV_SITE_NAME}-payment" --with-decryption --region $AWS_REGION | jq -r '.Parameter.Value' >> $TARGET_DIR/.env aws ssm get-parameter --name "${ENV_SITE_NAME}-cron-payment" --with-decryption --region $AWS_REGION | jq -r '.Parameter.Value' >> $TARGET_DIR/.env diff --git a/docker-compose.yml b/docker-compose.yml index 0dd47c6ca4..ffb6c0124f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -129,6 +129,11 @@ services: - GROWTHBOOK_CLIENT_KEY # env vars for virus scanner - VIRUS_SCANNER_LAMBDA_FUNCTION_NAME=function + - WOGAA_SECRET_KEY + - WOGAA_START_ENDPOINT + - WOGAA_SUBMIT_ENDPOINT + - WOGAA_FEEDBACK_ENDPOINT + mockpass: build: https://github.com/opengovsg/mockpass.git#v4.0.4 diff --git a/frontend/src/features/admin-form/common/components/PreviewFormBanner/PreviewFormBanner.tsx b/frontend/src/features/admin-form/common/components/PreviewFormBanner/PreviewFormBanner.tsx index 53991ee8fe..966aac2551 100644 --- a/frontend/src/features/admin-form/common/components/PreviewFormBanner/PreviewFormBanner.tsx +++ b/frontend/src/features/admin-form/common/components/PreviewFormBanner/PreviewFormBanner.tsx @@ -47,7 +47,7 @@ interface PreviewFormBannerProps { const textProps: TextProps = { textStyle: 'body-2', color: 'white', - ml: '2rem', + mx: '2rem', mt: '0.5rem', mb: '0.5rem', } diff --git a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditEmail/EditEmail.tsx b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditEmail/EditEmail.tsx index dd456dfb0a..dfa29143a8 100644 --- a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditEmail/EditEmail.tsx +++ b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditEmail/EditEmail.tsx @@ -139,6 +139,18 @@ export const EditEmail = ({ field }: EditEmailProps): JSX.Element => { } }, [isPdfResponseEnabled]) + // vfn is not supported on MRF + const isToggleVfnDisabled = useMemo( + () => form?.responseMode === FormResponseMode.Multirespondent, + [form], + ) + + // email confirmation is not supported on MRF + const isToggleEmailConfirmationDisabled = useMemo( + () => form?.responseMode === FormResponseMode.Multirespondent, + [form], + ) + return ( @@ -158,7 +170,7 @@ export const EditEmail = ({ field }: EditEmailProps): JSX.Element => { - + { )} - + { const { data: freeSmsCount } = useFreeSmsQuota() const isToggleVfnDisabled = useMemo(() => { + // vfn is not supported on MRF + if (form?.responseMode === FormResponseMode.Multirespondent) return true if (!freeSmsCount) return true return ( !field.isVerifiable && !hasTwilioCredentials && freeSmsCount.freeSmsCounts >= freeSmsCount.quota ) - }, [field.isVerifiable, freeSmsCount, hasTwilioCredentials]) + }, [ + field.isVerifiable, + freeSmsCount, + hasTwilioCredentials, + form?.responseMode, + ]) const smsCountsDisclosure = useDisclosure() diff --git a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/FieldListDrawer/field-panels/BasicFieldPanel.tsx b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/FieldListDrawer/field-panels/BasicFieldPanel.tsx index 0e9667fc1b..b3c75d58e0 100644 --- a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/FieldListDrawer/field-panels/BasicFieldPanel.tsx +++ b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/FieldListDrawer/field-panels/BasicFieldPanel.tsx @@ -1,6 +1,9 @@ import { Droppable } from 'react-beautiful-dnd' import { Box } from '@chakra-ui/react' +import { BasicField, FormResponseMode } from '~shared/types' + +import { useAdminForm } from '~features/admin-form/common/queries' import { BASIC_FIELDS_ORDERED, CREATE_FIELD_DROP_ID, @@ -13,20 +16,33 @@ import { FieldSection } from './FieldSection' export const BasicFieldPanel = () => { const { isLoading } = useCreateTabForm() + const { data: form } = useAdminForm() return ( {(provided) => ( - {BASIC_FIELDS_ORDERED.map((fieldType, index) => ( - - ))} + {BASIC_FIELDS_ORDERED.map((fieldType, index) => { + let shouldDisableField = isLoading + + // Attachment is not supported on MRF + if ( + fieldType === BasicField.Attachment && + form?.responseMode === FormResponseMode.Multirespondent + ) { + shouldDisableField = true + } + + return ( + + ) + })} {provided.placeholder} diff --git a/frontend/src/features/public-form/components/FormEndPage/FormEndPage.stories.tsx b/frontend/src/features/public-form/components/FormEndPage/FormEndPage.stories.tsx index e33db29525..c135214869 100644 --- a/frontend/src/features/public-form/components/FormEndPage/FormEndPage.stories.tsx +++ b/frontend/src/features/public-form/components/FormEndPage/FormEndPage.stories.tsx @@ -43,6 +43,8 @@ Default.args = { title: 'Thank you for your submission with some super long backstory about how important the submission is to them', paragraph: 'We will get back to you shortly.\n\nOnce again,\r\nthank you.', + paymentTitle: '', + paymentParagraph: '', }, submissionData: { id: 'mockSubmissionId', @@ -84,7 +86,7 @@ ColorThemeOrange.args = { export const FeedbackSubmitted = Template.bind({}) FeedbackSubmitted.args = { ...Default.args, - isFeedbackSubmitted: true, + isFeedbackSectionHidden: true, } export const Mobile = Template.bind({}) diff --git a/frontend/src/features/public-form/components/FormEndPage/FormEndPage.tsx b/frontend/src/features/public-form/components/FormEndPage/FormEndPage.tsx index 798dea40e8..c3eb632e64 100644 --- a/frontend/src/features/public-form/components/FormEndPage/FormEndPage.tsx +++ b/frontend/src/features/public-form/components/FormEndPage/FormEndPage.tsx @@ -13,13 +13,13 @@ export interface FormEndPageProps { endPage: FormDto['endPage'] submissionData: SubmissionData handleSubmitFeedback: (inputs: FeedbackFormInput) => void - isFeedbackSubmitted: boolean + isFeedbackSectionHidden: boolean colorTheme: FormColorTheme } export const FormEndPage = ({ handleSubmitFeedback, - isFeedbackSubmitted, + isFeedbackSectionHidden, colorTheme, ...endPageProps }: FormEndPageProps): JSX.Element => { @@ -40,7 +40,7 @@ export const FormEndPage = ({ {...endPageProps} colorTheme={colorTheme} /> - {isFeedbackSubmitted ? null : ( + {isFeedbackSectionHidden ? null : ( { /> ) } + + const isFeedbackHidden = + // Feedback is not supported on MRF + form.responseMode === FormResponseMode.Multirespondent || + isFeedbackSubmitted + return ( { submissionData={submissionData} formTitle={form.title} endPage={form.endPage} - isFeedbackSubmitted={isFeedbackSubmitted} + isFeedbackSectionHidden={isFeedbackHidden} handleSubmitFeedback={handleSubmitFeedback} /> diff --git a/frontend/src/features/public-form/components/FormEndPage/components/PaymentEndPagePreview.tsx b/frontend/src/features/public-form/components/FormEndPage/components/PaymentEndPagePreview.tsx index 7daa3fb9d3..09a5dac02d 100644 --- a/frontend/src/features/public-form/components/FormEndPage/components/PaymentEndPagePreview.tsx +++ b/frontend/src/features/public-form/components/FormEndPage/components/PaymentEndPagePreview.tsx @@ -31,8 +31,9 @@ export const PaymentEndPagePreview = ({ {isFeedbackSubmitted ? null : ( diff --git a/frontend/src/features/public-form/components/FormPaymentPage/stripe/StripePaymentElement.tsx b/frontend/src/features/public-form/components/FormPaymentPage/stripe/StripePaymentElement.tsx index 8f5b491b8e..b90a493aa7 100644 --- a/frontend/src/features/public-form/components/FormPaymentPage/stripe/StripePaymentElement.tsx +++ b/frontend/src/features/public-form/components/FormPaymentPage/stripe/StripePaymentElement.tsx @@ -1,6 +1,6 @@ import { useMemo, useState } from 'react' import { useParams } from 'react-router-dom' -import { Box, Center, Container } from '@chakra-ui/react' +import { Box, Center, Container, Flex, Stack, Text } from '@chakra-ui/react' import { Elements, useStripe } from '@stripe/react-stripe-js' import { loadStripe } from '@stripe/stripe-js' @@ -11,6 +11,7 @@ import { } from '~shared/types' import InlineMessage from '~components/InlineMessage' +import { CopyButton } from '~templates/CopyButton' import { useEnv } from '~features/env/queries' @@ -155,9 +156,22 @@ const StripePaymentContainer = ({ {secretEnv === 'production' ? null : ( - Use '4242 4242 4242 4242' as your card number to test payments - on this form. Payments made on this form will only show in - test mode in Stripe. + + + Make a test payment with the card number below! Payments + made on this form will only show in test mode in Stripe. + + + 4242 4242 4242 4242 + + + + + )} diff --git a/serverless/virus-scanner/src/__tests/index.spec.ts b/serverless/virus-scanner/src/__tests/index.spec.ts index 6b1911a2bb..c1826e48e5 100644 --- a/serverless/virus-scanner/src/__tests/index.spec.ts +++ b/serverless/virus-scanner/src/__tests/index.spec.ts @@ -97,7 +97,7 @@ describe('handler', () => { expect(mockLoggerWarn).toHaveBeenCalledWith( expect.objectContaining({ message: 'File not found', - error: new Error('File not found'), + err: new Error('File not found'), quarantineFileKey: mockUUID, }), ) @@ -175,7 +175,7 @@ describe('handler', () => { expect(mockLoggerError).toHaveBeenCalledWith( expect.objectContaining({ message: 'Failed to scan file', - error: new Error('Failed to scan file'), + err: new Error('Failed to scan file'), quarantineFileKey: mockUUID, }), ) @@ -248,7 +248,7 @@ describe('handler', () => { expect(mockLoggerError).toHaveBeenCalledWith( expect.objectContaining({ message: 'Failed to move file to clean bucket', - error: new Error('Failed to move file'), + err: new Error('Failed to move file'), bucket: 'local-virus-scanner-quarantine-bucket', key: mockUUID, }), diff --git a/serverless/virus-scanner/src/__tests/s3.service.spec.ts b/serverless/virus-scanner/src/__tests/s3.service.spec.ts index c8bbee5c7f..958fdfbaf0 100644 --- a/serverless/virus-scanner/src/__tests/s3.service.spec.ts +++ b/serverless/virus-scanner/src/__tests/s3.service.spec.ts @@ -145,7 +145,7 @@ describe('S3Service', () => { expect.objectContaining({ bucketName: 'bucketName', objectKey: 'objectKey', - error: new Error('Body is empty'), + err: new Error('Body is empty'), }), 'Failed to get object from s3', ) @@ -172,7 +172,7 @@ describe('S3Service', () => { expect.objectContaining({ bucketName: 'bucketName', objectKey: 'objectKey', - error: new Error('VersionId is empty'), + err: new Error('VersionId is empty'), }), 'Failed to get object from s3', ) diff --git a/serverless/virus-scanner/src/index.ts b/serverless/virus-scanner/src/index.ts index a31fc37280..6f55c325e8 100644 --- a/serverless/virus-scanner/src/index.ts +++ b/serverless/virus-scanner/src/index.ts @@ -66,10 +66,10 @@ export const handler = async ( bucketName: quarantineBucket, objectKey: quarantineFileKey, }) - } catch (error) { + } catch (err) { logger.warn({ message: 'File not found', - error, + err, quarantineFileKey, }) return { @@ -88,10 +88,10 @@ export const handler = async ( let scanResult try { scanResult = await scanFileStream(body) - } catch (error) { + } catch (err) { logger.error({ message: 'Failed to scan file', - error, + err, quarantineFileKey, }) return { @@ -122,11 +122,11 @@ export const handler = async ( objectKey: quarantineFileKey, versionId, }) - } catch (error) { + } catch (err) { // Log but do not halt execution as we still want to return 400 for malicious file logger.error({ message: 'Failed to delete file from quarantine bucket', - error, + err, key: quarantineFileKey, }) } @@ -158,10 +158,10 @@ export const handler = async ( destinationBucketName: cleanBucket, destinationObjectKey: cleanFileKey, }) - } catch (error) { + } catch (err) { logger.error({ message: 'Failed to move file to clean bucket', - error, + err, bucket: quarantineBucket, key: quarantineFileKey, }) diff --git a/serverless/virus-scanner/src/s3.service.ts b/serverless/virus-scanner/src/s3.service.ts index 1dd6c78f0f..9ec6fb5ed8 100644 --- a/serverless/virus-scanner/src/s3.service.ts +++ b/serverless/virus-scanner/src/s3.service.ts @@ -72,17 +72,17 @@ export class S3Service { ) return { body, versionId } as GetS3FileStreamResult - } catch (error) { + } catch (err) { this.logger.error( { bucketName, objectKey, - error, + err, }, 'Failed to get object from s3', ) - throw error + throw err } } @@ -112,17 +112,17 @@ export class S3Service { }, 'Deleted document from s3', ) - } catch (error) { + } catch (err) { this.logger.error( { bucketName, objectKey, - error, + err, }, 'Failed to delete object from s3', ) - throw error + throw err } } @@ -189,7 +189,7 @@ export class S3Service { ) return VersionId - } catch (error) { + } catch (err) { this.logger.error( { sourceBucketName, @@ -197,12 +197,12 @@ export class S3Service { sourceObjectVersionId, destinationBucketName, destinationObjectKey, - error, + err, }, 'Failed to move object in s3', ) - throw error + throw err } } } diff --git a/shared/constants/countryRegion.ts b/shared/constants/countryRegion.ts index 393f342fc8..66da81c73e 100644 --- a/shared/constants/countryRegion.ts +++ b/shared/constants/countryRegion.ts @@ -5,7 +5,6 @@ export enum CountryRegion { American_Samoa = 'American Samoa', Andorra = 'Andorra', Angola = 'Angola', - Anguilla = 'Anguilla', Antigua = 'Antigua', Argentina = 'Argentina', Armenia = 'Armenia', diff --git a/shared/constants/field/myinfo/myinfo-countries.ts b/shared/constants/field/myinfo/myinfo-countries.ts index cc2e5efec6..d14bff865a 100644 --- a/shared/constants/field/myinfo/myinfo-countries.ts +++ b/shared/constants/field/myinfo/myinfo-countries.ts @@ -5,7 +5,6 @@ export const myInfoCountries = [ 'AMERICAN SAMOA', 'ANDORRA', 'ANGOLA', - 'ANGUILLA', 'ANTIGUA', 'ARGENTINA', 'ARMENIA', diff --git a/src/app/config/config.ts b/src/app/config/config.ts index 524f95ad72..f242b94ec4 100644 --- a/src/app/config/config.ts +++ b/src/app/config/config.ts @@ -97,10 +97,16 @@ const s3 = new aws.S3({ // using aws-sdk v3 (FRM-993) const virusScannerLambda = new Lambda({ region: basicVars.awsConfig.region, - // Endpoint is set for development mode to point to the separate docker container running the lambda function. + // For dev mode or where specified, endpoint is set to point to the separate docker container running the lambda function. // host.docker.internal is a special DNS name which resolves to the internal IP address used by the host. // Reference: https://docs.docker.com/desktop/networking/#i-want-to-connect-from-a-container-to-a-service-on-the-host - ...(isDev ? { endpoint: 'http://host.docker.internal:9999' } : undefined), + ...(isDev || basicVars.awsConfig.virusScannerLambdaEndpoint + ? { + endpoint: + basicVars.awsConfig.virusScannerLambdaEndpoint || + 'http://host.docker.internal:9999', + } + : undefined), }) const awsConfig: AwsConfig = { diff --git a/src/app/config/features/wogaa.ts b/src/app/config/features/wogaa.ts new file mode 100644 index 0000000000..e5777ed153 --- /dev/null +++ b/src/app/config/features/wogaa.ts @@ -0,0 +1,39 @@ +import convict, { Schema } from 'convict' + +export interface IWogaa { + wogaaSecretKey: string + wogaaStartEndpoint: string + wogaaSubmitEndpoint: string + wogaaFeedbackEndpoint: string +} + +const wogaaSchema: Schema = { + wogaaSecretKey: { + doc: 'Wogaa shared secret key', + format: String, + default: '', + env: 'WOGAA_SECRET_KEY', + }, + wogaaStartEndpoint: { + doc: 'Wogaa endpoint when a form is loaded', + format: String, + default: '', + env: 'WOGAA_START_ENDPOINT', + }, + wogaaSubmitEndpoint: { + doc: 'Wogaa endpoint when a form is loaded', + format: String, + default: '', + env: 'WOGAA_SUBMIT_ENDPOINT', + }, + wogaaFeedbackEndpoint: { + doc: 'Wogaa endpoint when a form is loaded', + format: String, + default: '', + env: 'WOGAA_FEEDBACK_ENDPOINT', + }, +} + +export const wogaaConfig = convict(wogaaSchema) + .validate({ allowed: 'strict' }) + .getProperties() diff --git a/src/app/config/schema.ts b/src/app/config/schema.ts index e17f25d980..ee6361f134 100644 --- a/src/app/config/schema.ts +++ b/src/app/config/schema.ts @@ -297,6 +297,12 @@ export const optionalVarsSchema: Schema = { default: '', env: 'VIRUS_SCANNER_LAMBDA_FUNCTION_NAME', }, + virusScannerLambdaEndpoint: { + doc: 'Endpoint address for virus scanner lambda function. Specify this if the lambda is hosted neither on AWS nor your local dev environment.', + format: String, + default: '', + env: 'VIRUS_SCANNER_LAMBDA_ENDPOINT', + }, }, core: { port: { diff --git a/src/app/modules/wogaa/wogaa.controller.ts b/src/app/modules/wogaa/wogaa.controller.ts new file mode 100644 index 0000000000..1d755fcaf3 --- /dev/null +++ b/src/app/modules/wogaa/wogaa.controller.ts @@ -0,0 +1,160 @@ +import Axios from 'axios' +import * as crypto from 'crypto' +import uuidGen from 'uuid-by-string' + +import { wogaaConfig } from '../../config/features/wogaa' +import { createLoggerWithLabel } from '../../config/logger' +import { ControllerHandler } from '../core/core.types' + +const logger = createLoggerWithLabel(module) +const generateSignature = (payload: Record) => { + const signature = crypto + .createHmac('sha256', wogaaConfig.wogaaSecretKey) + .update(JSON.stringify(payload)) + .digest('hex') + return signature +} + +const isConfigValid = () => { + if (!wogaaConfig.wogaaSecretKey) { + return false + } + if (!wogaaConfig.wogaaStartEndpoint) { + return false + } + if (!wogaaConfig.wogaaSubmitEndpoint) { + return false + } + if (!wogaaConfig.wogaaFeedbackEndpoint) { + return false + } + + return true +} + +export const handleSubmit: ControllerHandler<{ formId: string }> = async ( + req, + _, + next, +) => { + const { formId } = req.params + + if (!req.sessionID || !formId || !isConfigValid()) { + return next() + } + + const logMeta = { + action: 'wogaaHandleSubmit', + formId, + } + + const payload = { + formSgId: formId, + transactionId: uuidGen(req.sessionID), + } + // fire and forget + void Axios.post(wogaaConfig.wogaaSubmitEndpoint, payload, { + headers: { + 'WOGAA-Signature': generateSignature(payload), + }, + }) + .then(() => { + logger.info({ + message: 'Successfully sent WOGAA submit endpoint', + meta: logMeta, + }) + }) + .catch((e) => { + logger.warn({ + message: 'Error sending to WOGAA submit endpoint', + meta: { ...logMeta, wogaaRespError: e }, + }) + }) + + return next() +} + +export const handleFormView: ControllerHandler<{ formId: string }> = async ( + req, + _, + next, +) => { + const { formId } = req.params + + if (!req.sessionID || !formId || !isConfigValid()) { + return next() + } + + const logMeta = { + action: 'wogaaHandleFormView', + formId, + } + const payload = { + formSgId: formId, + pageUrl: formId, + transactionId: uuidGen(req.sessionID), + } + void Axios.post(wogaaConfig.wogaaStartEndpoint, payload, { + headers: { + 'WOGAA-Signature': generateSignature(payload), + }, + }) + .then(() => { + logger.info({ + message: 'Successfully sent WOGAA load form endpoint', + meta: logMeta, + }) + }) + .catch((e) => { + logger.warn({ + message: 'Error sending to WOGAA load form endpoint', + meta: { ...logMeta, wogaaRespError: e }, + }) + }) + + return next() +} + +export const handleFormFeedback: ControllerHandler< + { formId: string }, + unknown, + { rating: number; comment: string } +> = async (req, _, next) => { + const { formId } = req.params + const { rating, comment } = req.body + + if (!req.sessionID || !formId || !isConfigValid()) { + return next() + } + + const logMeta = { + action: 'wogaaHandleFormFeedback', + formId, + } + const payload = { + formSgId: formId, + transactionId: uuidGen(req.sessionID), + rating, + comment, + } + + void Axios.post(wogaaConfig.wogaaFeedbackEndpoint, payload, { + headers: { + 'WOGAA-Signature': generateSignature(payload), + }, + }) + .then(() => { + logger.info({ + message: 'Successfully sent WOGAA form feedback endpoint', + meta: logMeta, + }) + }) + .catch((e) => { + logger.warn({ + message: 'Error sending to WOGAA form feedback endpoint', + meta: { ...logMeta, wogaaRespError: e }, + }) + }) + + return next() +} diff --git a/src/app/routes/api/v3/forms/public-forms.feedback.routes.ts b/src/app/routes/api/v3/forms/public-forms.feedback.routes.ts index 432cc64a76..0be6bbd705 100644 --- a/src/app/routes/api/v3/forms/public-forms.feedback.routes.ts +++ b/src/app/routes/api/v3/forms/public-forms.feedback.routes.ts @@ -1,6 +1,7 @@ import { Router } from 'express' import * as FeedbackController from '../../../../modules/feedback/feedback.controller' +import * as WogaaController from '../../../../modules/wogaa/wogaa.controller' export const PublicFormsFeedbackRouter = Router() @@ -22,4 +23,7 @@ export const PublicFormsFeedbackRouter = Router() */ PublicFormsFeedbackRouter.route( '/:formId([a-fA-F0-9]{24})/submissions/:submissionId([a-fA-F0-9]{24})/feedback', -).post(FeedbackController.handleSubmitFormFeedback) +).post( + WogaaController.handleFormFeedback, + FeedbackController.handleSubmitFormFeedback, +) diff --git a/src/app/routes/api/v3/forms/public-forms.form.routes.ts b/src/app/routes/api/v3/forms/public-forms.form.routes.ts index b14e3746e0..b72c967a0b 100644 --- a/src/app/routes/api/v3/forms/public-forms.form.routes.ts +++ b/src/app/routes/api/v3/forms/public-forms.form.routes.ts @@ -1,6 +1,7 @@ import { Router } from 'express' import * as PublicFormController from '../../../../modules/form/public-form/public-form.controller' +import * as WogaaController from '../../../../modules/wogaa/wogaa.controller' export const PublicFormsFormRouter = Router() @@ -19,6 +20,7 @@ export const PublicFormsFormRouter = Router() * @returns 500 when database error occurs */ PublicFormsFormRouter.route('/:formId([a-fA-F0-9]{24})').get( + WogaaController.handleFormView, PublicFormController.handleGetPublicForm, ) diff --git a/src/app/routes/api/v3/forms/public-forms.submissions.routes.ts b/src/app/routes/api/v3/forms/public-forms.submissions.routes.ts index 947e9ed643..e53836ac2d 100644 --- a/src/app/routes/api/v3/forms/public-forms.submissions.routes.ts +++ b/src/app/routes/api/v3/forms/public-forms.submissions.routes.ts @@ -5,6 +5,7 @@ import * as EmailSubmissionController from '../../../../modules/submission/email import * as EncryptSubmissionController from '../../../../modules/submission/encrypt-submission/encrypt-submission.controller' import * as MultirespondentSubmissionController from '../../../../modules/submission/multirespondent-submission/multirespondent-submission.controller' import * as SubmissionController from '../../../../modules/submission/submission.controller' +import * as WogaaController from '../../../../modules/wogaa/wogaa.controller' import { limitRate } from '../../../../utils/limit-rate' export const PublicFormsSubmissionsRouter = Router() @@ -29,6 +30,7 @@ PublicFormsSubmissionsRouter.route( '/:formId([a-fA-F0-9]{24})/submissions/email', ).post( limitRate({ max: rateLimitConfig.submissions }), + WogaaController.handleSubmit, EmailSubmissionController.handleEmailSubmission, ) @@ -45,6 +47,7 @@ PublicFormsSubmissionsRouter.route( '/:formId([a-fA-F0-9]{24})/submissions/storage', ).post( limitRate({ max: rateLimitConfig.submissions }), + WogaaController.handleSubmit, EncryptSubmissionController.handleStorageSubmission, ) @@ -61,6 +64,7 @@ PublicFormsSubmissionsRouter.route( '/:formId([a-fA-F0-9]{24})/submissions/multirespondent', ).post( limitRate({ max: rateLimitConfig.submissions }), + WogaaController.handleSubmit, MultirespondentSubmissionController.handleMultirespondentSubmission, ) diff --git a/src/types/config.ts b/src/types/config.ts index 0c85b6d056..e76271230b 100644 --- a/src/types/config.ts +++ b/src/types/config.ts @@ -168,6 +168,7 @@ export interface IOptionalVarsSchema { region: string customCloudWatchGroup: string virusScannerLambdaFunctionName: string + virusScannerLambdaEndpoint: string } mail: { from: string