diff --git a/src/nginxconfig.ejs b/src/nginxconfig.ejs index 25950a091..f0f09e4c2 100644 --- a/src/nginxconfig.ejs +++ b/src/nginxconfig.ejs @@ -303,7 +303,7 @@ server { proxy_set_header Content-Length ""; } - location ~ ^/(logout|callback)$ { + location ~ ^/(login|logout|callback)$ { proxy_pass http://127.0.0.1:3001; } @@ -314,7 +314,7 @@ server { if ($http_user_agent ~* "container") { return 401; } - return 302 "https://<%= proxyAuth.oidcEndpoint %>/openid/auth?client_id=<%= proxyAuth.oidcClientId %>&scope=openid profile email&response_type=code&redirect_uri=https://<%= vhost %>/callback"; + return 302 "/login"; } location <%= proxyAuth.location %> { @@ -370,7 +370,7 @@ server { proxy_set_header Content-Length ""; } - location ~ ^/(logout|callback)$ { + location ~ ^/(login|logout|callback)$ { proxy_pass http://127.0.0.1:3001; } @@ -382,7 +382,7 @@ server { return 401; } - return 302 "https://<%= proxyAuth.oidcEndpoint %>/openid/auth?client_id=<%= proxyAuth.oidcClientId %>&scope=openid profile email&response_type=code&redirect_uri=https://<%= vhost %>/callback"; + return 302 "/login"; } location / { diff --git a/src/oidc_templates/login.ejs b/src/oidc_templates/login.ejs index 3b1696e04..c05dec411 100644 --- a/src/oidc_templates/login.ejs +++ b/src/oidc_templates/login.ejs @@ -6,9 +6,9 @@ {{ login.loginTo }} <%= name %> - - - + + + diff --git a/src/oidc_templates/proxyauth_login.ejs b/src/oidc_templates/proxyauth_login.ejs new file mode 100644 index 000000000..2bd40f986 --- /dev/null +++ b/src/oidc_templates/proxyauth_login.ejs @@ -0,0 +1,84 @@ + + + + + + + {{ login.loginTo }} <%= name %> + + + + + + + + + + + + + + + + +
+
+
+
+
+ +
+

{{ login.loginTo }} <%= name %>

+
+
+
+
+
+ Proceed +
+
+
+
+ + +
+ + + diff --git a/src/proxyauth.js b/src/proxyauth.js index aea35e495..69300f63e 100644 --- a/src/proxyauth.js +++ b/src/proxyauth.js @@ -11,18 +11,23 @@ const apps = require('./apps.js'), assert = require('assert'), basicAuth = require('basic-auth'), blobs = require('./blobs.js'), + branding = require('./branding.js'), constants = require('./constants.js'), dashboard = require('./dashboard.js'), debug = require('debug')('box:proxyAuth'), + ejs = require('ejs'), express = require('express'), + fs = require('fs'), hat = require('./hat.js'), http = require('http'), HttpError = require('connect-lastmile').HttpError, HttpSuccess = require('connect-lastmile').HttpSuccess, jwt = require('jsonwebtoken'), + marked = require('marked'), middleware = require('./middleware'), oidc = require('./oidc.js'), safe = require('safetydance'), + translation = require('./translation.js'), users = require('./users.js'), util = require('util'); @@ -109,6 +114,29 @@ function auth(req, res, next) { next(new HttpSuccess(200, {})); } +async function login(req, res, next) { + const appId = req.headers['x-app-id'] || ''; + if (!appId) return next(new HttpError(503, 'Nginx misconfiguration')); + + const [error, app] = await safe(apps.get(appId)); + if (error) return next(new HttpError(403, 'No such app')); + + const dashboardFqdn = (await dashboard.getLocation()).fqdn; + const options = { + oidcEndpoint: `https://${dashboardFqdn}`, + loginUrl: `https://${dashboardFqdn}/openid/auth?client_id=${appId}&scope=openid profile email&response_type=code&redirect_uri=https://${app.fqdn}/callback`, + iconUrl: `https://${dashboardFqdn}${app.iconUrl}`, + name: app.label || app.fqdn, + footer: marked.parse(await branding.renderFooter()) + }; + + const translationAssets = await translation.getTranslations(); + const template = fs.readFileSync(__dirname + '/oidc_templates/proxyauth_login.ejs', 'utf-8'); + const html = ejs.render(translation.translate(template, translationAssets.translations || {}, translationAssets.fallback || {}), options); + + return res.send(html); +} + async function callback(req, res, next) { if (!req.query.code) return next(new HttpError(400, 'missing query argument "code"')); @@ -151,12 +179,9 @@ async function logout(req, res, next) { res.clearCookie('authToken'); - const oidcProviderFqdn = (await dashboard.getLocation()).fqdn; - const oidcLoginURI = `https://${oidcProviderFqdn}/openid/auth?client_id=${app.id}&scope=openid profile email&response_type=code&redirect_uri=https://${app.fqdn}/callback`; - // when we have no path, redirect to the login page. we cannot redirect to '/' because browsers will immediately serve up the cached page // if a path is set, we can assume '/' is a public page - res.redirect(302, app.manifest.addons.proxyAuth.path ? '/' : oidcLoginURI); + res.redirect(302, app.manifest.addons.proxyAuth.path ? '/' : '/login'); } // provides webhooks for the auth wall @@ -175,6 +200,7 @@ function initializeAuthwallExpressSync() { .use(router) .use(middleware.lastMile()); + router.get ('/login', login); router.get ('/callback', callback, authorize); router.get ('/auth', jwtVerify, authorizationHeader, auth); // called by nginx before accessing protected page router.get ('/logout', logout);