diff --git a/src/oidc.js b/src/oidc.js index cd0c3de20..f22554cdf 100644 --- a/src/oidc.js +++ b/src/oidc.js @@ -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)); diff --git a/src/oidc_templates/login.ejs b/src/oidc_templates/login.ejs index b75dca9ca..32cf01852 100644 --- a/src/oidc_templates/login.ejs +++ b/src/oidc_templates/login.ejs @@ -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); + }); +} +