Skip to content

Commit

Permalink
refactor/is-form-public: migrate isFormPublic middleware to TypeScript (
Browse files Browse the repository at this point in the history
  • Loading branch information
liangyuanruo committed Dec 11, 2020
1 parent ca57bc0 commit a8ec327
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 76 deletions.
24 changes: 0 additions & 24 deletions src/app/controllers/public-forms.server.controller.js

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { Request } from 'express'
import { StatusCodes } from 'http-status-codes'

import expressHandler from 'tests/unit/backend/helpers/jest-express'

import { Status, WithForm } from '../../../../../types'
import { isFormPublicCheck } from '../public-form.middlewares'

describe('public-form.middlewares', () => {
it('should call next middleware function if form is public', () => {
const mockReq = Object.assign(expressHandler.mockRequest(), {
form: { status: Status.Public },
}) as WithForm<Request>
const mockRes = expressHandler.mockResponse()
const mockNext = jest.fn()

isFormPublicCheck(mockReq, mockRes, mockNext)

expect(mockNext).toBeCalled()
expect(mockRes.sendStatus).not.toBeCalled()
expect(mockRes.status).not.toBeCalled()
expect(mockRes.json).not.toBeCalled()
})

it('should return HTTP 404 Not Found if form is private', () => {
const title = 'My private form'
const inactiveMessage = 'The form is not available.'
const form = {
status: Status.Private,
title,
inactiveMessage,
}

const mockReq = Object.assign(expressHandler.mockRequest(), {
form,
}) as WithForm<Request>
const mockRes = expressHandler.mockResponse()
const mockNext = jest.fn()

isFormPublicCheck(mockReq, mockRes, mockNext)

expect(mockNext).not.toBeCalled()
expect(mockRes.sendStatus).not.toBeCalled()
expect(mockRes.status).toBeCalledWith(StatusCodes.NOT_FOUND)
expect(mockRes.json).toBeCalledWith({
message: inactiveMessage,
isPageFound: true,
formTitle: title,
})
})

it('should return HTTP 410 Gone if form is archived', () => {
const form = {
status: Status.Archived,
}

const mockReq = Object.assign(expressHandler.mockRequest(), {
form,
}) as WithForm<Request>
const mockRes = expressHandler.mockResponse()
const mockNext = jest.fn()

isFormPublicCheck(mockReq, mockRes, mockNext)

expect(mockNext).not.toBeCalled()
expect(mockRes.sendStatus).toBeCalledWith(StatusCodes.GONE)
expect(mockRes.status).not.toBeCalled()
expect(mockRes.json).not.toBeCalledWith()
})
})
29 changes: 29 additions & 0 deletions src/app/modules/form/public-form/public-form.middlewares.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { RequestHandler } from 'express'
import { StatusCodes } from 'http-status-codes'

import { WithForm } from '../../../../types'
import { FormDeletedError } from '../form.errors'
import { isFormPublic } from '../form.service'

/**
* Express middleware function that checks if a form attached to the Express request handler is public.
* before allowing downstream middleware to handle the request. Otherwise, it returns a HTTP 404 if the
* form is private, or HTTP 410 if the form has been archived.
* @param req - Express request object
* @param res - Express response object
* @param next - Express next middleware function
*/
export const isFormPublicCheck: RequestHandler = (req, res, next) => {
const { form } = req as WithForm<typeof req>
return isFormPublic(form)
.map(() => next())
.mapErr((error) => {
return error instanceof FormDeletedError
? res.sendStatus(StatusCodes.GONE)
: res.status(StatusCodes.NOT_FOUND).json({
message: form.inactiveMessage,
isPageFound: true, // Flag to prevent default 404 subtext ("please check link") from showing
formTitle: form.title,
})
})
}
8 changes: 4 additions & 4 deletions src/app/routes/public-forms.server.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Module dependencies.
*/
const forms = require('../../app/controllers/forms.server.controller')
const publicForms = require('../../app/controllers/public-forms.server.controller')
const publicForms = require('../modules/form/public-form/public-form.middlewares')
const submissions = require('../../app/controllers/submissions.server.controller')
const encryptSubmissions = require('../../app/controllers/encrypt-submissions.server.controller')
const myInfoController = require('../../app/controllers/myinfo.server.controller')
Expand Down Expand Up @@ -128,7 +128,7 @@ module.exports = function (app) {
.route('/:formId([a-fA-F0-9]{24})/publicform')
.get(
forms.formById,
publicForms.isFormPublic,
publicForms.isFormPublicCheck,
SpcpController.addSpcpSessionInfo,
myInfoController.addMyInfo,
forms.read(forms.REQUEST_TYPE.PUBLIC),
Expand Down Expand Up @@ -162,7 +162,7 @@ module.exports = function (app) {
limitRate({ max: rateLimitConfig.submissions }),
CaptchaFactory.validateCaptchaParams,
forms.formById,
publicForms.isFormPublic,
publicForms.isFormPublicCheck,
CaptchaMiddleware.checkCaptchaResponse,
SpcpController.isSpcpAuthenticated,
EmailSubmissionsMiddleware.receiveEmailSubmission,
Expand Down Expand Up @@ -269,7 +269,7 @@ module.exports = function (app) {
}),
}),
forms.formById,
publicForms.isFormPublic,
publicForms.isFormPublicCheck,
CaptchaMiddleware.checkCaptchaResponse,
encryptSubmissions.validateEncryptSubmission,
SpcpController.isSpcpAuthenticated,
Expand Down

This file was deleted.

0 comments on commit a8ec327

Please sign in to comment.