You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
79 lines
2.7 KiB
JavaScript
79 lines
2.7 KiB
JavaScript
"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 */ |