From 304110b6f9808f04ff0db01cf53aaf587fcc60da Mon Sep 17 00:00:00 2001 From: Scott Date: Wed, 1 Apr 2026 09:43:43 +0100 Subject: [PATCH 1/9] Media journey URL Retain session data with media uploads From c7e24806bba22ee8f3a512ffad738431b789ef90 Mon Sep 17 00:00:00 2001 From: Scott Date: Thu, 2 Apr 2026 07:06:38 +0100 Subject: [PATCH 2/9] URL link --- .jest/test.env.js | 1 + server/routes/__tests__/report-sent.spec.js | 43 +++++++++++++++ server/routes/report-sent.js | 60 ++++++++++++++++++++- server/utils/__tests__/date-helpers.spec.js | 18 +++++++ server/utils/config.js | 6 ++- server/utils/date-helpers.js | 20 ++++++- server/views/report-sent.html | 14 +++++ 7 files changed, 157 insertions(+), 5 deletions(-) create mode 100644 server/utils/__tests__/date-helpers.spec.js diff --git a/.jest/test.env.js b/.jest/test.env.js index f54c92f7..9e164078 100644 --- a/.jest/test.env.js +++ b/.jest/test.env.js @@ -7,3 +7,4 @@ process.env.CAPTCHA_ENABLED = 'true' process.env.CAPTCHA_API_KEY = '1234' process.env.CAPTCHA_SITE_KEY = 'abcd' process.env.CAPTCHA_BYPASS_KEY = 'testcaptchabypasskey' +process.env.MEDIA_UPLOAD_BASE_URL = 'https://example.test/upload-photo' diff --git a/server/routes/__tests__/report-sent.spec.js b/server/routes/__tests__/report-sent.spec.js index 6707daa9..28c4353d 100644 --- a/server/routes/__tests__/report-sent.spec.js +++ b/server/routes/__tests__/report-sent.spec.js @@ -1,13 +1,56 @@ import { submitGetRequest } from '../../__test-helpers__/server.js' import constants from '../../utils/constants.js' +import { parse } from 'node-html-parser' const url = constants.routes.REPORT_SENT const header = 'Report sent' +const getUploadLink = async (userAgreedForImages) => { + const sessionData = { + [constants.redisKeys.QUESTION_SET_ID]: 100, + [constants.redisKeys.SUBMISSION_TIMESTAMP]: '2026-04-01T10:30:00.000Z', + [constants.redisKeys.WATER_POLLUTION_CONTACT_DETAILS]: { + reporterEmailAddress: 'reporter@example.com' + }, + [constants.redisKeys.WATER_POLLUTION_IMAGES_OR_VIDEO]: [{ + questionResponse: userAgreedForImages + }] + } + + const response = await submitGetRequest({ url }, header, constants.statusCodes.OK, sessionData) + const html = parse(response.payload) + + return html.querySelector(`a[href*="${process.env.MEDIA_UPLOAD_BASE_URL}"]`) +} + describe(url, () => { describe('GET', () => { it(`Should return success response and correct view for ${url}`, async () => { await submitGetRequest({ url }, header) }) + + it('should render external upload link when user agreed to upload images', async () => { + const uploadLink = await getUploadLink(true) + + expect(uploadLink).toBeTruthy() + }) + + it('should include journey query param in upload link', async () => { + const uploadLink = await getUploadLink(true) + + expect(uploadLink.getAttribute('href')).toContain('journey=water+pollution') + }) + + it('should include dateTime query param in upload link', async () => { + const uploadLink = await getUploadLink(true) + + expect(uploadLink.getAttribute('href')).toContain('dateTime=') + }) + + it('should not render upload link when user did not agree to upload images', async () => { + const uploadLink = await getUploadLink(false) + + expect(uploadLink).toBeFalsy() + }) }) }) diff --git a/server/routes/report-sent.js b/server/routes/report-sent.js index 0dabb104..730194d8 100644 --- a/server/routes/report-sent.js +++ b/server/routes/report-sent.js @@ -1,17 +1,73 @@ import constants from '../utils/constants.js' +import config from '../utils/config.js' +import { formattedDate } from '../utils/date-helpers.js' const handlers = { get: async (request, h) => { const questionSetID = request.yar.get(constants.redisKeys.QUESTION_SET_ID) + const photoUploadDetails = getPhotoUploadDetails(request, questionSetID) request.yar.reset() - request.yar.set(constants.redisKeys.QUESTION_SET_ID, questionSetID) const context = _getContext() return h.view(constants.views.REPORT_SENT, { - ...context + ...context, photoUploadDetails }) } } +function getPhotoUploadDetails (request, questionSetID) { + const keyMap = { + 100: { + contact: constants.redisKeys.WATER_POLLUTION_CONTACT_DETAILS, + images: constants.redisKeys.WATER_POLLUTION_IMAGES_OR_VIDEO, + journey: 'water pollution' + }, + 200: { + contact: constants.redisKeys.SMELL_CONTACT_DETAILS, + images: constants.redisKeys.SMELL_IMAGES_OR_VIDEO, + journey: 'smell' + }, + 300: { + contact: constants.redisKeys.BLOCKAGE_CONTACT_DETAILS, + images: constants.redisKeys.BLOCKAGE_IMAGES_OR_VIDEO, + journey: 'blockage' + }, + 1800: { + contact: constants.redisKeys.ILLEGAL_FISHING_CONTACT_DETAILS, + images: constants.redisKeys.ILLEGAL_FISHING_IMAGES_OR_VIDEO, + journey: 'illegal fishing' + } + } + + const keys = keyMap[questionSetID] + + if (!keys) { + return { + userAgreedForImages: false, + reportersEmail: '', + photoUploadLink: null + } + } + + const submissionTimestamp = request.yar.get(constants.redisKeys.SUBMISSION_TIMESTAMP) + const reportersEmail = + request.yar.get(keys.contact).reporterEmailAddress + + const userAgreedForImages = + request.yar.get(keys.images)[0].questionResponse + + const photoUploadLink = getPhotoUploadLink(keys.journey, submissionTimestamp) + + return { userAgreedForImages, reportersEmail, photoUploadLink } +} + +function getPhotoUploadLink (journey, submissionTimestamp) { + const mediaUploadUrl = new URL(config.mediaUploadBaseUrl) + mediaUploadUrl.searchParams.set('journey', journey) + mediaUploadUrl.searchParams.set('dateTime', formattedDate(submissionTimestamp)) + + return mediaUploadUrl.toString() +} + const _getContext = () => { return { hideBackLink: true diff --git a/server/utils/__tests__/date-helpers.spec.js b/server/utils/__tests__/date-helpers.spec.js new file mode 100644 index 00000000..75b2da48 --- /dev/null +++ b/server/utils/__tests__/date-helpers.spec.js @@ -0,0 +1,18 @@ +import { formattedDate } from '../date-helpers.js' + +describe('date-helpers', () => { + describe('formattedDate', () => { + it('should return the full formatted result string', () => { + jest.spyOn(Date.prototype, 'toLocaleTimeString').mockReturnValue('2:48 pm') + jest.spyOn(Date.prototype, 'toLocaleDateString') + .mockReturnValueOnce('Monday') + .mockReturnValueOnce('April') + + const result = formattedDate('2026-04-01T10:30:00.000Z') + + expect(result).toEqual('2:48 pm on Monday, 1 April 2026') + + jest.restoreAllMocks() + }) + }) +}) diff --git a/server/utils/config.js b/server/utils/config.js index d8223f12..c7a18455 100644 --- a/server/utils/config.js +++ b/server/utils/config.js @@ -29,7 +29,8 @@ const schema = Joi.object().keys({ captchaEnabled: Joi.bool().default(false), captchaApiKey: Joi.string().allow(''), captchaSiteKey: Joi.string().allow(''), - captchaBypassKey: Joi.string() + captchaBypassKey: Joi.string(), + mediaUploadBaseUrl: Joi.string().uri({ scheme: ['http', 'https'] }).allow('').default('') }) const captchaEnabled = getBoolean(process.env.CAPTCHA_ENABLED) @@ -54,7 +55,8 @@ const config = { captchaEnabled, captchaApiKey: captchaEnabled ? process.env.CAPTCHA_API_KEY : '', captchaSiteKey: captchaEnabled ? process.env.CAPTCHA_SITE_KEY : '', - captchaBypassKey: process.env.CAPTCHA_BYPASS_KEY + captchaBypassKey: process.env.CAPTCHA_BYPASS_KEY, + mediaUploadBaseUrl: process.env.MEDIA_UPLOAD_BASE_URL } // Validate config diff --git a/server/utils/date-helpers.js b/server/utils/date-helpers.js index f548fa2b..bab05f3b 100644 --- a/server/utils/date-helpers.js +++ b/server/utils/date-helpers.js @@ -150,9 +150,27 @@ const returnError = (errorSummary, validateAndError, text, href, invalidDate) => } } +const formattedDate = (inputDate) => { + const date = new Date(inputDate) + const time = date.toLocaleTimeString('en-GB', { + hour: 'numeric', + minute: '2-digit', + hour12: true + }).toLowerCase() + + const weekday = date.toLocaleDateString('en-GB', { weekday: 'long' }) + const day = date.getDate() + const month = date.toLocaleDateString('en-GB', { month: 'long' }) + const year = date.getFullYear() + const dateString = `${time} on ${weekday}, ${day} ${month} ${year}` + + return dateString +} + export { dateValidateAndError, fieldErrorClasses, getDateErrors, - validatePayload + validatePayload, + formattedDate } diff --git a/server/views/report-sent.html b/server/views/report-sent.html index 15a04e56..64a3a7d1 100644 --- a/server/views/report-sent.html +++ b/server/views/report-sent.html @@ -11,6 +11,20 @@ titleText: "Report sent", html: "We have received your report" }) }} + {% if(photoUploadDetails.userAgreedForImages and photoUploadDetails.reportersEmail !== '') %} +

We have sent a confirmation of your report and a reference number to {{ photoUploadDetails.reportersEmail }}

+ {% endif %} + + {% if(photoUploadDetails.userAgreedForImages) %} +

+ Upload images +

+

You can now upload any photos you have that might help us investigate the problem.

+ {% endif %} + {% if(photoUploadDetails.userAgreedForImages and photoUploadDetails.reportersEmail !== '') %} +

We've also included this link in your confirmation email, if you want to do this later.

+ {% endif %} +

What happens next

From aae635c8347a21648851e0b6eaf3f13c54dacbe0 Mon Sep 17 00:00:00 2001 From: Scott Date: Thu, 9 Apr 2026 08:39:21 +0100 Subject: [PATCH 3/9] undo link setup --- server/routes/__tests__/report-sent.spec.js | 43 --------------- server/routes/report-sent.js | 61 +-------------------- server/utils/__tests__/date-helpers.spec.js | 18 ------ server/utils/config.js | 6 +- server/utils/date-helpers.js | 20 +------ 5 files changed, 5 insertions(+), 143 deletions(-) delete mode 100644 server/utils/__tests__/date-helpers.spec.js diff --git a/server/routes/__tests__/report-sent.spec.js b/server/routes/__tests__/report-sent.spec.js index 28c4353d..6707daa9 100644 --- a/server/routes/__tests__/report-sent.spec.js +++ b/server/routes/__tests__/report-sent.spec.js @@ -1,56 +1,13 @@ import { submitGetRequest } from '../../__test-helpers__/server.js' import constants from '../../utils/constants.js' -import { parse } from 'node-html-parser' const url = constants.routes.REPORT_SENT const header = 'Report sent' -const getUploadLink = async (userAgreedForImages) => { - const sessionData = { - [constants.redisKeys.QUESTION_SET_ID]: 100, - [constants.redisKeys.SUBMISSION_TIMESTAMP]: '2026-04-01T10:30:00.000Z', - [constants.redisKeys.WATER_POLLUTION_CONTACT_DETAILS]: { - reporterEmailAddress: 'reporter@example.com' - }, - [constants.redisKeys.WATER_POLLUTION_IMAGES_OR_VIDEO]: [{ - questionResponse: userAgreedForImages - }] - } - - const response = await submitGetRequest({ url }, header, constants.statusCodes.OK, sessionData) - const html = parse(response.payload) - - return html.querySelector(`a[href*="${process.env.MEDIA_UPLOAD_BASE_URL}"]`) -} - describe(url, () => { describe('GET', () => { it(`Should return success response and correct view for ${url}`, async () => { await submitGetRequest({ url }, header) }) - - it('should render external upload link when user agreed to upload images', async () => { - const uploadLink = await getUploadLink(true) - - expect(uploadLink).toBeTruthy() - }) - - it('should include journey query param in upload link', async () => { - const uploadLink = await getUploadLink(true) - - expect(uploadLink.getAttribute('href')).toContain('journey=water+pollution') - }) - - it('should include dateTime query param in upload link', async () => { - const uploadLink = await getUploadLink(true) - - expect(uploadLink.getAttribute('href')).toContain('dateTime=') - }) - - it('should not render upload link when user did not agree to upload images', async () => { - const uploadLink = await getUploadLink(false) - - expect(uploadLink).toBeFalsy() - }) }) }) diff --git a/server/routes/report-sent.js b/server/routes/report-sent.js index 730194d8..426b3bc3 100644 --- a/server/routes/report-sent.js +++ b/server/routes/report-sent.js @@ -1,73 +1,16 @@ import constants from '../utils/constants.js' -import config from '../utils/config.js' -import { formattedDate } from '../utils/date-helpers.js' const handlers = { get: async (request, h) => { - const questionSetID = request.yar.get(constants.redisKeys.QUESTION_SET_ID) - const photoUploadDetails = getPhotoUploadDetails(request, questionSetID) + request.yar.get(constants.redisKeys.QUESTION_SET_ID) request.yar.reset() const context = _getContext() return h.view(constants.views.REPORT_SENT, { - ...context, photoUploadDetails + ...context }) } } -function getPhotoUploadDetails (request, questionSetID) { - const keyMap = { - 100: { - contact: constants.redisKeys.WATER_POLLUTION_CONTACT_DETAILS, - images: constants.redisKeys.WATER_POLLUTION_IMAGES_OR_VIDEO, - journey: 'water pollution' - }, - 200: { - contact: constants.redisKeys.SMELL_CONTACT_DETAILS, - images: constants.redisKeys.SMELL_IMAGES_OR_VIDEO, - journey: 'smell' - }, - 300: { - contact: constants.redisKeys.BLOCKAGE_CONTACT_DETAILS, - images: constants.redisKeys.BLOCKAGE_IMAGES_OR_VIDEO, - journey: 'blockage' - }, - 1800: { - contact: constants.redisKeys.ILLEGAL_FISHING_CONTACT_DETAILS, - images: constants.redisKeys.ILLEGAL_FISHING_IMAGES_OR_VIDEO, - journey: 'illegal fishing' - } - } - - const keys = keyMap[questionSetID] - - if (!keys) { - return { - userAgreedForImages: false, - reportersEmail: '', - photoUploadLink: null - } - } - - const submissionTimestamp = request.yar.get(constants.redisKeys.SUBMISSION_TIMESTAMP) - const reportersEmail = - request.yar.get(keys.contact).reporterEmailAddress - - const userAgreedForImages = - request.yar.get(keys.images)[0].questionResponse - - const photoUploadLink = getPhotoUploadLink(keys.journey, submissionTimestamp) - - return { userAgreedForImages, reportersEmail, photoUploadLink } -} - -function getPhotoUploadLink (journey, submissionTimestamp) { - const mediaUploadUrl = new URL(config.mediaUploadBaseUrl) - mediaUploadUrl.searchParams.set('journey', journey) - mediaUploadUrl.searchParams.set('dateTime', formattedDate(submissionTimestamp)) - - return mediaUploadUrl.toString() -} - const _getContext = () => { return { hideBackLink: true diff --git a/server/utils/__tests__/date-helpers.spec.js b/server/utils/__tests__/date-helpers.spec.js deleted file mode 100644 index 75b2da48..00000000 --- a/server/utils/__tests__/date-helpers.spec.js +++ /dev/null @@ -1,18 +0,0 @@ -import { formattedDate } from '../date-helpers.js' - -describe('date-helpers', () => { - describe('formattedDate', () => { - it('should return the full formatted result string', () => { - jest.spyOn(Date.prototype, 'toLocaleTimeString').mockReturnValue('2:48 pm') - jest.spyOn(Date.prototype, 'toLocaleDateString') - .mockReturnValueOnce('Monday') - .mockReturnValueOnce('April') - - const result = formattedDate('2026-04-01T10:30:00.000Z') - - expect(result).toEqual('2:48 pm on Monday, 1 April 2026') - - jest.restoreAllMocks() - }) - }) -}) diff --git a/server/utils/config.js b/server/utils/config.js index c7a18455..d8223f12 100644 --- a/server/utils/config.js +++ b/server/utils/config.js @@ -29,8 +29,7 @@ const schema = Joi.object().keys({ captchaEnabled: Joi.bool().default(false), captchaApiKey: Joi.string().allow(''), captchaSiteKey: Joi.string().allow(''), - captchaBypassKey: Joi.string(), - mediaUploadBaseUrl: Joi.string().uri({ scheme: ['http', 'https'] }).allow('').default('') + captchaBypassKey: Joi.string() }) const captchaEnabled = getBoolean(process.env.CAPTCHA_ENABLED) @@ -55,8 +54,7 @@ const config = { captchaEnabled, captchaApiKey: captchaEnabled ? process.env.CAPTCHA_API_KEY : '', captchaSiteKey: captchaEnabled ? process.env.CAPTCHA_SITE_KEY : '', - captchaBypassKey: process.env.CAPTCHA_BYPASS_KEY, - mediaUploadBaseUrl: process.env.MEDIA_UPLOAD_BASE_URL + captchaBypassKey: process.env.CAPTCHA_BYPASS_KEY } // Validate config diff --git a/server/utils/date-helpers.js b/server/utils/date-helpers.js index bab05f3b..f548fa2b 100644 --- a/server/utils/date-helpers.js +++ b/server/utils/date-helpers.js @@ -150,27 +150,9 @@ const returnError = (errorSummary, validateAndError, text, href, invalidDate) => } } -const formattedDate = (inputDate) => { - const date = new Date(inputDate) - const time = date.toLocaleTimeString('en-GB', { - hour: 'numeric', - minute: '2-digit', - hour12: true - }).toLowerCase() - - const weekday = date.toLocaleDateString('en-GB', { weekday: 'long' }) - const day = date.getDate() - const month = date.toLocaleDateString('en-GB', { month: 'long' }) - const year = date.getFullYear() - const dateString = `${time} on ${weekday}, ${day} ${month} ${year}` - - return dateString -} - export { dateValidateAndError, fieldErrorClasses, getDateErrors, - validatePayload, - formattedDate + validatePayload } From 55f75e2df4d755ba6f8fb55f5f29551d939d8c23 Mon Sep 17 00:00:00 2001 From: Scott Date: Thu, 9 Apr 2026 10:55:40 +0100 Subject: [PATCH 4/9] update cache --- server/routes/__tests__/report-sent.spec.js | 30 +++++++++++++++++++++ server/routes/report-sent.js | 26 +++++++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/server/routes/__tests__/report-sent.spec.js b/server/routes/__tests__/report-sent.spec.js index 6707daa9..9c85522f 100644 --- a/server/routes/__tests__/report-sent.spec.js +++ b/server/routes/__tests__/report-sent.spec.js @@ -1,13 +1,43 @@ import { submitGetRequest } from '../../__test-helpers__/server.js' import constants from '../../utils/constants.js' +import reportSentRoutes from '../report-sent.js' const url = constants.routes.REPORT_SENT const header = 'Report sent' +const submissionTimestamp = '2026-04-09T09:00:00.000Z' +const sessionId = 'test-session-id' describe(url, () => { describe('GET', () => { it(`Should return success response and correct view for ${url}`, async () => { await submitGetRequest({ url }, header) }) + + it.each([ + { questionSetID: 100, expectedJourney: 'water pollution' }, + { questionSetID: 200, expectedJourney: 'smell' }, + { questionSetID: 300, expectedJourney: 'blockage' }, + { questionSetID: 1800, expectedJourney: 'illegal fishing' } + ])('should cache journey "$expectedJourney" for questionSetID $questionSetID', async ({ questionSetID, expectedJourney }) => { + const set = jest.fn() + await reportSentRoutes[0].handler({ + yar: { + get: jest.fn(key => ({ + [constants.redisKeys.QUESTION_SET_ID]: questionSetID, + [constants.redisKeys.SUBMISSION_TIMESTAMP]: submissionTimestamp + }[key])), + id: sessionId, + reset: jest.fn() + }, + server: { + cache: jest.fn(() => ({ set })) + } + }, { view: jest.fn() }) + + expect(set).toHaveBeenCalledWith(sessionId, { + journey: expectedJourney, + dateTime: submissionTimestamp + }) + }) }) }) diff --git a/server/routes/report-sent.js b/server/routes/report-sent.js index 426b3bc3..749e4ee3 100644 --- a/server/routes/report-sent.js +++ b/server/routes/report-sent.js @@ -1,8 +1,32 @@ import constants from '../utils/constants.js' +const expire = 72 * 60 * 60 * 1000 + +const journeyMap = { + 100: 'water pollution', + 200: 'smell', + 300: 'blockage', + 1800: 'illegal fishing' +} + const handlers = { get: async (request, h) => { - request.yar.get(constants.redisKeys.QUESTION_SET_ID) + const questionSetID = request.yar.get(constants.redisKeys.QUESTION_SET_ID) + const submissionTimestamp = request.yar.get(constants.redisKeys.SUBMISSION_TIMESTAMP) + const journey = journeyMap[questionSetID] + const sessionId = request.yar.id + + const mediaUploadCache = request.server.cache({ + cache: 'redis_cache', + segment: 'media-upload', + expiresIn: expire + }) + + await mediaUploadCache.set(sessionId, { + journey, + dateTime: submissionTimestamp + }) + request.yar.reset() const context = _getContext() return h.view(constants.views.REPORT_SENT, { From 80d9c56d9d26412e77dcc087ac5729fae66fb916 Mon Sep 17 00:00:00 2001 From: Scott Date: Fri, 10 Apr 2026 13:32:06 +0100 Subject: [PATCH 5/9] hardcode values to test --- .jest/test.env.js | 1 - server/routes/__tests__/report-sent.spec.js | 46 ++++++++++++++------- server/routes/report-sent.js | 5 ++- server/utils/config.js | 2 + server/views/report-sent.html | 2 +- 5 files changed, 39 insertions(+), 17 deletions(-) diff --git a/.jest/test.env.js b/.jest/test.env.js index 9e164078..f54c92f7 100644 --- a/.jest/test.env.js +++ b/.jest/test.env.js @@ -7,4 +7,3 @@ process.env.CAPTCHA_ENABLED = 'true' process.env.CAPTCHA_API_KEY = '1234' process.env.CAPTCHA_SITE_KEY = 'abcd' process.env.CAPTCHA_BYPASS_KEY = 'testcaptchabypasskey' -process.env.MEDIA_UPLOAD_BASE_URL = 'https://example.test/upload-photo' diff --git a/server/routes/__tests__/report-sent.spec.js b/server/routes/__tests__/report-sent.spec.js index 9c85522f..1ca18eed 100644 --- a/server/routes/__tests__/report-sent.spec.js +++ b/server/routes/__tests__/report-sent.spec.js @@ -1,5 +1,6 @@ import { submitGetRequest } from '../../__test-helpers__/server.js' import constants from '../../utils/constants.js' +// import config from '../../utils/config.js' import reportSentRoutes from '../report-sent.js' const url = constants.routes.REPORT_SENT @@ -7,6 +8,27 @@ const header = 'Report sent' const submissionTimestamp = '2026-04-09T09:00:00.000Z' const sessionId = 'test-session-id' +const handler = async questionSetID => { + const set = jest.fn() + const view = jest.fn() + + await reportSentRoutes[0].handler({ + yar: { + get: jest.fn(key => ({ + [constants.redisKeys.QUESTION_SET_ID]: questionSetID, + [constants.redisKeys.SUBMISSION_TIMESTAMP]: submissionTimestamp + }[key])), + id: sessionId, + reset: jest.fn() + }, + server: { + cache: jest.fn(() => ({ set })) + } + }, { view }) + + return { set, view } +} + describe(url, () => { describe('GET', () => { it(`Should return success response and correct view for ${url}`, async () => { @@ -19,25 +41,21 @@ describe(url, () => { { questionSetID: 300, expectedJourney: 'blockage' }, { questionSetID: 1800, expectedJourney: 'illegal fishing' } ])('should cache journey "$expectedJourney" for questionSetID $questionSetID', async ({ questionSetID, expectedJourney }) => { - const set = jest.fn() - await reportSentRoutes[0].handler({ - yar: { - get: jest.fn(key => ({ - [constants.redisKeys.QUESTION_SET_ID]: questionSetID, - [constants.redisKeys.SUBMISSION_TIMESTAMP]: submissionTimestamp - }[key])), - id: sessionId, - reset: jest.fn() - }, - server: { - cache: jest.fn(() => ({ set })) - } - }, { view: jest.fn() }) + const { set } = await handler(questionSetID) expect(set).toHaveBeenCalledWith(sessionId, { journey: expectedJourney, dateTime: submissionTimestamp }) }) + + it('should pass mediaUploadLink', async () => { + const { view } = await handler(100) + + expect(view).toHaveBeenCalledWith(constants.views.REPORT_SENT, expect.objectContaining({ + mediaUploadLink: 'https://sir-uploader-dev1.azure.defra.cloud/upload-photo' + // mediaUploadLink: config.mediaUploadUrl + })) + }) }) }) diff --git a/server/routes/report-sent.js b/server/routes/report-sent.js index 749e4ee3..77b0daa2 100644 --- a/server/routes/report-sent.js +++ b/server/routes/report-sent.js @@ -1,4 +1,5 @@ import constants from '../utils/constants.js' +// import config from '../utils/config.js' const expire = 72 * 60 * 60 * 1000 @@ -30,7 +31,9 @@ const handlers = { request.yar.reset() const context = _getContext() return h.view(constants.views.REPORT_SENT, { - ...context + ...context, + mediaUploadLink: 'https://sir-uploader-dev1.azure.defra.cloud/upload-photo' + // mediaUploadLink: config.mediaUploadUrl }) } } diff --git a/server/utils/config.js b/server/utils/config.js index d8223f12..9ab413ed 100644 --- a/server/utils/config.js +++ b/server/utils/config.js @@ -30,6 +30,7 @@ const schema = Joi.object().keys({ captchaApiKey: Joi.string().allow(''), captchaSiteKey: Joi.string().allow(''), captchaBypassKey: Joi.string() + // mediaUploadUrl: Joi.string().uri({ scheme: ['http', 'https'] }).allow('').default('') }) const captchaEnabled = getBoolean(process.env.CAPTCHA_ENABLED) @@ -55,6 +56,7 @@ const config = { captchaApiKey: captchaEnabled ? process.env.CAPTCHA_API_KEY : '', captchaSiteKey: captchaEnabled ? process.env.CAPTCHA_SITE_KEY : '', captchaBypassKey: process.env.CAPTCHA_BYPASS_KEY + // mediaUploadUrl: process.env.MEDIA_UPLOAD_URL } // Validate config diff --git a/server/views/report-sent.html b/server/views/report-sent.html index 64a3a7d1..e8c6dbe4 100644 --- a/server/views/report-sent.html +++ b/server/views/report-sent.html @@ -19,7 +19,7 @@

Upload images

-

You can now upload any photos you have that might help us investigate the problem.

+

You can now upload any photos you have that might help us investigate the problem.

{% endif %} {% if(photoUploadDetails.userAgreedForImages and photoUploadDetails.reportersEmail !== '') %}

We've also included this link in your confirmation email, if you want to do this later.

From c99cf2c8b8763a41633cc5c6a46107edb9741b1f Mon Sep 17 00:00:00 2001 From: Scott Date: Mon, 13 Apr 2026 09:32:11 +0100 Subject: [PATCH 6/9] display content on report sent --- server/routes/__tests__/report-sent.spec.js | 115 +++++++++++++++++++- server/routes/report-sent.js | 53 ++++++++- server/views/report-sent.html | 2 +- 3 files changed, 158 insertions(+), 12 deletions(-) diff --git a/server/routes/__tests__/report-sent.spec.js b/server/routes/__tests__/report-sent.spec.js index 1ca18eed..7776c04a 100644 --- a/server/routes/__tests__/report-sent.spec.js +++ b/server/routes/__tests__/report-sent.spec.js @@ -1,5 +1,6 @@ import { submitGetRequest } from '../../__test-helpers__/server.js' import constants from '../../utils/constants.js' +import { questionSets } from '../../utils/question-sets.js' // import config from '../../utils/config.js' import reportSentRoutes from '../report-sent.js' @@ -8,15 +9,85 @@ const header = 'Report sent' const submissionTimestamp = '2026-04-09T09:00:00.000Z' const sessionId = 'test-session-id' -const handler = async questionSetID => { +const journeySessionData = { + 100: { + contactDetails: { + reporterEmailAddress: 'water@test.com' + }, + imagesOrVideo: [{ + answerId: questionSets.WATER_POLLUTION.questions.WATER_POLLUTION_IMAGES_OR_VIDEO.answers.yes.answerId + }] + }, + 200: { + contactDetails: { + reporterEmailAddress: 'smell@test.com' + }, + imagesOrVideo: [{ + answerId: questionSets.SMELL.questions.SMELL_IMAGES_OR_VIDEO.answers.yes.answerId + }] + }, + 300: { + contactDetails: { + reporterEmailAddress: 'blockage@test.com' + }, + imagesOrVideo: [{ + answerId: questionSets.BLOCKAGE.questions.BLOCKAGE_IMAGES_OR_VIDEO.answers.yes.answerId + }] + }, + 1800: { + contactDetails: { + reporterEmailAddress: 'fishing@test.com' + }, + imagesOrVideo: [{ + answerId: questionSets.ILLEGAL_FISHING.questions.ILLEGAL_FISHING_IMAGES_OR_VIDEO.answers.yes.answerId + }] + } +} + +const handler = async (questionSetID, overrides = {}) => { const set = jest.fn() const view = jest.fn() + const defaultJourneyData = journeySessionData[questionSetID] || { + contactDetails: { reporterEmailAddress: '' }, + imagesOrVideo: [] + } + + const contactDetails = overrides.contactDetails !== undefined + ? overrides.contactDetails + : defaultJourneyData.contactDetails + const imagesOrVideo = overrides.imagesOrVideo !== undefined + ? overrides.imagesOrVideo + : defaultJourneyData.imagesOrVideo + + const keyMap = { + 100: { + contactDetailsKey: constants.redisKeys.WATER_POLLUTION_CONTACT_DETAILS, + imagesOrVideoKey: constants.redisKeys.WATER_POLLUTION_IMAGES_OR_VIDEO + }, + 200: { + contactDetailsKey: constants.redisKeys.SMELL_CONTACT_DETAILS, + imagesOrVideoKey: constants.redisKeys.SMELL_IMAGES_OR_VIDEO + }, + 300: { + contactDetailsKey: constants.redisKeys.BLOCKAGE_CONTACT_DETAILS, + imagesOrVideoKey: constants.redisKeys.BLOCKAGE_IMAGES_OR_VIDEO + }, + 1800: { + contactDetailsKey: constants.redisKeys.ILLEGAL_FISHING_CONTACT_DETAILS, + imagesOrVideoKey: constants.redisKeys.ILLEGAL_FISHING_IMAGES_OR_VIDEO + } + } + + const journeyKeys = keyMap[questionSetID] || {} + await reportSentRoutes[0].handler({ yar: { get: jest.fn(key => ({ [constants.redisKeys.QUESTION_SET_ID]: questionSetID, - [constants.redisKeys.SUBMISSION_TIMESTAMP]: submissionTimestamp + [constants.redisKeys.SUBMISSION_TIMESTAMP]: submissionTimestamp, + [journeyKeys.contactDetailsKey]: contactDetails, + [journeyKeys.imagesOrVideoKey]: imagesOrVideo }[key])), id: sessionId, reset: jest.fn() @@ -49,12 +120,46 @@ describe(url, () => { }) }) - it('should pass mediaUploadLink', async () => { + it('should pass mediaUploadLink in photoUploadDetails', async () => { const { view } = await handler(100) expect(view).toHaveBeenCalledWith(constants.views.REPORT_SENT, expect.objectContaining({ - mediaUploadLink: 'https://sir-uploader-dev1.azure.defra.cloud/upload-photo' - // mediaUploadLink: config.mediaUploadUrl + photoUploadDetails: expect.objectContaining({ + mediaUploadLink: 'https://sir-uploader-dev1.azure.defra.cloud/upload-photo' + // mediaUploadLink: config.mediaUploadUrl + }) + })) + }) + + it.each([ + { questionSetID: 100, email: 'water@test.com' }, + { questionSetID: 200, email: 'smell@test.com' }, + { questionSetID: 300, email: 'blockage@test.com' }, + { questionSetID: 1800, email: 'fishing@test.com' } + ])('should pass photo upload details for questionSetID $questionSetID', async ({ questionSetID, email }) => { + const { view } = await handler(questionSetID) + + expect(view).toHaveBeenCalledWith(constants.views.REPORT_SENT, expect.objectContaining({ + photoUploadDetails: { + mediaUploadLink: 'https://sir-uploader-dev1.azure.defra.cloud/upload-photo', + reportersEmail: email, + userAgreedForImages: true + } + })) + }) + + it('should default photo upload details when contact details and image answer are missing', async () => { + const { view } = await handler(100, { + contactDetails: null, + imagesOrVideo: null + }) + + expect(view).toHaveBeenCalledWith(constants.views.REPORT_SENT, expect.objectContaining({ + photoUploadDetails: { + mediaUploadLink: 'https://sir-uploader-dev1.azure.defra.cloud/upload-photo', + reportersEmail: '', + userAgreedForImages: false + } })) }) }) diff --git a/server/routes/report-sent.js b/server/routes/report-sent.js index 77b0daa2..aeabe6ae 100644 --- a/server/routes/report-sent.js +++ b/server/routes/report-sent.js @@ -1,7 +1,9 @@ import constants from '../utils/constants.js' +import { questionSets } from '../utils/question-sets.js' // import config from '../utils/config.js' const expire = 72 * 60 * 60 * 1000 +const mediaUploadLink = 'https://sir-uploader-dev1.azure.defra.cloud/upload-photo' const journeyMap = { 100: 'water pollution', @@ -10,12 +12,48 @@ const journeyMap = { 1800: 'illegal fishing' } +const journeyConfigMap = { + 100: { + contactDetailsKey: constants.redisKeys.WATER_POLLUTION_CONTACT_DETAILS, + imagesOrVideoKey: constants.redisKeys.WATER_POLLUTION_IMAGES_OR_VIDEO, + imagesQuestion: questionSets.WATER_POLLUTION.questions.WATER_POLLUTION_IMAGES_OR_VIDEO + }, + 200: { + contactDetailsKey: constants.redisKeys.SMELL_CONTACT_DETAILS, + imagesOrVideoKey: constants.redisKeys.SMELL_IMAGES_OR_VIDEO, + imagesQuestion: questionSets.SMELL.questions.SMELL_IMAGES_OR_VIDEO + }, + 300: { + contactDetailsKey: constants.redisKeys.BLOCKAGE_CONTACT_DETAILS, + imagesOrVideoKey: constants.redisKeys.BLOCKAGE_IMAGES_OR_VIDEO, + imagesQuestion: questionSets.BLOCKAGE.questions.BLOCKAGE_IMAGES_OR_VIDEO + }, + 1800: { + contactDetailsKey: constants.redisKeys.ILLEGAL_FISHING_CONTACT_DETAILS, + imagesOrVideoKey: constants.redisKeys.ILLEGAL_FISHING_IMAGES_OR_VIDEO, + imagesQuestion: questionSets.ILLEGAL_FISHING.questions.ILLEGAL_FISHING_IMAGES_OR_VIDEO + } +} + const handlers = { get: async (request, h) => { const questionSetID = request.yar.get(constants.redisKeys.QUESTION_SET_ID) const submissionTimestamp = request.yar.get(constants.redisKeys.SUBMISSION_TIMESTAMP) const journey = journeyMap[questionSetID] const sessionId = request.yar.id + const journeyConfig = journeyConfigMap[questionSetID] + + const contactDetails = journeyConfig + ? request.yar.get(journeyConfig.contactDetailsKey) + : null + const imagesOrVideoAnswer = journeyConfig + ? request.yar.get(journeyConfig.imagesOrVideoKey) + : null + + const reportersEmail = contactDetails?.reporterEmailAddress || '' + const userAgreedForImages = journeyConfig + ? imagesOrVideoAnswer?.[0]?.answerId === journeyConfig.imagesQuestion.answers.yes.answerId + : false const mediaUploadCache = request.server.cache({ cache: 'redis_cache', @@ -29,18 +67,21 @@ const handlers = { }) request.yar.reset() - const context = _getContext() - return h.view(constants.views.REPORT_SENT, { - ...context, - mediaUploadLink: 'https://sir-uploader-dev1.azure.defra.cloud/upload-photo' + const context = _getContext({ + reportersEmail, + userAgreedForImages, + mediaUploadLink // mediaUploadLink: config.mediaUploadUrl }) + return h.view(constants.views.REPORT_SENT, context) } } -const _getContext = () => { +const _getContext = (photoUploadDetails) => { return { - hideBackLink: true + hideBackLink: true, + photoUploadDetails + // mediaUploadLink: config.mediaUploadUrl } } diff --git a/server/views/report-sent.html b/server/views/report-sent.html index e8c6dbe4..b04fb57c 100644 --- a/server/views/report-sent.html +++ b/server/views/report-sent.html @@ -19,7 +19,7 @@

Upload images

-

You can now upload any photos you have that might help us investigate the problem.

+

You can now upload any photos you have that might help us investigate the problem.

{% endif %} {% if(photoUploadDetails.userAgreedForImages and photoUploadDetails.reportersEmail !== '') %}

We've also included this link in your confirmation email, if you want to do this later.

From 615b3ed2a32d58d87c1a9b56bafe07ebb87c7a6f Mon Sep 17 00:00:00 2001 From: Scott Date: Mon, 13 Apr 2026 09:59:04 +0100 Subject: [PATCH 7/9] change cache setup --- server/routes/__tests__/report-sent.spec.js | 19 ++++++++----------- server/routes/report-sent.js | 14 ++------------ 2 files changed, 10 insertions(+), 23 deletions(-) diff --git a/server/routes/__tests__/report-sent.spec.js b/server/routes/__tests__/report-sent.spec.js index 7776c04a..2389e47a 100644 --- a/server/routes/__tests__/report-sent.spec.js +++ b/server/routes/__tests__/report-sent.spec.js @@ -7,7 +7,6 @@ import reportSentRoutes from '../report-sent.js' const url = constants.routes.REPORT_SENT const header = 'Report sent' const submissionTimestamp = '2026-04-09T09:00:00.000Z' -const sessionId = 'test-session-id' const journeySessionData = { 100: { @@ -45,7 +44,7 @@ const journeySessionData = { } const handler = async (questionSetID, overrides = {}) => { - const set = jest.fn() + const yarSet = jest.fn() const view = jest.fn() const defaultJourneyData = journeySessionData[questionSetID] || { @@ -89,15 +88,15 @@ const handler = async (questionSetID, overrides = {}) => { [journeyKeys.contactDetailsKey]: contactDetails, [journeyKeys.imagesOrVideoKey]: imagesOrVideo }[key])), - id: sessionId, + set: yarSet, reset: jest.fn() }, server: { - cache: jest.fn(() => ({ set })) + cache: jest.fn() } }, { view }) - return { set, view } + return { yarSet, view } } describe(url, () => { @@ -111,13 +110,11 @@ describe(url, () => { { questionSetID: 200, expectedJourney: 'smell' }, { questionSetID: 300, expectedJourney: 'blockage' }, { questionSetID: 1800, expectedJourney: 'illegal fishing' } - ])('should cache journey "$expectedJourney" for questionSetID $questionSetID', async ({ questionSetID, expectedJourney }) => { - const { set } = await handler(questionSetID) + ])('should set journey "$expectedJourney" for questionSetID $questionSetID', async ({ questionSetID, expectedJourney }) => { + const { yarSet } = await handler(questionSetID) - expect(set).toHaveBeenCalledWith(sessionId, { - journey: expectedJourney, - dateTime: submissionTimestamp - }) + expect(yarSet).toHaveBeenCalledWith('journey', expectedJourney) + expect(yarSet).toHaveBeenCalledWith('dateTime', submissionTimestamp) }) it('should pass mediaUploadLink in photoUploadDetails', async () => { diff --git a/server/routes/report-sent.js b/server/routes/report-sent.js index aeabe6ae..f61753b2 100644 --- a/server/routes/report-sent.js +++ b/server/routes/report-sent.js @@ -2,7 +2,6 @@ import constants from '../utils/constants.js' import { questionSets } from '../utils/question-sets.js' // import config from '../utils/config.js' -const expire = 72 * 60 * 60 * 1000 const mediaUploadLink = 'https://sir-uploader-dev1.azure.defra.cloud/upload-photo' const journeyMap = { @@ -40,7 +39,6 @@ const handlers = { const questionSetID = request.yar.get(constants.redisKeys.QUESTION_SET_ID) const submissionTimestamp = request.yar.get(constants.redisKeys.SUBMISSION_TIMESTAMP) const journey = journeyMap[questionSetID] - const sessionId = request.yar.id const journeyConfig = journeyConfigMap[questionSetID] const contactDetails = journeyConfig @@ -55,16 +53,8 @@ const handlers = { ? imagesOrVideoAnswer?.[0]?.answerId === journeyConfig.imagesQuestion.answers.yes.answerId : false - const mediaUploadCache = request.server.cache({ - cache: 'redis_cache', - segment: 'media-upload', - expiresIn: expire - }) - - await mediaUploadCache.set(sessionId, { - journey, - dateTime: submissionTimestamp - }) + request.yar.set('journey', journey) + request.yar.set('dateTime', submissionTimestamp) request.yar.reset() const context = _getContext({ From 967ea59a6b99248cf06460c6bc406f618599894f Mon Sep 17 00:00:00 2001 From: Scott Date: Mon, 13 Apr 2026 10:49:58 +0100 Subject: [PATCH 8/9] media upload cache --- server/index.js | 7 +++++++ server/routes/__tests__/report-sent.spec.js | 21 +++++++++++++-------- server/routes/report-sent.js | 7 +++++-- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/server/index.js b/server/index.js index 28467bb8..f809c2b3 100644 --- a/server/index.js +++ b/server/index.js @@ -10,6 +10,8 @@ import logging from './plugins/logging.js' import session from './plugins/session.js' import onPostHandler from './plugins/on-post-handler.js' +const expire = 72 * 60 * 60 * 1000 + const createServer = async options => { // Create the hapi server options = { @@ -34,6 +36,11 @@ const createServer = async options => { const init = async server => { await _registerPlugins(server) + server.app.mediaUploadCache = server.cache({ + cache: 'redis_cache', + segment: 'media-upload', + expiresIn: expire + }) await server.start() } diff --git a/server/routes/__tests__/report-sent.spec.js b/server/routes/__tests__/report-sent.spec.js index 2389e47a..91208e99 100644 --- a/server/routes/__tests__/report-sent.spec.js +++ b/server/routes/__tests__/report-sent.spec.js @@ -7,6 +7,7 @@ import reportSentRoutes from '../report-sent.js' const url = constants.routes.REPORT_SENT const header = 'Report sent' const submissionTimestamp = '2026-04-09T09:00:00.000Z' +const sessionId = 'test-session-id' const journeySessionData = { 100: { @@ -44,7 +45,7 @@ const journeySessionData = { } const handler = async (questionSetID, overrides = {}) => { - const yarSet = jest.fn() + const set = jest.fn() const view = jest.fn() const defaultJourneyData = journeySessionData[questionSetID] || { @@ -88,15 +89,17 @@ const handler = async (questionSetID, overrides = {}) => { [journeyKeys.contactDetailsKey]: contactDetails, [journeyKeys.imagesOrVideoKey]: imagesOrVideo }[key])), - set: yarSet, + id: sessionId, reset: jest.fn() }, server: { - cache: jest.fn() + app: { + mediaUploadCache: { set } + } } }, { view }) - return { yarSet, view } + return { set, view } } describe(url, () => { @@ -110,11 +113,13 @@ describe(url, () => { { questionSetID: 200, expectedJourney: 'smell' }, { questionSetID: 300, expectedJourney: 'blockage' }, { questionSetID: 1800, expectedJourney: 'illegal fishing' } - ])('should set journey "$expectedJourney" for questionSetID $questionSetID', async ({ questionSetID, expectedJourney }) => { - const { yarSet } = await handler(questionSetID) + ])('should cache journey "$expectedJourney" for questionSetID $questionSetID', async ({ questionSetID, expectedJourney }) => { + const { set } = await handler(questionSetID) - expect(yarSet).toHaveBeenCalledWith('journey', expectedJourney) - expect(yarSet).toHaveBeenCalledWith('dateTime', submissionTimestamp) + expect(set).toHaveBeenCalledWith(sessionId, { + journey: expectedJourney, + dateTime: submissionTimestamp + }) }) it('should pass mediaUploadLink in photoUploadDetails', async () => { diff --git a/server/routes/report-sent.js b/server/routes/report-sent.js index f61753b2..ecbb7498 100644 --- a/server/routes/report-sent.js +++ b/server/routes/report-sent.js @@ -39,6 +39,7 @@ const handlers = { const questionSetID = request.yar.get(constants.redisKeys.QUESTION_SET_ID) const submissionTimestamp = request.yar.get(constants.redisKeys.SUBMISSION_TIMESTAMP) const journey = journeyMap[questionSetID] + const sessionId = request.yar.id const journeyConfig = journeyConfigMap[questionSetID] const contactDetails = journeyConfig @@ -53,8 +54,10 @@ const handlers = { ? imagesOrVideoAnswer?.[0]?.answerId === journeyConfig.imagesQuestion.answers.yes.answerId : false - request.yar.set('journey', journey) - request.yar.set('dateTime', submissionTimestamp) + await request.server.app.mediaUploadCache.set(sessionId, { + journey, + dateTime: submissionTimestamp + }) request.yar.reset() const context = _getContext({ From 3df4c18b5549b6ea1cd12948f3a9c7e7f15748cb Mon Sep 17 00:00:00 2001 From: Scott Date: Tue, 14 Apr 2026 09:44:41 +0100 Subject: [PATCH 9/9] use env --- server/routes/__tests__/report-sent.spec.js | 9 +++++---- server/routes/report-sent.js | 6 ++++-- server/utils/config.js | 8 ++++---- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/server/routes/__tests__/report-sent.spec.js b/server/routes/__tests__/report-sent.spec.js index 91208e99..56602121 100644 --- a/server/routes/__tests__/report-sent.spec.js +++ b/server/routes/__tests__/report-sent.spec.js @@ -1,13 +1,14 @@ import { submitGetRequest } from '../../__test-helpers__/server.js' import constants from '../../utils/constants.js' import { questionSets } from '../../utils/question-sets.js' -// import config from '../../utils/config.js' +import config from '../../utils/config.js' import reportSentRoutes from '../report-sent.js' const url = constants.routes.REPORT_SENT const header = 'Report sent' const submissionTimestamp = '2026-04-09T09:00:00.000Z' const sessionId = 'test-session-id' +const expectedMediaUploadLink = `${config.mediaUploadUrl}/upload-photo?sirid=${sessionId}` const journeySessionData = { 100: { @@ -127,7 +128,7 @@ describe(url, () => { expect(view).toHaveBeenCalledWith(constants.views.REPORT_SENT, expect.objectContaining({ photoUploadDetails: expect.objectContaining({ - mediaUploadLink: 'https://sir-uploader-dev1.azure.defra.cloud/upload-photo' + mediaUploadLink: expectedMediaUploadLink // mediaUploadLink: config.mediaUploadUrl }) })) @@ -143,7 +144,7 @@ describe(url, () => { expect(view).toHaveBeenCalledWith(constants.views.REPORT_SENT, expect.objectContaining({ photoUploadDetails: { - mediaUploadLink: 'https://sir-uploader-dev1.azure.defra.cloud/upload-photo', + mediaUploadLink: expectedMediaUploadLink, reportersEmail: email, userAgreedForImages: true } @@ -158,7 +159,7 @@ describe(url, () => { expect(view).toHaveBeenCalledWith(constants.views.REPORT_SENT, expect.objectContaining({ photoUploadDetails: { - mediaUploadLink: 'https://sir-uploader-dev1.azure.defra.cloud/upload-photo', + mediaUploadLink: expectedMediaUploadLink, reportersEmail: '', userAgreedForImages: false } diff --git a/server/routes/report-sent.js b/server/routes/report-sent.js index ecbb7498..930d8658 100644 --- a/server/routes/report-sent.js +++ b/server/routes/report-sent.js @@ -1,8 +1,8 @@ import constants from '../utils/constants.js' import { questionSets } from '../utils/question-sets.js' -// import config from '../utils/config.js' +import config from '../utils/config.js' -const mediaUploadLink = 'https://sir-uploader-dev1.azure.defra.cloud/upload-photo' +const mediaUploadBaseUrl = `${config.mediaUploadUrl}/upload-photo` const journeyMap = { 100: 'water pollution', @@ -59,6 +59,8 @@ const handlers = { dateTime: submissionTimestamp }) + const mediaUploadLink = `${mediaUploadBaseUrl}?sirid=${sessionId}` + request.yar.reset() const context = _getContext({ reportersEmail, diff --git a/server/utils/config.js b/server/utils/config.js index 9ab413ed..86fa3d08 100644 --- a/server/utils/config.js +++ b/server/utils/config.js @@ -29,8 +29,8 @@ const schema = Joi.object().keys({ captchaEnabled: Joi.bool().default(false), captchaApiKey: Joi.string().allow(''), captchaSiteKey: Joi.string().allow(''), - captchaBypassKey: Joi.string() - // mediaUploadUrl: Joi.string().uri({ scheme: ['http', 'https'] }).allow('').default('') + captchaBypassKey: Joi.string(), + mediaUploadUrl: Joi.string().uri({ scheme: ['http', 'https'] }).allow('').default('') }) const captchaEnabled = getBoolean(process.env.CAPTCHA_ENABLED) @@ -55,8 +55,8 @@ const config = { captchaEnabled, captchaApiKey: captchaEnabled ? process.env.CAPTCHA_API_KEY : '', captchaSiteKey: captchaEnabled ? process.env.CAPTCHA_SITE_KEY : '', - captchaBypassKey: process.env.CAPTCHA_BYPASS_KEY - // mediaUploadUrl: process.env.MEDIA_UPLOAD_URL + captchaBypassKey: process.env.CAPTCHA_BYPASS_KEY, + mediaUploadUrl: process.env.MEDIA_UPLOAD_URL } // Validate config