From 390498fefd19be6a5c3365fcb83ccb5857cfca28 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 9 Jul 2019 10:58:10 -0700 Subject: [PATCH] Remove auth --- modules/__tests__/_auth-test.js | 65 --------------- modules/__tests__/api-auth-test.js | 89 --------------------- modules/__tests__/setupTestFramework.js | 3 - modules/__tests__/utils/closeDatabase.js | 5 -- modules/__tests__/utils/withAuthHeader.js | 11 --- modules/__tests__/utils/withRevokedToken.js | 10 --- modules/__tests__/utils/withToken.js | 5 -- modules/actions/createAuth.js | 18 ----- modules/actions/serveAuth.js | 3 - modules/middleware/userToken.js | 42 ---------- modules/utils/__tests__/auth-test.js | 39 --------- modules/utils/auth.js | 86 -------------------- modules/utils/data.js | 9 --- package.json | 1 - yarn.lock | 80 ------------------ 15 files changed, 466 deletions(-) delete mode 100644 modules/__tests__/_auth-test.js delete mode 100644 modules/__tests__/api-auth-test.js delete mode 100644 modules/__tests__/setupTestFramework.js delete mode 100644 modules/__tests__/utils/closeDatabase.js delete mode 100644 modules/__tests__/utils/withAuthHeader.js delete mode 100644 modules/__tests__/utils/withRevokedToken.js delete mode 100644 modules/__tests__/utils/withToken.js delete mode 100644 modules/actions/createAuth.js delete mode 100644 modules/actions/serveAuth.js delete mode 100644 modules/middleware/userToken.js delete mode 100644 modules/utils/__tests__/auth-test.js delete mode 100644 modules/utils/auth.js delete mode 100644 modules/utils/data.js diff --git a/modules/__tests__/_auth-test.js b/modules/__tests__/_auth-test.js deleted file mode 100644 index f161e99..0000000 --- a/modules/__tests__/_auth-test.js +++ /dev/null @@ -1,65 +0,0 @@ -import request from 'supertest'; - -import createServer from '../createServer'; -import withRevokedToken from './utils/withRevokedToken'; -import withToken from './utils/withToken'; - -describe('The /_auth endpoint', () => { - let server; - beforeEach(() => { - server = createServer(); - }); - - describe('POST /_auth', () => { - it('creates a new auth token', done => { - request(server) - .post('/_auth') - .end((err, res) => { - expect(res.body).toHaveProperty('token'); - done(); - }); - }); - }); - - describe('GET /_auth', () => { - describe('with no auth', () => { - it('echoes back null', done => { - request(server) - .get('/_auth') - .end((err, res) => { - expect(res.body).toHaveProperty('auth'); - expect(res.body.auth).toBe(null); - done(); - }); - }); - }); - - describe('with a revoked auth token', () => { - it('echoes back null', done => { - withRevokedToken({ some: { scope: true } }, token => { - request(server) - .get('/_auth?token=' + token) - .end((err, res) => { - expect(res.body).toHaveProperty('auth'); - expect(res.body.auth).toBe(null); - done(); - }); - }); - }); - }); - - describe('with a valid auth token', () => { - it('echoes back the auth payload', done => { - withToken({ some: { scope: true } }, token => { - request(server) - .get('/_auth?token=' + token) - .end((err, res) => { - expect(res.body).toHaveProperty('auth'); - expect(typeof res.body.auth).toBe('object'); - done(); - }); - }); - }); - }); - }); -}); diff --git a/modules/__tests__/api-auth-test.js b/modules/__tests__/api-auth-test.js deleted file mode 100644 index 868efd7..0000000 --- a/modules/__tests__/api-auth-test.js +++ /dev/null @@ -1,89 +0,0 @@ -import request from 'supertest'; - -import createServer from '../createServer'; -import withAuthHeader from './utils/withAuthHeader'; -import withRevokedToken from './utils/withRevokedToken'; -import withToken from './utils/withToken'; - -describe('The /api/auth endpoint', () => { - let server; - beforeEach(() => { - server = createServer(); - }); - - describe('POST /api/auth', () => { - it('creates a new auth token', done => { - request(server) - .post('/api/auth') - .end((err, res) => { - expect(res.body).toHaveProperty('token'); - done(); - }); - }); - }); - - describe('GET /api/auth', () => { - describe('with no auth', () => { - it('echoes back null', done => { - request(server) - .get('/api/auth') - .end((err, res) => { - expect(res.body).toHaveProperty('auth'); - expect(res.body.auth).toBe(null); - done(); - }); - }); - }); - - describe('with a revoked auth token', () => { - it('echoes back null', done => { - withRevokedToken({ some: { scope: true } }, token => { - request(server) - .get('/api/auth?token=' + token) - .end((err, res) => { - expect(res.body).toHaveProperty('auth'); - expect(res.body.auth).toBe(null); - done(); - }); - }); - }); - }); - - describe('with a valid auth token', () => { - describe('in the query string', () => { - it('echoes back the auth payload', done => { - const scopes = { some: { scope: true } }; - - withToken(scopes, token => { - request(server) - .get('/api/auth?token=' + token) - .end((err, res) => { - expect(res.body).toHaveProperty('auth'); - expect(res.body.auth).toBeDefined(); - expect(res.body.auth.scopes).toMatchObject(scopes); - done(); - }); - }); - }); - }); - - describe('in the Authorization header', () => { - it('echoes back the auth payload', done => { - const scopes = { some: { scope: true } }; - - withAuthHeader(scopes, header => { - request(server) - .get('/api/auth') - .set({ Authorization: header }) - .end((err, res) => { - expect(res.body).toHaveProperty('auth'); - expect(res.body.auth).toBeDefined(); - expect(res.body.auth.scopes).toMatchObject(scopes); - done(); - }); - }); - }); - }); - }); - }); -}); diff --git a/modules/__tests__/setupTestFramework.js b/modules/__tests__/setupTestFramework.js deleted file mode 100644 index 72796e6..0000000 --- a/modules/__tests__/setupTestFramework.js +++ /dev/null @@ -1,3 +0,0 @@ -import closeDatabase from './utils/closeDatabase'; - -afterAll(closeDatabase); diff --git a/modules/__tests__/utils/closeDatabase.js b/modules/__tests__/utils/closeDatabase.js deleted file mode 100644 index 3e44474..0000000 --- a/modules/__tests__/utils/closeDatabase.js +++ /dev/null @@ -1,5 +0,0 @@ -import data from '../../utils/data'; - -export default function closeDatabase() { - data.quit(); -} diff --git a/modules/__tests__/utils/withAuthHeader.js b/modules/__tests__/utils/withAuthHeader.js deleted file mode 100644 index 97314a9..0000000 --- a/modules/__tests__/utils/withAuthHeader.js +++ /dev/null @@ -1,11 +0,0 @@ -import withToken from './withToken'; - -function encodeBase64(token) { - return Buffer.from(token).toString('base64'); -} - -export default function withAuthHeader(scopes, done) { - withToken(scopes, token => { - done(encodeBase64(token)); - }); -} diff --git a/modules/__tests__/utils/withRevokedToken.js b/modules/__tests__/utils/withRevokedToken.js deleted file mode 100644 index 900454e..0000000 --- a/modules/__tests__/utils/withRevokedToken.js +++ /dev/null @@ -1,10 +0,0 @@ -import { revokeToken } from '../../utils/auth'; -import withToken from './withToken'; - -export default function withRevokedToken(scopes, done) { - withToken(scopes, token => { - revokeToken(token).then(() => { - done(token); - }); - }); -} diff --git a/modules/__tests__/utils/withToken.js b/modules/__tests__/utils/withToken.js deleted file mode 100644 index 56df881..0000000 --- a/modules/__tests__/utils/withToken.js +++ /dev/null @@ -1,5 +0,0 @@ -import { createToken } from '../../utils/auth'; - -export default function withToken(scopes, done) { - createToken(scopes).then(done); -} diff --git a/modules/actions/createAuth.js b/modules/actions/createAuth.js deleted file mode 100644 index b4a5fd8..0000000 --- a/modules/actions/createAuth.js +++ /dev/null @@ -1,18 +0,0 @@ -import { createToken } from '../utils/auth'; - -const defaultScopes = {}; - -export default function createAuth(req, res) { - createToken(defaultScopes).then( - token => { - res.send({ token }); - }, - error => { - console.error(error); - - res.status(500).send({ - error: 'Unable to generate auth token' - }); - } - ); -} diff --git a/modules/actions/serveAuth.js b/modules/actions/serveAuth.js deleted file mode 100644 index 772df99..0000000 --- a/modules/actions/serveAuth.js +++ /dev/null @@ -1,3 +0,0 @@ -export default function serveAuth(req, res) { - res.send({ auth: req.user }); -} diff --git a/modules/middleware/userToken.js b/modules/middleware/userToken.js deleted file mode 100644 index ed37944..0000000 --- a/modules/middleware/userToken.js +++ /dev/null @@ -1,42 +0,0 @@ -import { verifyToken } from '../utils/auth'; - -function decodeBase64(string) { - return Buffer.from(string, 'base64').toString(); -} - -/** - * Sets req.user from the payload in the auth token in the request. - */ -export default function userToken(req, res, next) { - if (req.user !== undefined) { - return next(); - } - - const auth = req.get('Authorization'); - const token = auth && decodeBase64(auth); - - if (!token) { - req.user = null; - return next(); - } - - verifyToken(token).then( - payload => { - req.user = payload; - next(); - }, - error => { - if (error.name === 'JsonWebTokenError') { - res.status(403).send({ - error: `Bad auth token: ${error.message}` - }); - } else { - console.error(error); - - res.status(500).send({ - error: 'Unable to verify auth' - }); - } - } - ); -} diff --git a/modules/utils/__tests__/auth-test.js b/modules/utils/__tests__/auth-test.js deleted file mode 100644 index 5e9678d..0000000 --- a/modules/utils/__tests__/auth-test.js +++ /dev/null @@ -1,39 +0,0 @@ -import * as auth from '../auth'; - -describe('Auth API', () => { - beforeEach(done => { - auth.removeAllRevokedTokens().then(() => done(), done); - }); - - it('creates tokens with the right scopes', done => { - const scopes = { - blacklist: { - add: true, - remove: true - } - }; - - auth.createToken(scopes).then(token => { - auth.verifyToken(token).then(payload => { - expect(payload.jti).toEqual(expect.any(String)); - expect(payload.iss).toEqual(expect.any(String)); - expect(payload.iat).toEqual(expect.any(Number)); - expect(payload.scopes).toMatchObject(scopes); - done(); - }); - }); - }); - - it('refuses to verify revoked tokens', done => { - const scopes = {}; - - auth.createToken(scopes).then(token => { - auth.revokeToken(token).then(() => { - auth.verifyToken(token).then(payload => { - expect(payload).toBe(null); - done(); - }); - }); - }); - }); -}); diff --git a/modules/utils/auth.js b/modules/utils/auth.js deleted file mode 100644 index 07d1969..0000000 --- a/modules/utils/auth.js +++ /dev/null @@ -1,86 +0,0 @@ -import crypto from 'crypto'; -import jwt from 'jsonwebtoken'; - -import data from './data'; -import { privateKey, publicKey } from './secret'; - -function getCurrentSeconds() { - return Math.floor(Date.now() / 1000); -} - -function createTokenId() { - return crypto.randomBytes(16).toString('hex'); -} - -export function createToken(scopes = {}) { - return new Promise((resolve, reject) => { - const payload = { - jti: createTokenId(), - iss: 'https://unpkg.com', - iat: getCurrentSeconds(), - scopes - }; - - jwt.sign(payload, privateKey, { algorithm: 'RS256' }, (error, token) => { - if (error) { - reject(error); - } else { - resolve(token); - } - }); - }); -} - -const revokedTokensSet = 'revoked-tokens'; - -export function verifyToken(token) { - return new Promise((resolve, reject) => { - const options = { algorithms: ['RS256'] }; - - jwt.verify(token, publicKey, options, (error, payload) => { - if (error) { - reject(error); - } else { - if (payload.jti) { - data.sismember(revokedTokensSet, payload.jti, (error, value) => { - if (error) { - reject(error); - } else { - resolve(value === 0 ? payload : null); - } - }); - } else { - resolve(null); - } - } - }); - }); -} - -export function revokeToken(token) { - return verifyToken(token).then(payload => { - if (payload) { - return new Promise((resolve, reject) => { - data.sadd(revokedTokensSet, payload.jti, error => { - if (error) { - reject(error); - } else { - resolve(); - } - }); - }); - } - }); -} - -export function removeAllRevokedTokens() { - return new Promise((resolve, reject) => { - data.del(revokedTokensSet, error => { - if (error) { - reject(error); - } else { - resolve(); - } - }); - }); -} diff --git a/modules/utils/data.js b/modules/utils/data.js deleted file mode 100644 index 60d966d..0000000 --- a/modules/utils/data.js +++ /dev/null @@ -1,9 +0,0 @@ -import redis from 'redis'; - -redis.debug_mode = process.env.DEBUG_REDIS != null; - -const client = redis.createClient( - process.env.DATA_URL || process.env.OPENREDIS_URL || 'redis://localhost:6379' -); - -export default client; diff --git a/package.json b/package.json index ff3c1d2..93ffd0f 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,6 @@ "gunzip-maybe": "^1.4.1", "invariant": "^2.2.4", "isomorphic-fetch": "^2.2.1", - "jsonwebtoken": "^8.4.0", "lru-cache": "^5.1.1", "mime": "^2.4.0", "morgan": "^1.9.1", diff --git a/yarn.lock b/yarn.lock index e57a884..25be29f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1556,11 +1556,6 @@ buffer-alloc@^1.2.0: buffer-alloc-unsafe "^1.1.0" buffer-fill "^1.0.0" -buffer-equal-constant-time@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" - integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= - buffer-fill@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" @@ -2187,13 +2182,6 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" -ecdsa-sig-formatter@1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" - integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== - dependencies: - safe-buffer "^5.0.1" - ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -3925,22 +3913,6 @@ jsonify@~0.0.0: resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= -jsonwebtoken@^8.4.0: - version "8.5.1" - resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" - integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w== - dependencies: - jws "^3.2.2" - lodash.includes "^4.3.0" - lodash.isboolean "^3.0.3" - lodash.isinteger "^4.0.4" - lodash.isnumber "^3.0.3" - lodash.isplainobject "^4.0.6" - lodash.isstring "^4.0.1" - lodash.once "^4.0.0" - ms "^2.1.1" - semver "^5.6.0" - jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" @@ -3958,23 +3930,6 @@ jsx-ast-utils@^2.1.0: dependencies: array-includes "^3.0.3" -jwa@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" - integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== - dependencies: - buffer-equal-constant-time "1.0.1" - ecdsa-sig-formatter "1.0.11" - safe-buffer "^5.0.1" - -jws@^3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" - integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== - dependencies: - jwa "^1.4.1" - safe-buffer "^5.0.1" - kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -4053,41 +4008,6 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" -lodash.includes@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" - integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8= - -lodash.isboolean@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" - integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY= - -lodash.isinteger@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" - integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M= - -lodash.isnumber@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" - integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w= - -lodash.isplainobject@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" - integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs= - -lodash.isstring@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" - integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= - -lodash.once@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" - integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= - lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"