@@ -11,6 +11,7 @@ import { StatusCodes } from 'http-status-codes'
1111import Joi from 'joi'
1212
1313import { createLogger } from '~/src/server/common/helpers/logging/logger.js'
14+ import { createJoiError } from '~/src/server/helpers/error-helper.js'
1415import { publishSaveAndExitEvent } from '~/src/server/messaging/publish.js'
1516import {
1617 confirmationViewModel ,
@@ -26,7 +27,10 @@ import {
2627 resumeSuccessViewModel ,
2728 validatePayloadSchema
2829} from '~/src/server/models/save-and-exit.js'
29- import { getPayloadFromFlash } from '~/src/server/routes/save-and-exit-helper.js'
30+ import {
31+ getPayloadFromFlash ,
32+ hasState
33+ } from '~/src/server/routes/save-and-exit-helper.js'
3034import {
3135 getFormMetadata ,
3236 getFormMetadataById ,
@@ -40,6 +44,7 @@ const maxInvalidPasswordAttempts = 5
4044const ERROR_BASE_URL = '/resume-form-error'
4145
4246// View paths
47+ const SAVE_AND_EXIT_DETAILS = 'save-and-exit/details'
4348const RESUME_ERROR = 'save-and-exit/resume-error'
4449const RESUME_ERROR_LOCKED = 'save-and-exit/resume-error-locked'
4550const RESUME_PASSWORD_PATH = 'save-and-exit/resume-password'
@@ -52,6 +57,19 @@ export function getPasswordAttemptsLeft(attemptsSoFar) {
5257 return maxInvalidPasswordAttempts - attemptsSoFar
5358}
5459
60+ /**
61+ * @param {Partial<{ errors?: { text: string, href: string }[]}> } model
62+ * @param {{ href: string, text: string } } error
63+ */
64+ export function addError ( model , error ) {
65+ if ( model . errors ) {
66+ model . errors . push ( error )
67+ } else {
68+ model . errors = [ error ]
69+ }
70+ return model
71+ }
72+
5573export default [
5674 /**
5775 * @satisfies {ServerRoute<{ Params: SaveAndExitParams }> }
@@ -70,6 +88,13 @@ export default [
7088 // The current page state may be invalid so we don't want to push into the cache as normal properties.
7189 const cacheService = getCacheService ( request . server )
7290 const formState = await cacheService . getState ( request )
91+
92+ // Handle the user navigating back from previously submitting a save-and-exit. The state has been cleared
93+ // so just show the form from the start
94+ if ( ! hasState ( formState ) ) {
95+ return h . redirect ( model . serviceUrl )
96+ }
97+
7398 const pagePayload = getPayloadFromFlash ( request )
7499 const currentPagePayload = Array . isArray ( pagePayload )
75100 ? { }
@@ -98,7 +123,9 @@ export default [
98123 // Clear any previous save and exit session state
99124 request . yar . clear ( getKey ( slug , status ) )
100125
101- return h . view ( 'save-and-exit/details' , model )
126+ return h
127+ . view ( SAVE_AND_EXIT_DETAILS , model )
128+ . header ( 'Cache-Control' , 'no-cache, no-store, must-revalidate' )
102129 } ,
103130 options : {
104131 validate : {
@@ -126,6 +153,23 @@ export default [
126153 }
127154 const state = await cacheService . getState ( request )
128155
156+ const statusPath = status ? `/${ status } ` : ''
157+
158+ // Handle the user navigating back from previously submitting a save-and-exit. The state has been cleared
159+ // so we need to warn the user
160+ if ( ! hasState ( state ) ) {
161+ const model = detailsViewModel (
162+ metadata ,
163+ status ,
164+ /** @type {SaveAndExitPayload } */ ( payload ) ,
165+ createJoiError (
166+ 'general' ,
167+ 'Your information is no longer available. Return to the start of the form.'
168+ )
169+ )
170+ return h . view ( SAVE_AND_EXIT_DETAILS , model ) . takeover ( )
171+ }
172+
129173 await publishSaveAndExitEvent (
130174 metadata . id ,
131175 metadata . title ,
@@ -142,8 +186,6 @@ export default [
142186 request . yar . set ( getKey ( slug , status ) , email )
143187
144188 // Redirect to the save and exit confirmation page
145- const statusPath = status ? `/${ status } ` : ''
146-
147189 return h . redirect ( `/save-and-exit/${ slug } /confirmation${ statusPath } ` )
148190 } ,
149191 options : {
@@ -159,7 +201,7 @@ export default [
159201 err
160202 )
161203
162- return h . view ( 'save-and-exit/details' , model ) . takeover ( )
204+ return h . view ( SAVE_AND_EXIT_DETAILS , model ) . takeover ( )
163205 } ,
164206 params : paramsSchema ,
165207 payload : payloadSchema
0 commit comments