From 06182da61c065ec83222cd1616343c943d5df922 Mon Sep 17 00:00:00 2001 From: Will White Date: Wed, 29 Jul 2015 16:43:23 -0400 Subject: [PATCH] get_user helper to determine owner of the provided access_token. --- lib/get_user.js | 20 ++++++++++++++++++++ lib/make_service.js | 6 +++++- test/get_user.js | 37 +++++++++++++++++++++++++++++++++++++ test/test.js | 12 +++++++----- 4 files changed, 69 insertions(+), 6 deletions(-) create mode 100644 lib/get_user.js create mode 100644 test/get_user.js diff --git a/lib/get_user.js b/lib/get_user.js new file mode 100644 index 00000000..bfccfa9d --- /dev/null +++ b/lib/get_user.js @@ -0,0 +1,20 @@ +'use strict'; + +function getUser(token) { + var data = token.split('.')[1]; + data = data.replace(/-/g, '+').replace(/_/g, '/'); + + var mod = data.length % 4; + if (mod === 2) data += '=='; + if (mod === 3) data += '='; + if (mod === 1 || mod > 3) return null; + + try { + data = (new Buffer(data, 'base64')).toString('utf8'); + return JSON.parse(data).u; + } catch(err) { + return null; + } +} + +module.exports = getUser; diff --git a/lib/make_service.js b/lib/make_service.js index 10f280b5..83c381fc 100644 --- a/lib/make_service.js +++ b/lib/make_service.js @@ -2,6 +2,7 @@ var invariant = require('invariant'); var constants = require('./constants'); +var getUser = require('./get_user'); function makeService(name) { @@ -9,7 +10,10 @@ function makeService(name) { this.name = name; invariant(typeof accessToken === 'string', - 'accessToken required to instantiate MapboxDirections'); + 'accessToken required to instantiate Mapbox client'); + + this.user = getUser(accessToken); + invariant(!!this.user, 'could not determine user from provided accessToken'); this.accessToken = accessToken; this.endpoint = constants.DEFAULT_ENDPOINT; diff --git a/test/get_user.js b/test/get_user.js new file mode 100644 index 00000000..d359960f --- /dev/null +++ b/test/get_user.js @@ -0,0 +1,37 @@ +/* eslint no-shadow: 0 */ +'use strict'; + +var test = require('tap').test; +var getUser = require('../lib/get_user'); + +test('getUser', function(t) { + t.test('public token', function(assert) { + var token = 'pk.eyJ1Ijoid29yYmx5IiwiYSI6ImQzMjFkZWRkN2IzNzc5M2MzZDgyNTIzZTRhM2E5MDE3In0.IIrNhFTaOiW-Ykw_J-yQbg'; + assert.equal(getUser(token), 'worbly', 'success'); + assert.end(); + }); + + t.test('secret token', function(assert) { + var token = 'sk.eyJ1Ijoid29yYmx5IiwiYSI6ImQwNTg3OGU2MWI5NTI5MjIyNmI1YzNhNWE4ZGFlMmFiIn0.-47f43O4Cz5-vEd0gXzJ3w'; + assert.equal(getUser(token), 'worbly', 'success'); + assert.end(); + }); + + t.test('token padding', function(assert) { + var token = 'sk.eyJ1Ijoid29yYmx5IiwiYSI6ImQwNTg3OGU2MWI5NTI5MjIyNmI1YzNhNWE4ZGFlMmFiIn0=.-47f43O4Cz5-vEd0gXzJ3w'; + assert.equal(getUser(token), 'worbly', 'success'); + token = 'sk.eyJ1Ijoid29yYmx5IiwiYSI6ImQwNTg3OGU2MWI5NTI5MjIyNmI1YzNhNWE4ZGFlMmFiIn0===.-47f43O4Cz5-vEd0gXzJ3w'; + assert.equal(getUser(token), 'worbly', 'success'); + assert.end(); + }); + + t.test('bogus token', function(assert) { + var token = 'sk.eyJ1Ijoid29yYmx5IiwiYSI6ImQwNTg3OGU2MWI5NTI5MjIyNmI1YzNhNWE4ZGFlMmFiIn0==.-47f43O4Cz5-vEd0gXzJ3w'; + assert.notOk(getUser(token), 'bad length success'); + token = 'sk.eyJ1Ijoid29yYmx5IiwiYSI6ImQwNTg3OGU2MWI5NTI5MjIyNmI1YzNhNWE4ZGFlMmFiI12.-47f43O4Cz5-vEd0gXzJ3w'; + assert.notOk(getUser(token), 'cannot parse success'); + assert.end(); + }); + + t.end(); +}); diff --git a/test/test.js b/test/test.js index b0888c42..485152a2 100644 --- a/test/test.js +++ b/test/test.js @@ -19,27 +19,29 @@ test('prerequisites', function(t) { t.end(); }); +var deadToken = 'pk.eyJ1Ijoid29yYmx5IiwiYSI6ImQzMjFkZWRkN2IzNzc5M2MzZDgyNTIzZTRhM2E5MDE3In0.IIrNhFTaOiW-Ykw_J-yQbg'; + test('MapboxClient', function(t) { t.throws(function() { var client = new MapboxClient(); t.notOk(client); }, /accessToken required to instantiate MapboxClient/); - var client = new MapboxClient('token'); + var client = new MapboxClient(deadToken); t.ok(client); - t.equal(client.accessToken, 'token'); + t.equal(client.accessToken, deadToken); t.end(); }); test('MapboxClient - custom endpoint', function(t) { t.throws(function() { - var client = new MapboxClient('foo', 1); + var client = new MapboxClient(deadToken, 1); t.notOk(client); }, /options/); t.throws(function() { - var client = new MapboxClient('foo', { endpoint: 1 }); + var client = new MapboxClient(deadToken, { endpoint: 1 }); t.notOk(client); }, /endpoint/); - var customClient = new MapboxClient('foo', { endpoint: 'foo.bar' }); + var customClient = new MapboxClient(deadToken, { endpoint: 'foo.bar' }); t.equal(customClient.endpoint, 'foo.bar', 'receives an endpoint from options'); t.end(); });