Skip to content

Commit

Permalink
chore: remove old encrypt submission route
Browse files Browse the repository at this point in the history
  • Loading branch information
tshuli committed Jan 8, 2024
1 parent a548085 commit 02aacc2
Show file tree
Hide file tree
Showing 4 changed files with 1 addition and 321 deletions.
5 changes: 1 addition & 4 deletions __tests__/e2e/encrypt-submission.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
MyInfoAttribute,
} from 'shared/types'

import { IFeatureFlagModel, IFormModel } from 'src/types'
import { IFormModel } from 'src/types'

import {
ALL_FIELDS as _ALL_FIELDS,
Expand Down Expand Up @@ -48,9 +48,6 @@ test.describe('Storage form submission', () => {
// Create models
db = await makeMongooseFixtures()
Form = makeModel(db, 'form.server.model', 'Form')
// TODO(FRM-1232): Remove this once old storage submission endpoint (/submissions/encrypt) is removed
// Add feature flag model and set encryption boundary shift to true
FeatureFlags = makeModel(db, 'feature_flag.server.model', 'FeatureFlags')
})
test.afterAll(async () => {
// Clean up db
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -622,17 +622,6 @@ const _createSubmission = async ({
return await performEncryptPostSubmissionActions(submission, responses)
}

// TODO (FRM-1232): remove endpoint after encryption boundary is shifted
export const handleEncryptedSubmission = [
CaptchaMiddleware.validateCaptchaParams,
TurnstileMiddleware.validateTurnstileParams,
EncryptSubmissionMiddleware.validateEncryptSubmissionParams,
EncryptSubmissionMiddleware.createFormsgAndRetrieveForm,
EncryptSubmissionMiddleware.validateEncryptSubmission,
EncryptSubmissionMiddleware.moveEncryptedPayload,
submitEncryptModeForm,
] as ControllerHandler[]

export const handleStorageSubmission = [
CaptchaMiddleware.validateCaptchaParams,
TurnstileMiddleware.validateTurnstileParams,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -946,292 +946,6 @@ describe('public-form.submissions.routes', () => {
})
})

describe('POST /forms/:formId/submissions/encrypt', () => {
const MOCK_ENCRYPTED_CONTENT = `${'a'.repeat(44)};${'a'.repeat(
32,
)}:${'a'.repeat(4)}`
const MOCK_SUBMISSION_BODY = {
responses: [],
encryptedContent: MOCK_ENCRYPTED_CONTENT,

version: 1,
}
describe('SPCP authentication', () => {
describe('SingPass', () => {
it('should return 200 when submission is valid', async () => {
jest
.spyOn(SpOidcClient.prototype, 'verifyJwt')
.mockResolvedValueOnce({
userName: 'S1234567A',
})
const { form } = await dbHandler.insertEncryptForm({
formOptions: {
esrvcId: 'mockEsrvcId',
authType: FormAuthType.SP,
hasCaptcha: false,
status: FormStatus.Public,
},
})

const response = await request
.post(`/forms/${form._id}/submissions/encrypt`)
.send(MOCK_SUBMISSION_BODY)
.query({ captchaResponse: 'null', captchaType: '' })
.set('Cookie', ['jwtSp=mockJwt'])

expect(response.status).toBe(200)
expect(response.body).toEqual({
message: 'Form submission successful.',
submissionId: expect.any(String),
timestamp: expect.any(Number),
})
})

it('should return 401 when submission does not have JWT', async () => {
const { form } = await dbHandler.insertEncryptForm({
formOptions: {
esrvcId: 'mockEsrvcId',
authType: FormAuthType.SP,
hasCaptcha: false,
status: FormStatus.Public,
},
})

const response = await request
.post(`/forms/${form._id}/submissions/encrypt`)
.send(MOCK_SUBMISSION_BODY)
.query({ captchaResponse: 'null', captchaType: '' })
// Note cookie is not set

expect(response.status).toBe(401)
expect(response.body).toEqual({
message:
'Something went wrong with your login. Please try logging in and submitting again.',
spcpSubmissionFailure: true,
})
})

it('should return 401 when submission has the wrong JWT type', async () => {
const { form } = await dbHandler.insertEncryptForm({
formOptions: {
esrvcId: 'mockEsrvcId',
authType: FormAuthType.SP,
hasCaptcha: false,
status: FormStatus.Public,
},
})

const response = await request
.post(`/forms/${form._id}/submissions/encrypt`)
.send(MOCK_SUBMISSION_BODY)
.query({ captchaResponse: 'null', captchaType: '' })
.set('Cookie', ['jwtCp=mockJwt'])
// Note cookie is for CorpPass, not SingPass

expect(response.status).toBe(401)
expect(response.body).toEqual({
message:
'Something went wrong with your login. Please try logging in and submitting again.',
spcpSubmissionFailure: true,
})
})

it('should return 401 when submission has invalid JWT', async () => {
// Mock auth client to return error when decoding JWT
jest
.spyOn(SpOidcClient.prototype, 'verifyJwt')
.mockRejectedValueOnce(new Error())

const { form } = await dbHandler.insertEncryptForm({
formOptions: {
esrvcId: 'mockEsrvcId',
authType: FormAuthType.SP,
hasCaptcha: false,
status: FormStatus.Public,
},
})

const response = await request
.post(`/forms/${form._id}/submissions/encrypt`)
.send(MOCK_SUBMISSION_BODY)
.query({ captchaResponse: 'null', captchaType: '' })
.set('Cookie', ['jwtSp=mockJwt'])

expect(response.status).toBe(401)
expect(response.body).toEqual({
message:
'Something went wrong with your login. Please try logging in and submitting again.',
spcpSubmissionFailure: true,
})
})

it('should return 401 when submission has JWT with the wrong shape', async () => {
// Mock auth client to return wrong decoded JWT shape
jest
.spyOn(SpOidcClient.prototype, 'verifyJwt')
.mockResolvedValueOnce({
wrongKey: 'S1234567A',
})

const { form } = await dbHandler.insertEncryptForm({
formOptions: {
esrvcId: 'mockEsrvcId',
authType: FormAuthType.SP,
hasCaptcha: false,
status: FormStatus.Public,
},
})

const response = await request
.post(`/forms/${form._id}/submissions/encrypt`)
.send(MOCK_SUBMISSION_BODY)
.query({ captchaResponse: 'null', captchaType: '' })
.set('Cookie', ['jwtSp=mockJwt'])

expect(response.status).toBe(401)
expect(response.body).toEqual({
message:
'Something went wrong with your login. Please try logging in and submitting again.',
spcpSubmissionFailure: true,
})
})
})

describe('CorpPass', () => {
it('should return 200 when submission is valid', async () => {
mockCpClient.verifyJwt.mockResolvedValueOnce({
userName: 'S1234567A',
userInfo: 'MyCorpPassUEN',
})
const { form } = await dbHandler.insertEncryptForm({
formOptions: {
esrvcId: 'mockEsrvcId',
authType: FormAuthType.CP,
hasCaptcha: false,
status: FormStatus.Public,
},
})

const response = await request
.post(`/forms/${form._id}/submissions/encrypt`)
.send(MOCK_SUBMISSION_BODY)
.query({ captchaResponse: 'null', captchaType: '' })
.set('Cookie', ['jwtCp=mockJwt'])

expect(response.status).toBe(200)
expect(response.body).toEqual({
message: 'Form submission successful.',
submissionId: expect.any(String),
timestamp: expect.any(Number),
})
})

it('should return 401 when submission does not have JWT', async () => {
const { form } = await dbHandler.insertEncryptForm({
formOptions: {
esrvcId: 'mockEsrvcId',
authType: FormAuthType.CP,
hasCaptcha: false,
status: FormStatus.Public,
},
})

const response = await request
.post(`/forms/${form._id}/submissions/encrypt`)
.send(MOCK_SUBMISSION_BODY)
.query({ captchaResponse: 'null', captchaType: '' })
// Note cookie is not set

expect(response.status).toBe(401)
expect(response.body).toEqual({
message:
'Something went wrong with your login. Please try logging in and submitting again.',
spcpSubmissionFailure: true,
})
})

it('should return 401 when submission has the wrong JWT type', async () => {
const { form } = await dbHandler.insertEncryptForm({
formOptions: {
esrvcId: 'mockEsrvcId',
authType: FormAuthType.CP,
hasCaptcha: false,
status: FormStatus.Public,
},
})

const response = await request
.post(`/forms/${form._id}/submissions/encrypt`)
.send(MOCK_SUBMISSION_BODY)
.query({ captchaResponse: 'null', captchaType: '' })
// Note cookie is for SingPass, not CorpPass
.set('Cookie', ['jwtSp=mockJwt'])

expect(response.status).toBe(401)
expect(response.body).toEqual({
message:
'Something went wrong with your login. Please try logging in and submitting again.',
spcpSubmissionFailure: true,
})
})

it('should return 401 when submission has invalid JWT', async () => {
// Mock auth client to return error when decoding JWT
mockCpClient.verifyJwt.mockRejectedValueOnce(new Error())
const { form } = await dbHandler.insertEncryptForm({
formOptions: {
esrvcId: 'mockEsrvcId',
authType: FormAuthType.CP,
hasCaptcha: false,
status: FormStatus.Public,
},
})

const response = await request
.post(`/forms/${form._id}/submissions/encrypt`)
.send(MOCK_SUBMISSION_BODY)
.query({ captchaResponse: 'null', captchaType: '' })
.set('Cookie', ['jwtCp=mockJwt'])

expect(response.status).toBe(401)
expect(response.body).toEqual({
message:
'Something went wrong with your login. Please try logging in and submitting again.',
spcpSubmissionFailure: true,
})
})

it('should return 401 when submission has JWT with the wrong shape', async () => {
// Mock auth client to return wrong decoded JWT shape
mockCpClient.verifyJwt.mockResolvedValueOnce({
wrongKey: 'S1234567A',
})
const { form } = await dbHandler.insertEncryptForm({
formOptions: {
esrvcId: 'mockEsrvcId',
authType: FormAuthType.CP,
hasCaptcha: false,
status: FormStatus.Public,
},
})

const response = await request
.post(`/forms/${form._id}/submissions/encrypt`)
.send(MOCK_SUBMISSION_BODY)
.query({ captchaResponse: 'null', captchaType: '' })
.set('Cookie', ['jwtCp=mockJwt'])

expect(response.status).toBe(401)
expect(response.body).toEqual({
message:
'Something went wrong with your login. Please try logging in and submitting again.',
spcpSubmissionFailure: true,
})
})
})
})
})

describe('POST /forms/:formId/submissions/get-s3-presigned-post-data', () => {
const FILE_MAP_1 = { id: '64ed84955ac23100636a00a0', size: 1 }
const FILE_MAP_2 = { id: '64ed84a35ac23100636a00af', size: 19999999 }
Expand Down
20 changes: 0 additions & 20 deletions src/app/routes/api/v3/forms/public-forms.submissions.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,26 +32,6 @@ PublicFormsSubmissionsRouter.route(
EmailSubmissionController.handleEmailSubmission,
)

// TODO (FRM-1232): remove endpoint after encryption boundary is shifted
/**
* Submit a form response, validate submission params and stores the encrypted
* contents.
* Optionally, an autoreply confirming submission is sent back to the user, if
* an email address was given. SMS autoreplies for mobile number fields are also
* sent if the feature is enabled.
* @route POST /forms/:formId/submissions/encrypt
* @param response.body.required - contains the entire form submission
* @param captchaResponse.query - contains the reCAPTCHA response artifact, if any
* @returns 200 - submission made
* @returns 400 - submission has bad data and could not be processed
*/
PublicFormsSubmissionsRouter.route(
'/:formId([a-fA-F0-9]{24})/submissions/encrypt',
).post(
limitRate({ max: rateLimitConfig.submissions }),
EncryptSubmissionController.handleEncryptedSubmission,
)

/**
* Submit a form response before public key encryption, performs pre-encryption
* steps (e.g. field validation, virus scanning) and stores the encrypted contents.
Expand Down

0 comments on commit 02aacc2

Please sign in to comment.