oidc: enable auto login when a token is provided

This commit is contained in:
Johannes Zellner
2024-04-03 18:11:21 +02:00
parent 91d3980e3b
commit 2f6a66dbd7
2 changed files with 54 additions and 4 deletions
+28 -1
View File
@@ -518,6 +518,33 @@ function interactionLogin(provider) {
debug(`interactionLogin: for OpenID client ${clientId} from ${ip}`);
// This is the auto login via token hack
if (req.body.token) {
if (typeof req.body.token !== 'string') return next(new HttpError(400, 'token must be string if provided'));
const token = await tokens.getByAccessToken(req.body.token);
if (!token) return next(new HttpError(401, 'No such token'));
const user = await users.get(token.identifier);
if (!user) return next(new HttpError(401,'User not found'));
if (!user.active) return next(new HttpError(401,'User not active'));
const result = {
login: {
accountId: user.id,
},
};
const [interactionFinishError, redirectTo] = await safe(provider.interactionResult(req, res, result));
if (interactionFinishError) return next(new HttpError(500, interactionFinishError));
const auditSource = AuditSource.fromOidcRequest(req);
await eventlog.add(user.ghost ? eventlog.ACTION_USER_LOGIN_GHOST : eventlog.ACTION_USER_LOGIN, auditSource, { userId: user.id, user: users.removePrivateFields(user), appId: clientId });
if (!user.ghost) safe(users.notifyLoginLocation(user, ip, userAgent, auditSource), { debug });
return res.status(200).send({ redirectTo });
}
if (!req.body.username || typeof req.body.username !== 'string') return next(new HttpError(400, 'A username must be non-empty string'));
if (!req.body.password || typeof req.body.password !== 'string') return next(new HttpError(400, 'A password must be non-empty string'));
if ('totpToken' in req.body && typeof req.body.totpToken !== 'string') return next(new HttpError(400, 'totpToken must be a string' ));
@@ -526,7 +553,7 @@ function interactionLogin(provider) {
const verifyFunc = username.indexOf('@') === -1 ? users.verifyWithUsername : users.verifyWithEmail;
const [verifyError, user] = await safe(verifyFunc(username, password, users.AP_WEBADMIN, { totpToken, skipTotpCheck: false }));
const [verifyError, user] = await safe(verifyFunc(username, password, users.AP_WEBADMIN, { totpToken, skipTotpCheck: false }));
if (verifyError && verifyError.reason === BoxError.INVALID_CREDENTIALS) return next(new HttpError(401, verifyError.message));
if (verifyError && verifyError.reason === BoxError.NOT_FOUND) return next(new HttpError(401, 'Username and password does not match'));
if (verifyError) return next(new HttpError(500, verifyError));
+26 -3
View File
@@ -105,10 +105,9 @@ document.getElementById('loginForm').addEventListener('submit', function (event)
document.getElementById('internalError').classList.add('hide');
document.getElementById('busyIndicator').classList.remove('hide');
var apiUrl = '<%= submitUrl %>';
console.log('submit', apiUrl);
const apiUrl = '<%= submitUrl %>';
var body = {
const body = {
username: document.getElementById('inputUsername').value,
password: document.getElementById('inputPassword').value,
totpToken: document.getElementById('inputTotpToken').value
@@ -150,6 +149,30 @@ document.getElementById('loginForm').addEventListener('submit', function (event)
});
});
const token = location.search.slice(1);
if (token) {
console.log('got token do auto login', token);
const apiUrl = '<%= submitUrl %>';
let res;
fetch(apiUrl, {
method: 'POST',
body: JSON.stringify({ token: token }),
headers: { 'Content-type': 'application/json; charset=UTF-8' }
}).then(function (response) {
res = response;
return res.json(); // we always return objects
}).then(function (data) {
if (data.redirectTo) window.location.href = data.redirectTo;
else console.log('login success but missing redirectTo in data:', data);
}).catch(function (error) {
document.getElementById('internalError').classList.remove('hide');
document.getElementById('busyIndicator').classList.add('hide');
console.warn(error, res);
});
}
</script>
</body>