Files
cloudron-box/oauthproxy.js
T

119 lines
3.7 KiB
JavaScript
Raw Normal View History

2015-01-19 16:26:46 +01:00
#!/usr/bin/env node
'use strict';
2015-01-20 17:42:40 +01:00
require('supererror')({ splatchError: true });
2015-01-19 16:26:46 +01:00
var express = require('express'),
url = require('url'),
2015-01-19 19:39:48 +01:00
async = require('async'),
assert = require('assert'),
2015-01-19 23:19:24 +01:00
debug = require('debug')('box:proxy'),
2015-01-19 16:26:46 +01:00
proxy = require('proxy-middleware'),
session = require('cookie-session'),
2015-01-19 19:39:48 +01:00
database = require('./src/database.js'),
2015-01-19 21:14:22 +01:00
appdb = require('./src/appdb.js'),
clientdb = require('./src/clientdb.js'),
config = require('./config.js'),
2015-01-19 16:26:46 +01:00
http = require('http');
var gSessions = {};
2015-01-19 19:25:40 +01:00
var gProxyMiddlewareCache = {};
2015-01-19 16:26:46 +01:00
var gApp = express();
var gHttpServer = http.createServer(gApp);
2015-01-19 19:25:40 +01:00
var CALLBACK_URI = '/callback';
2015-01-19 19:39:48 +01:00
var PORT = 4000;
2015-01-19 19:25:40 +01:00
2015-01-19 19:39:48 +01:00
function startServer(callback) {
assert(typeof callback === 'function');
2015-01-19 16:26:46 +01:00
2015-01-19 19:39:48 +01:00
gHttpServer.on('error', console.error);
2015-01-19 16:26:46 +01:00
2015-01-19 19:39:48 +01:00
gApp.use(session({
keys: ['blue', 'cheese', 'is', 'something']
}));
2015-01-19 16:26:46 +01:00
2015-01-19 19:39:48 +01:00
gApp.use(function (req, res, next) {
if (req.session && gSessions[req.session.sessid]) return next();
2015-01-19 16:26:46 +01:00
2015-01-19 19:39:48 +01:00
if (req.path === CALLBACK_URI) {
// FIXME we need to exchange the authCode and verify it
req.session.sessid = req.query.authCode;
2015-01-19 16:26:46 +01:00
2015-01-19 19:39:48 +01:00
// this is a simple in memory auth store
gSessions[req.session.sessid] = 'ok';
2015-01-19 19:25:40 +01:00
2015-01-19 23:19:24 +01:00
debug('user verified.');
2015-01-19 19:39:48 +01:00
// now redirect to the actual initially requested URL
res.redirect(req.session.returnTo);
} else {
var port = parseInt(req.headers['x-cloudron-proxy-port'], 10);
2015-01-19 19:25:40 +01:00
2015-01-20 17:42:40 +01:00
if (!Number.isFinite(port)) {
console.error('Failed to parse nginx proxy header to get app port.');
return res.send(500, 'Routing error. No forwarded port.');
}
2015-01-19 19:25:40 +01:00
2015-01-20 17:42:40 +01:00
debug('begin verifying user for app on port %s.', port);
2015-01-19 23:19:24 +01:00
2015-01-19 21:14:22 +01:00
appdb.getByHttpPort(port, function (error, result) {
2015-01-20 17:42:40 +01:00
if (error) {
console.error('Unknown app.', error);
return res.send(500, 'Unknown app.');
}
2015-01-19 16:26:46 +01:00
2015-01-20 17:48:48 +01:00
clientdb.getByAppId('proxy-' + result.id, function (error, result) {
2015-01-20 17:42:40 +01:00
if (error) {
console.error('Unkonwn OAuth client.', error);
return res.send(500, 'Unknown OAuth client.');
}
2015-01-19 16:26:46 +01:00
2015-01-19 21:14:22 +01:00
req.session.port = port;
req.session.returnTo = result.redirectURI + req.path;
2015-01-19 21:14:22 +01:00
2015-02-11 17:04:04 -08:00
var callbackUrl = result.redirectURI + CALLBACK_URI;
2015-01-19 23:19:24 +01:00
var scope = 'profile,roleUser';
2015-02-11 17:04:04 -08:00
var oauthLogin = config.adminOrigin() + '/api/v1/oauth/dialog/authorize?response_type=code&client_id=' + result.id + '&redirect_uri=' + callbackUrl + '&scope=' + scope;
2015-01-19 21:14:22 +01:00
2015-01-19 23:19:24 +01:00
debug('begin OAuth flow for client %s.', result.name);
2015-01-19 21:14:22 +01:00
// begin the OAuth flow
res.redirect(oauthLogin);
});
});
2015-01-19 19:39:48 +01:00
}
});
2015-01-19 19:25:40 +01:00
2015-01-19 19:39:48 +01:00
gApp.use(function (req, res, next) {
var port = req.session.port;
2015-01-19 19:25:40 +01:00
2015-01-19 23:19:24 +01:00
debug('proxy request for port %s with path %s.', port, req.path);
2015-01-19 19:39:48 +01:00
var proxyMiddleware = gProxyMiddlewareCache[port];
if (!proxyMiddleware) {
console.log('Adding proxy middleware for port %d', port);
2015-01-19 19:25:40 +01:00
2015-01-19 19:39:48 +01:00
proxyMiddleware = proxy(url.parse('http://127.0.0.1:' + port));
gProxyMiddlewareCache[port] = proxyMiddleware;
}
proxyMiddleware(req, res, next);
});
gHttpServer.listen(PORT, callback);
}
async.series([
database.initialize,
startServer
], function (error) {
if (error) {
console.error('Failed to start proxy server.', error);
process.exit(1);
}
2015-01-19 16:26:46 +01:00
console.log('Proxy server listening...');
});