"use strict"; const Promise = require("bluebird"); const defaultValue = require("default-value"); const errors = require("../errors"); module.exports = function ({ uiaTracker }) { return function (options) { if (options.flows == null || options.flows.length === 0) { throw new Error("At least one authentication flow must be defined"); } else { let required = defaultValue(options.required, true); return function userInteractiveAuthenticationMiddleware(req, res, next) { if (req.body.auth != null && req.body.auth.session != null) { let authenticationData = req.body.auth; /* FIXME: Riot currently doesn't pass back the session ID it was handed: https://github.com/vector-im/riot-web/issues/8458 - need to work around this*/ let sessionId = authenticationData.session; let authenticationType = authenticationData.type; return Promise.try(() => { if (authenticationType != null) { return uiaTracker.performAuthentication({ sessionId: sessionId, type: authenticationType, data: authenticationData }); } else { /* Client re-requested authentication session state without providing credentials; they most likely completed an out-of-band stage. */ return uiaTracker.getStatus({ sessionId }); } }).then((status) => { if (status.completed) { req.uiaSessionId = sessionId; return next(); } else { throw new errors.UIARequired("More authentication steps are required", { noErrorCode: true, errorMeta: status.sessionData }); } }); } else { /* Workaround for Riot violating spec: https://github.com/vector-im/riot-web/issues/8458#issuecomment-488839052 */ let riotAttempt = (req.body.auth != null); if (required || riotAttempt) { return Promise.try(() => { return uiaTracker.createSession({ flows: options.flows, }); }).then((sessionData) => { throw new errors.UIARequired("User-Interactive Authentication is required for this endpoint", { noErrorCode: true, errorMeta: sessionData }); }); } else { return next(); } } }; } }; }; /* MARKER: If successful: either let through request (if all stages completed), or send back a 401 with updated "completed" list Authentication method handlers are defined on the uiaTracker itself Also need to remove the `tx = knex` from db modules errorMeta: { flows: [], params: {}, session: sessionId } */ /* MARKER: Store flows/params in UIA tracker, send flows/params to user, write logic for subsequent UIA requests that interacts with the UIA tracker... also add code for UIA initialization where it is *optional* to do so */