forked from coolaj86/goldilocks.js
58 lines
1.8 KiB
JavaScript
58 lines
1.8 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
module.exports.create = function (deps, config) {
|
||
|
var stunnel = require('stunnel');
|
||
|
var activeTunnels = {};
|
||
|
|
||
|
function addToken(data) {
|
||
|
if (!data.tunnelUrl) {
|
||
|
var decoded;
|
||
|
try {
|
||
|
decoded = JSON.parse(new Buffer(data.jwt.split('.')[1], 'base64').toString('ascii'));
|
||
|
} catch (err) {
|
||
|
console.warn('invalid web token given to tunnel manager', err);
|
||
|
return;
|
||
|
}
|
||
|
if (!decoded.aud) {
|
||
|
console.warn('tunnel manager given token with no tunnelUrl or audience');
|
||
|
return;
|
||
|
}
|
||
|
data.tunnelUrl = 'wss://' + decoded.aud + '/';
|
||
|
}
|
||
|
|
||
|
if (!activeTunnels[data.tunnelUrl]) {
|
||
|
console.log('creating new tunnel client for', data.tunnelUrl);
|
||
|
// We create the tunnel without an initial token so we can append the token and
|
||
|
// get the promise that should tell us more about if it worked or not.
|
||
|
activeTunnels[data.tunnelUrl] = stunnel.connect({
|
||
|
stunneld: data.tunnelUrl
|
||
|
, net: deps.tunnel.net
|
||
|
// NOTE: the ports here aren't that important since we are providing a custom
|
||
|
// `net.createConnection` that doesn't actually use the port. What is important
|
||
|
// is that any services we are interested in are listed in this object and have
|
||
|
// a '*' sub-property.
|
||
|
, services: {
|
||
|
https: { '*': 443 }
|
||
|
, http: { '*': 80 }
|
||
|
, smtp: { '*': 25 }
|
||
|
, smtps: { '*': 587 /*also 465/starttls*/ }
|
||
|
, ssh: { '*': 22 }
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
console.log('appending token to tunnel at', data.tunnelUrl);
|
||
|
return activeTunnels[data.tunnelUrl].append(data.jwt);
|
||
|
}
|
||
|
|
||
|
if (typeof config.tunnel === 'string') {
|
||
|
config.tunnel.split(',').forEach(function (jwt) {
|
||
|
addToken({ jwt: jwt, owner: 'config' });
|
||
|
});
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
add: addToken
|
||
|
};
|
||
|
};
|