Created
September 20, 2012 20:02
-
-
Save jcoglan/3758017 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var child = require('child_process'), | |
fs = require('fs'), | |
http = require('http'), | |
qs = require('querystring'), | |
url = require('url'), | |
Proxy = require('./proxy'); | |
var extractToken = function(query, callback) { | |
var params = qs.parse(query), | |
token = params.access_token, | |
error = params.hasOwnProperty('error') ? new Error(params.error_description) : null; | |
if (error) error.type = params.error; | |
callback(error, token); | |
}; | |
var authenticate = function(target, clientId, scopes, callback) { | |
var uri = url.parse(target, true), | |
inline = (process.env.INLINE !== undefined), | |
browser, | |
server; | |
var receiver = http.createServer(function(request, response) { | |
Proxy.buffer(request, function() { | |
if (request.url !== '/') { | |
response.writeHead(404, {}); | |
return response.end(); | |
} | |
if (request.method === 'GET') { | |
fs.readFile(__dirname + '/receive.html', function(error, content) { | |
response.writeHead(200, {'Content-Type': 'text/html'}); | |
response.end(content, 'utf-8'); | |
}); | |
} | |
else if (request.method === 'POST') { | |
response.writeHead(200, {}); | |
response.end(); | |
receiver.close(); | |
extractToken(request.body, callback); | |
} | |
}); | |
}); | |
var proxy = Proxy.createPool(function(res) { | |
var hash = url.parse(res.headers.location || '').hash || ''; | |
if (res.statusCode < 301 || res.statusCode > 303 || !/\baccess_token=/.test(hash)) | |
return false; | |
browser.kill(); | |
proxy.close(); | |
extractToken(hash.substr(1), callback); | |
return true; | |
}); | |
server = inline ? proxy.forOrigin(uri.protocol + '//' + uri.host) : receiver; | |
server.listen(0, function() { | |
var addr = server.address(), | |
client = 'http://' + addr.address + ':' + addr.port + '/', | |
params = {client_id: clientId, redirect_uri: client, response_type: 'token', scope: scopes.join(' ')}; | |
var providerUrl = inline | |
? 'http://' + addr.address + ':' + addr.port + uri.pathname + (uri.search || '') | |
: target; | |
providerUrl += '?' + qs.stringify(params); | |
var cmds = {win32: 'cmd', darwin: 'open', other: 'xdg-open'}, | |
command = process.env.CMD || cmds[process.platform] || cmds.other, | |
args = (command === 'cmd') ? ['/c', 'start', '""', providerUrl] : [providerUrl], | |
options = {}; | |
if (inline) options.stdio = [0,2,2]; | |
browser = child.spawn(command, args, options); | |
}); | |
}; | |
// e.g. | |
authenticate('https://5apps.com/rs/oauth/jcoglan', 'vault', ['vault:rw'], function(error, token) { | |
console.log('TOKEN', token); | |
process.exit(); | |
}); | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var http = require('http'), | |
https = require('https'), | |
url = require('url'); | |
var Proxy = function(pool, origin) { | |
var uri = url.parse(origin); | |
this._server = http.createServer(function(request, response) { | |
var client = (uri.protocol === 'https:') ? https : http, | |
requri = url.parse(request.url); | |
request.headers.host = uri.host; | |
var req = client.request({ | |
host: uri.host, | |
port: uri.port, | |
method: request.method, | |
path: requri.pathname + (requri.search || ''), | |
headers: request.headers | |
}); | |
req.addListener('response', function(res) { | |
Proxy.buffer(res, function() { | |
pool.rewrite(res, function() { | |
if (pool.filter(res)) return; | |
delete res.headers['transfer-encoding']; | |
response.writeHead(res.statusCode, res.headers); | |
response.end(res.body); | |
}); | |
}); | |
}); | |
request.pipe(req); | |
}); | |
}; | |
['listen', 'close', 'address'].forEach(function(method) { | |
Proxy.prototype[method] = function() { | |
return this._server[method].apply(this._server, arguments); | |
}; | |
}); | |
var Pool = function(filter) { | |
this._filter = filter; | |
this._proxies = {}; | |
}; | |
Pool.prototype.close = function() { | |
for (var origin in this._proxies) this._proxies[origin].close(); | |
}; | |
Pool.prototype.filter = function(response) { | |
return this._filter(response); | |
}; | |
Pool.prototype.forOrigin = function(origin, filter) { | |
this._proxies[origin] = this._proxies[origin] || new Proxy(this, origin); | |
return this._proxies[origin]; | |
}; | |
Pool.prototype.listen = function(origin, callback) { | |
var proxy = this.forOrigin(origin), | |
addr = proxy.address(); | |
if (addr) return callback('http://' + addr.address + ':' + addr.port); | |
proxy.listen(0, function() { | |
var addr = proxy.address(); | |
callback('http://' + addr.address + ':' + addr.port); | |
}); | |
}; | |
Pool.prototype.rewrite = function(response, callback) { | |
var location = response.headers.location; | |
if (location === undefined) return callback(); | |
var uri = url.parse(location), | |
origin = uri.protocol + '//' + uri.host; | |
if (uri.hostname === '0.0.0.0') return callback(); | |
this.listen(origin, function(host) { | |
response.headers.location = host + uri.pathname + (uri.search || ''); | |
callback(); | |
}); | |
}; | |
Proxy.buffer = function(stream, callback) { | |
var body = ''; | |
stream.setEncoding('utf-8'); | |
stream.addListener('data', function(c) { body += c }); | |
stream.addListener('end', function() { | |
stream.body = body; | |
callback(); | |
}); | |
}; | |
Proxy.createPool = function(filter) { | |
return new Pool(filter); | |
}; | |
module.exports = Proxy; | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | |
<title>Receive token</title> | |
</head> | |
<body> | |
<p id="stat">Saving access token…</p> | |
<script type="text/javascript"> | |
var xhr = window.ActiveXObject | |
? new ActiveXObject("Microsoft.XMLHTTP") | |
: new XMLHttpRequest(); | |
xhr.open('POST', '/', true); | |
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); | |
xhr.onreadystatechange = function() { | |
if (xhr.readyState !== 4) return; | |
var status = document.getElementById('stat'); | |
status.innerHTML = 'You have successfully authenticated. Please close ' + | |
'this window and return to your shell.'; | |
}; | |
xhr.send(window.location.hash.substr(1)); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment