@dwp/govuk-casa
Version:
A framework for building GOVUK Collect-And-Submit-Applications
85 lines • 4.54 kB
JavaScript
;
// Determine where to take the user next
// We assume that the waypoint has been validated prior to reaching this
// middleware.
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const Plan_js_1 = __importDefault(require("../lib/Plan.js"));
const JourneyContext_js_1 = __importDefault(require("../lib/JourneyContext.js"));
const waypoint_url_js_1 = __importDefault(require("../lib/waypoint-url.js"));
const logger_js_1 = __importDefault(require("../lib/logger.js"));
const constants_js_1 = require("../lib/constants.js");
const log = (0, logger_js_1.default)("middleware:progress-journey");
const saveAndRedirect = (session, journeyContext, url, res, next) => {
JourneyContext_js_1.default.putContext(session, journeyContext, {
userInfo: {
casaRequestPhase: constants_js_1.REQUEST_PHASE_REDIRECT,
},
});
session.save((err) => {
if (err) {
next(err);
}
res.redirect(302, url);
});
};
exports.default = ({ waypoint, plan }) => [
(req, res, next) => {
// Determine the next available waypoint after the current one
const traversed = plan.traverse(req.casa.journeyContext);
const currentIndex = traversed.indexOf(waypoint);
const nextIndex = Math.max(currentIndex < 0 ? traversed.length - 1 : 0, Math.min(currentIndex + 1, traversed.length - 1));
const nextWaypoint = traversed[parseInt(nextIndex, 10)];
log.trace(`currentIndex = ${currentIndex}, nextIndex = ${nextIndex}, currentWaypoint = ${waypoint}, nextWaypoint = ${nextWaypoint}`);
// Edit mode
// Attempt to take the user back to their original URL. We rely on the
// `steer-journey` middleware to prevent the user going too far ahead in
// their permitted journey. Bear in mind that the `editOrigin` may not be
// a waypoint at all, but a route path for a custom endpoint, so we can't
// safely do a traversal check here.
//
// The edit mode URL params will be kept on this redirect. This means the
// user can keep "jumping" to the next _changed_ waypoint, until they get
// back to the original URL.
//
// Devs should use the `events` mechanism to mark waypoints as invalid if
// they want to force the user to re-visit particular waypoints during this
// "jumping" phase.
if (req.casa.editMode && req.casa.editOrigin) {
const url = new URL(req.casa.editOrigin, "https://placeholder.test/");
url.searchParams.append("edit", "true");
url.searchParams.append("editorigin", req.casa.editOrigin);
const redirectUrl = (0, waypoint_url_js_1.default)({ waypoint: url.pathname }) + url.search.toString();
log.debug(`Edit mode detected; redirecting to ${redirectUrl}`);
return saveAndRedirect(req.session, req.casa.journeyContext, redirectUrl, res, next);
}
// If the next URL is an "exit node", we need to flag that node as
// being validated so that subsequent traversals of this journey continue
// correctly to any waypoints leading on from this one.
// This effectively says that the other Plan linked to by the exit node is
// complete, but of course that may not be the case.
// It would be prudent for developers to add a conditions to the route to
// check is this is the case, eg
// setRoute('a', 'b');
// setRoute('b', 'url:///otherapp/')
// setRoute('url:////otherapp/', 'c', (r, c) => checkIfOtherAppIsFinished())
if (Plan_js_1.default.isExitNode(nextWaypoint)) {
log.trace(`Next waypoint is an exit node; clearing validation state on ${nextWaypoint}`);
req.casa.journeyContext.clearValidationErrorsForPage(nextWaypoint);
}
// Construct the next url
const nextUrl = (0, waypoint_url_js_1.default)({
waypoint: nextWaypoint,
mountUrl: `${req.baseUrl}/`,
journeyContext: req.casa.journeyContext,
edit: req.casa.editMode,
editOrigin: req.casa.editOrigin,
});
// Save and move on
log.trace(`Redirecting to ${nextUrl}`);
return saveAndRedirect(req.session, req.casa.journeyContext, nextUrl, res, next);
},
];
//# sourceMappingURL=progress-journey.js.map