diff --git a/__test__/auth-router.test.js b/__test__/auth-router.test.js new file mode 100644 index 0000000..75f26a2 --- /dev/null +++ b/__test__/auth-router.test.js @@ -0,0 +1,55 @@ +'use strict'; +// NOTE:fixed apiUrl- still failing elsewhere +require('./lib/setup'); +const superagent = require('superagent'); +const server = require('../lib/server'); +const accountMockFactory = require('./lib/account-mock-factory'); + +const apiUrl =`http://localhost:${process.env.PORT}`; + +describe('auth router', () => { + beforeAll(server.start); + afterAll(server.stop); + afterEach(accountMockFactory.remove); + + describe('POST', () => { + test('post creating account should respond 200 and token if no errors', () => { + return superagent.post(`${apiUrl}/signup`) + .send({ + username : 'nicholas', + email : 'nick.carignan@sbcglobal.net', + password : 'password', + }) + .then(response => { + expect(response.status).toEqual(200); + expect(response.body.token).toBeTruthy(); + }); + }); + test('POST /signup should return a 400 if incomplete request', () => { + return superagent.post(`${apiUrl}/signup`) + .send({ + username : 'nicholas', + email : 'nick.carignan@sbcglobal.net', + }) + .then(Promise.reject) + .catch(response => { + expect(response.status).toEqual(400); + }); + }); + }); + + + describe('GET /login', () => { + test('GET login should get 200 if there are no errors', () =>{ + return accountMockFactory.create() + .then(mock => { + return superagent.get(`${apiUrl}/login`) + .auth(mock.request.username, mock.request.password); + }) + .then(response => { + expect(response.status).toEqual(200); + expect(response.body.token).toBeTruthy(); + }); + }); + }); +}); diff --git a/__test__/block-router.test.js b/__test__/block-routertest.js similarity index 100% rename from __test__/block-router.test.js rename to __test__/block-routertest.js diff --git a/__test__/chain-router.test.js b/__test__/chain-routertest.js similarity index 100% rename from __test__/chain-router.test.js rename to __test__/chain-routertest.js diff --git a/__test__/lib/account-mock-factory.js b/__test__/lib/account-mock-factory.js new file mode 100644 index 0000000..6f5ab9c --- /dev/null +++ b/__test__/lib/account-mock-factory.js @@ -0,0 +1,31 @@ +'use strict'; + +const faker = require('faker'); +const Account = require('../../model/account'); + +const accountMockFactory = module.exports = {}; + +accountMockFactory.create = () => { + let mock = {}; + mock.request = { + username : faker.internet.userName(), + email : faker.internet.email(), + password : faker.lorem.words(), + }; + + return Account.create(mock.request.username, mock.request.email, mock.request.password) + .then(account => { + mock.account = account; + return account.createToken(); + }) + .then(token => { + mock.token = token; + return Account.findById(mock.account._id); + }) + .then(account => { + mock.account = account; + return mock; + }); +}; + +accountMockFactory.remove = () => Account.remove({}); diff --git a/__test__/lib/setup.js b/__test__/lib/setup.js index 001e071..55192d6 100644 --- a/__test__/lib/setup.js +++ b/__test__/lib/setup.js @@ -1,5 +1,6 @@ 'use strict'; process.env.PORT = 7000; -process.env.MONGODB_URI = 'mongodb://heroku_61rbrfdl:auii88ojlv9kju52l3mt6qmuin@ds135777.mlab.com:35777/heroku_61rbrfdl'; -// process.env.MONGODB_URI = 'mongodb://localhost/testing'; +// process.env.MONGODB_URI = 'mongodb://heroku_61rbrfdl:auii88ojlv9kju52l3mt6qmuin@ds135777.mlab.com:35777/heroku_61rbrfdl'; +process.env.CHAIN_CLOUD_SECRET = 'noncents'; +process.env.MONGODB_URI = 'mongodb://localhost/testing'; diff --git a/lib/basic-auth-middleware.js b/lib/basic-auth-middleware.js new file mode 100644 index 0000000..ffdd8b5 --- /dev/null +++ b/lib/basic-auth-middleware.js @@ -0,0 +1,33 @@ +'use strict'; + +const httpErrors = require('http-errors'); +const Account = require('../model/account'); + +module.exports = (request, response, next) => { + if(!request.headers.authorization) + return next(new httpErrors(400, '__ERROR__ authorization header required')); + let base64AuthHeader = request.headers.authorization.split('Basic ')[1]; + + if(!base64AuthHeader) + return next(new httpErrors(400, '__ERROR__ basic authorization required')); + + let stringAuthHeader = new Buffer(base64AuthHeader, 'base64').toString(); + + let [username,password]= stringAuthHeader.split(':'); + + if(!username ||!password) + return next(new httpErrors(400, '__ERROR__ username and password required')); + + Account.findOne({username}) + .then(account => { + if(!account) + throw new httpErrors(404, '__ERROR__ not found'); + return account.verifyPassword(password); + }) + .then(account => { + request.account = account; + return next(); + }) + .catch(next); + +}; diff --git a/lib/server.js b/lib/server.js index afba370..58ae050 100644 --- a/lib/server.js +++ b/lib/server.js @@ -10,7 +10,9 @@ let httpServer = null; //Setting up MongoDB and Mongoose mongoose.Promise = Promise; -// mongoose.connect(process.env.MONGODB_URI, {useMongoClient : true}); +mongoose.connect(process.env.MONGODB_URI, {useMongoClient : true}); + +app.use(require('../route/auth-router')); app.all('*', (request, response) => { diff --git a/log.json b/log.json index d135494..37d0fc4 100644 --- a/log.json +++ b/log.json @@ -503,3 +503,9 @@ {"level":"info","message":"Server is listening on port 7000","timestamp":"2018-01-09T20:07:42.110Z"} {"level":"info","message":"Server is listening on port 7000","timestamp":"2018-01-09T20:08:46.363Z"} {"level":"info","message":"Server is listening on port 7000","timestamp":"2018-01-11T06:53:32.188Z"} +{"level":"info","message":"Server is listening on port 7000","timestamp":"2018-01-23T22:00:02.843Z"} +{"level":"info","message":"Server is listening on port 7000","timestamp":"2018-01-23T22:01:12.866Z"} +{"level":"info","message":"Server is listening on port 7000","timestamp":"2018-01-23T22:02:26.062Z"} +{"level":"info","message":"Server is off","timestamp":"2018-01-23T22:04:26.160Z"} +{"level":"info","message":"Server is listening on port 7000","timestamp":"2018-01-23T22:05:28.179Z"} +{"level":"info","message":"Server is off","timestamp":"2018-01-23T22:05:28.394Z"} diff --git a/model/account.js b/model/account.js new file mode 100644 index 0000000..193af1a --- /dev/null +++ b/model/account.js @@ -0,0 +1,68 @@ +'use strict'; +const mongoose = require('mongoose'); +const crypto = require('crypto'); +const bcrypt = require('bcrypt'); +const httpErrors = require('http-errors'); +const jsonWebToken = require('jsonwebtoken'); + +const accountSchema = mongoose.Schema({ + passwordHash : { + type : String, + required : true, + }, + email : { + type : String, + required : true, + unique : true, + }, + username : { + type : String, + required : true, + unique : true, + }, + tokenSeed : { + type : String, + required : true, + unique : true, + }, + created : { + type : Date, + default : () => new Date(), + }, +}); + +accountSchema.methods.verifyPassword = function(password){ + return bcrypt.compare(password, this.passwordHash) + .then(response => { + if(!response) + throw new httpErrors(401, '__AUTH__ incorrect username or password'); + + return this; + }); +}; + +accountSchema.methods.createToken = function(){ + this.tokenSeed = crypto.randomBytes(64).toString('hex'); + return this.save() + .then(account => { + return jsonWebToken.sign({ + tokenSeed : account.tokenSeed, + }, process.env.CHAIN_CLOUD_SECRET); + }); +}; + +const Account = module.exports = mongoose.model('account', accountSchema); + +Account.create = (username, email, password) => { + const HASH_SALT_ROUNDS = 8; + return bcrypt.hash(password, HASH_SALT_ROUNDS) + .then(passwordHash => { + let tokenSeed = crypto.randomBytes(64).toString('hex'); + return new Account({ + username, + email, + passwordHash, + tokenSeed, + }).save(); + }); +}; diff --git a/package-lock.json b/package-lock.json index 363033e..b89de0e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -109,11 +109,6 @@ "normalize-path": "2.1.1" } }, - "append-field": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/append-field/-/append-field-0.1.0.tgz", - "integrity": "sha1-bdxY+gg8e8VF08WZWygwzCNm1Eo=" - }, "append-transform": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", @@ -218,41 +213,6 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, - "aws-sdk": { - "version": "2.173.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.173.0.tgz", - "integrity": "sha1-KylIbxbh0EFZ0FE6pH9d1wNwEW0=", - "requires": { - "buffer": "4.9.1", - "crypto-browserify": "1.0.9", - "events": "1.1.1", - "jmespath": "0.15.0", - "querystring": "0.2.0", - "sax": "1.2.1", - "url": "0.10.3", - "uuid": "3.1.0", - "xml2js": "0.4.17", - "xmlbuilder": "4.2.1" - }, - "dependencies": { - "sax": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", - "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=" - } - } - }, - "aws-sdk-mock": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/aws-sdk-mock/-/aws-sdk-mock-1.7.0.tgz", - "integrity": "sha1-dpizuoL0k/cf8GCuISPNCAathnY=", - "dev": true, - "requires": { - "aws-sdk": "2.173.0", - "sinon": "1.17.7", - "traverse": "0.6.6" - } - }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", @@ -465,11 +425,6 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, - "base64-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz", - "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==" - }, "base64url": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/base64url/-/base64url-2.0.0.tgz", @@ -571,16 +526,6 @@ "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.4.tgz", "integrity": "sha1-k8ENOeqltYQVy8QFLz5T5WKwtyw=" }, - "buffer": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", - "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", - "requires": { - "base64-js": "1.2.1", - "ieee754": "1.1.8", - "isarray": "1.0.0" - } - }, "buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", @@ -596,38 +541,6 @@ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" }, - "busboy": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", - "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", - "requires": { - "dicer": "0.2.5", - "readable-stream": "1.1.14" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - } - } - }, "bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", @@ -870,16 +783,6 @@ } } }, - "crypto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", - "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==" - }, - "crypto-browserify": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-1.0.9.tgz", - "integrity": "sha1-zFRJaF37hesRyYKKzHy4erW7/MA=" - }, "cssom": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz", @@ -986,38 +889,6 @@ "repeating": "2.0.1" } }, - "dicer": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", - "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", - "requires": { - "readable-stream": "1.1.14", - "streamsearch": "0.1.2" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - } - } - }, "diff": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz", @@ -1249,11 +1120,6 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, - "events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" - }, "exec-sh": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.1.tgz", @@ -1526,15 +1392,6 @@ "mime-types": "2.1.17" } }, - "formatio": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.1.1.tgz", - "integrity": "sha1-XtPM1jZVEJc4NGXZlhmRAOhhYek=", - "dev": true, - "requires": { - "samsam": "1.1.2" - } - }, "formidable": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.1.1.tgz", @@ -1550,16 +1407,6 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, - "fs-extra": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", - "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", - "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "4.0.0", - "universalify": "0.1.1" - } - }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1578,13 +1425,11 @@ "abbrev": { "version": "1.1.0", "bundled": true, - "dev": true, "optional": true }, "ajv": { "version": "4.11.8", "bundled": true, - "dev": true, "optional": true, "requires": { "co": "4.6.0", @@ -1593,19 +1438,16 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true, - "dev": true + "bundled": true }, "aproba": { "version": "1.1.1", "bundled": true, - "dev": true, "optional": true }, "are-we-there-yet": { "version": "1.1.4", "bundled": true, - "dev": true, "optional": true, "requires": { "delegates": "1.0.0", @@ -1615,42 +1457,35 @@ "asn1": { "version": "0.2.3", "bundled": true, - "dev": true, "optional": true }, "assert-plus": { "version": "0.2.0", "bundled": true, - "dev": true, "optional": true }, "asynckit": { "version": "0.4.0", "bundled": true, - "dev": true, "optional": true }, "aws-sign2": { "version": "0.6.0", "bundled": true, - "dev": true, "optional": true }, "aws4": { "version": "1.6.0", "bundled": true, - "dev": true, "optional": true }, "balanced-match": { "version": "0.4.2", - "bundled": true, - "dev": true + "bundled": true }, "bcrypt-pbkdf": { "version": "1.0.1", "bundled": true, - "dev": true, "optional": true, "requires": { "tweetnacl": "0.14.5" @@ -1659,7 +1494,6 @@ "block-stream": { "version": "0.0.9", "bundled": true, - "dev": true, "requires": { "inherits": "2.0.3" } @@ -1667,7 +1501,6 @@ "boom": { "version": "2.10.1", "bundled": true, - "dev": true, "requires": { "hoek": "2.16.3" } @@ -1675,7 +1508,6 @@ "brace-expansion": { "version": "1.1.7", "bundled": true, - "dev": true, "requires": { "balanced-match": "0.4.2", "concat-map": "0.0.1" @@ -1683,53 +1515,44 @@ }, "buffer-shims": { "version": "1.0.0", - "bundled": true, - "dev": true + "bundled": true }, "caseless": { "version": "0.12.0", "bundled": true, - "dev": true, "optional": true }, "co": { "version": "4.6.0", "bundled": true, - "dev": true, "optional": true }, "code-point-at": { "version": "1.1.0", - "bundled": true, - "dev": true + "bundled": true }, "combined-stream": { "version": "1.0.5", "bundled": true, - "dev": true, "requires": { "delayed-stream": "1.0.0" } }, "concat-map": { "version": "0.0.1", - "bundled": true, - "dev": true + "bundled": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true, - "dev": true + "bundled": true }, "core-util-is": { "version": "1.0.2", - "bundled": true, - "dev": true + "bundled": true }, "cryptiles": { "version": "2.0.5", "bundled": true, - "dev": true, "requires": { "boom": "2.10.1" } @@ -1737,7 +1560,6 @@ "dashdash": { "version": "1.14.1", "bundled": true, - "dev": true, "optional": true, "requires": { "assert-plus": "1.0.0" @@ -1746,7 +1568,6 @@ "assert-plus": { "version": "1.0.0", "bundled": true, - "dev": true, "optional": true } } @@ -1763,30 +1584,25 @@ "deep-extend": { "version": "0.4.2", "bundled": true, - "dev": true, "optional": true }, "delayed-stream": { "version": "1.0.0", - "bundled": true, - "dev": true + "bundled": true }, "delegates": { "version": "1.0.0", "bundled": true, - "dev": true, "optional": true }, "detect-libc": { "version": "1.0.2", "bundled": true, - "dev": true, "optional": true }, "ecc-jsbn": { "version": "0.1.1", "bundled": true, - "dev": true, "optional": true, "requires": { "jsbn": "0.1.1" @@ -1795,18 +1611,15 @@ "extend": { "version": "3.0.1", "bundled": true, - "dev": true, "optional": true }, "extsprintf": { "version": "1.0.2", - "bundled": true, - "dev": true + "bundled": true }, "forever-agent": { "version": "0.6.1", "bundled": true, - "dev": true, "optional": true }, "form-data": { @@ -1822,13 +1635,11 @@ }, "fs.realpath": { "version": "1.0.0", - "bundled": true, - "dev": true + "bundled": true }, "fstream": { "version": "1.0.11", "bundled": true, - "dev": true, "requires": { "graceful-fs": "4.1.11", "inherits": "2.0.3", @@ -1839,7 +1650,6 @@ "fstream-ignore": { "version": "1.0.5", "bundled": true, - "dev": true, "optional": true, "requires": { "fstream": "1.0.11", @@ -1850,7 +1660,6 @@ "gauge": { "version": "2.7.4", "bundled": true, - "dev": true, "optional": true, "requires": { "aproba": "1.1.1", @@ -1866,7 +1675,6 @@ "getpass": { "version": "0.1.7", "bundled": true, - "dev": true, "optional": true, "requires": { "assert-plus": "1.0.0" @@ -1875,7 +1683,6 @@ "assert-plus": { "version": "1.0.0", "bundled": true, - "dev": true, "optional": true } } @@ -1883,7 +1690,6 @@ "glob": { "version": "7.1.2", "bundled": true, - "dev": true, "requires": { "fs.realpath": "1.0.0", "inflight": "1.0.6", @@ -1895,13 +1701,11 @@ }, "graceful-fs": { "version": "4.1.11", - "bundled": true, - "dev": true + "bundled": true }, "har-schema": { "version": "1.0.5", "bundled": true, - "dev": true, "optional": true }, "har-validator": { @@ -1917,13 +1721,11 @@ "has-unicode": { "version": "2.0.1", "bundled": true, - "dev": true, "optional": true }, "hawk": { "version": "3.1.3", "bundled": true, - "dev": true, "requires": { "boom": "2.10.1", "cryptiles": "2.0.5", @@ -1933,13 +1735,11 @@ }, "hoek": { "version": "2.16.3", - "bundled": true, - "dev": true + "bundled": true }, "http-signature": { "version": "1.1.1", "bundled": true, - "dev": true, "optional": true, "requires": { "assert-plus": "0.2.0", @@ -1950,7 +1750,6 @@ "inflight": { "version": "1.0.6", "bundled": true, - "dev": true, "requires": { "once": "1.4.0", "wrappy": "1.0.2" @@ -1958,13 +1757,11 @@ }, "inherits": { "version": "2.0.3", - "bundled": true, - "dev": true + "bundled": true }, "ini": { "version": "1.3.4", "bundled": true, - "dev": true, "optional": true }, "is-fullwidth-code-point": { @@ -1978,24 +1775,20 @@ "is-typedarray": { "version": "1.0.0", "bundled": true, - "dev": true, "optional": true }, "isarray": { "version": "1.0.0", - "bundled": true, - "dev": true + "bundled": true }, "isstream": { "version": "0.1.2", "bundled": true, - "dev": true, "optional": true }, "jodid25519": { "version": "1.0.2", "bundled": true, - "dev": true, "optional": true, "requires": { "jsbn": "0.1.1" @@ -2004,19 +1797,16 @@ "jsbn": { "version": "0.1.1", "bundled": true, - "dev": true, "optional": true }, "json-schema": { "version": "0.2.3", "bundled": true, - "dev": true, "optional": true }, "json-stable-stringify": { "version": "1.0.1", "bundled": true, - "dev": true, "optional": true, "requires": { "jsonify": "0.0.0" @@ -2025,19 +1815,16 @@ "json-stringify-safe": { "version": "5.0.1", "bundled": true, - "dev": true, "optional": true }, "jsonify": { "version": "0.0.0", "bundled": true, - "dev": true, "optional": true }, "jsprim": { "version": "1.4.0", "bundled": true, - "dev": true, "optional": true, "requires": { "assert-plus": "1.0.0", @@ -2097,7 +1884,6 @@ "node-pre-gyp": { "version": "0.6.39", "bundled": true, - "dev": true, "optional": true, "requires": { "detect-libc": "1.0.2", @@ -2116,7 +1902,6 @@ "nopt": { "version": "4.0.1", "bundled": true, - "dev": true, "optional": true, "requires": { "abbrev": "1.1.0", @@ -2126,7 +1911,6 @@ "npmlog": { "version": "4.1.0", "bundled": true, - "dev": true, "optional": true, "requires": { "are-we-there-yet": "1.1.4", @@ -2155,7 +1939,6 @@ "once": { "version": "1.4.0", "bundled": true, - "dev": true, "requires": { "wrappy": "1.0.2" } @@ -2169,13 +1952,11 @@ "os-tmpdir": { "version": "1.0.2", "bundled": true, - "dev": true, "optional": true }, "osenv": { "version": "0.1.4", "bundled": true, - "dev": true, "optional": true, "requires": { "os-homedir": "1.0.2", @@ -2184,36 +1965,30 @@ }, "path-is-absolute": { "version": "1.0.1", - "bundled": true, - "dev": true + "bundled": true }, "performance-now": { "version": "0.2.0", "bundled": true, - "dev": true, "optional": true }, "process-nextick-args": { "version": "1.0.7", - "bundled": true, - "dev": true + "bundled": true }, "punycode": { "version": "1.4.1", "bundled": true, - "dev": true, "optional": true }, "qs": { "version": "6.4.0", "bundled": true, - "dev": true, "optional": true }, "rc": { "version": "1.2.1", "bundled": true, - "dev": true, "optional": true, "requires": { "deep-extend": "0.4.2", @@ -2225,7 +2000,6 @@ "minimist": { "version": "1.2.0", "bundled": true, - "dev": true, "optional": true } } @@ -2233,7 +2007,6 @@ "readable-stream": { "version": "2.2.9", "bundled": true, - "dev": true, "requires": { "buffer-shims": "1.0.0", "core-util-is": "1.0.2", @@ -2247,7 +2020,6 @@ "request": { "version": "2.81.0", "bundled": true, - "dev": true, "optional": true, "requires": { "aws-sign2": "0.6.0", @@ -2277,38 +2049,32 @@ "rimraf": { "version": "2.6.1", "bundled": true, - "dev": true, "requires": { "glob": "7.1.2" } }, "safe-buffer": { "version": "5.0.1", - "bundled": true, - "dev": true + "bundled": true }, "semver": { "version": "5.3.0", "bundled": true, - "dev": true, "optional": true }, "set-blocking": { "version": "2.0.0", "bundled": true, - "dev": true, "optional": true }, "signal-exit": { "version": "3.0.2", "bundled": true, - "dev": true, "optional": true }, "sntp": { "version": "1.0.9", "bundled": true, - "dev": true, "requires": { "hoek": "2.16.3" } @@ -2316,7 +2082,6 @@ "sshpk": { "version": "1.13.0", "bundled": true, - "dev": true, "optional": true, "requires": { "asn1": "0.2.3", @@ -2333,7 +2098,6 @@ "assert-plus": { "version": "1.0.0", "bundled": true, - "dev": true, "optional": true } } @@ -2341,7 +2105,6 @@ "string-width": { "version": "1.0.2", "bundled": true, - "dev": true, "requires": { "code-point-at": "1.1.0", "is-fullwidth-code-point": "1.0.0", @@ -2351,7 +2114,6 @@ "string_decoder": { "version": "1.0.1", "bundled": true, - "dev": true, "requires": { "safe-buffer": "5.0.1" } @@ -2359,13 +2121,11 @@ "stringstream": { "version": "0.0.5", "bundled": true, - "dev": true, "optional": true }, "strip-ansi": { "version": "3.0.1", "bundled": true, - "dev": true, "requires": { "ansi-regex": "2.1.1" } @@ -2373,13 +2133,11 @@ "strip-json-comments": { "version": "2.0.1", "bundled": true, - "dev": true, "optional": true }, "tar": { "version": "2.2.1", "bundled": true, - "dev": true, "requires": { "block-stream": "0.0.9", "fstream": "1.0.11", @@ -2389,7 +2147,6 @@ "tar-pack": { "version": "3.4.0", "bundled": true, - "dev": true, "optional": true, "requires": { "debug": "2.6.8", @@ -2405,7 +2162,6 @@ "tough-cookie": { "version": "2.3.2", "bundled": true, - "dev": true, "optional": true, "requires": { "punycode": "1.4.1" @@ -2414,7 +2170,6 @@ "tunnel-agent": { "version": "0.6.0", "bundled": true, - "dev": true, "optional": true, "requires": { "safe-buffer": "5.0.1" @@ -2423,30 +2178,25 @@ "tweetnacl": { "version": "0.14.5", "bundled": true, - "dev": true, "optional": true }, "uid-number": { "version": "0.0.6", "bundled": true, - "dev": true, "optional": true }, "util-deprecate": { "version": "1.0.2", - "bundled": true, - "dev": true + "bundled": true }, "uuid": { "version": "3.0.1", "bundled": true, - "dev": true, "optional": true }, "verror": { "version": "1.3.6", "bundled": true, - "dev": true, "optional": true, "requires": { "extsprintf": "1.0.2" @@ -2455,7 +2205,6 @@ "wide-align": { "version": "1.1.2", "bundled": true, - "dev": true, "optional": true, "requires": { "string-width": "1.0.2" @@ -2463,8 +2212,7 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true, - "dev": true + "bundled": true } } }, @@ -2727,11 +2475,6 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" }, - "ieee754": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", - "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=" - }, "ignore": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", @@ -3377,11 +3120,6 @@ "pretty-format": "21.2.1" } }, - "jmespath": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", - "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=" - }, "js-tokens": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", @@ -3471,23 +3209,15 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=" }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "4.1.11" - } - }, "jsonify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" }, "jsonwebtoken": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.1.0.tgz", - "integrity": "sha1-xjl80uX9WD1lwAeoPce7eOaYK4M=", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.1.1.tgz", + "integrity": "sha512-+ijVOtfLMlCII8LJkvabaKX3+8tGrGjiCTfzoed2D1b/ebKTO1hIYBQUJHbd9dJ9Fa4kH+dhYEd1qDwyzDLUUw==", "requires": { "jws": "3.1.4", "lodash.includes": "4.3.0", @@ -3497,8 +3227,15 @@ "lodash.isplainobject": "4.0.6", "lodash.isstring": "4.0.1", "lodash.once": "4.1.1", - "ms": "2.0.0", + "ms": "2.1.1", "xtend": "4.0.1" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } } }, "jsprim": { @@ -3647,12 +3384,6 @@ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" }, - "lolex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.3.2.tgz", - "integrity": "sha1-fD2mL/yzDw9agKJWbKJORdigHzE=", - "dev": true - }, "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", @@ -3873,28 +3604,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "multer": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/multer/-/multer-1.3.0.tgz", - "integrity": "sha1-CSsmcPaEb6SRSWXvyM+Uwg/sbNI=", - "requires": { - "append-field": "0.1.0", - "busboy": "0.2.14", - "concat-stream": "1.6.0", - "mkdirp": "0.5.1", - "object-assign": "3.0.0", - "on-finished": "2.3.0", - "type-is": "1.6.15", - "xtend": "4.0.1" - }, - "dependencies": { - "object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=" - } - } - }, "muri": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/muri/-/muri-1.3.0.tgz", @@ -3944,7 +3653,7 @@ "mkdirp": "0.5.1", "nopt": "4.0.1", "npmlog": "4.1.2", - "rc": "1.2.2", + "rc": "1.2.4", "request": "2.83.0", "rimraf": "2.6.2", "semver": "5.4.1", @@ -4307,11 +4016,6 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" - }, "randomatic": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", @@ -4366,9 +4070,9 @@ } }, "rc": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.2.tgz", - "integrity": "sha1-2M6ctX6NZNnHut2YdsfDTL48cHc=", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.4.tgz", + "integrity": "sha1-oPYGyq4qO4YrvQ74VILAElsxX6M=", "requires": { "deep-extend": "0.4.2", "ini": "1.3.5", @@ -4602,12 +4306,6 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" }, - "samsam": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.1.2.tgz", - "integrity": "sha1-vsEf3IOp/aBjQBIQ5AF2wwJNFWc=", - "dev": true - }, "sane": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/sane/-/sane-2.2.0.tgz", @@ -4711,18 +4409,6 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, - "sinon": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-1.17.7.tgz", - "integrity": "sha1-RUKk9JugxFwF6y6d2dID4rjv4L8=", - "dev": true, - "requires": { - "formatio": "1.1.1", - "lolex": "1.3.2", - "samsam": "1.1.2", - "util": "0.10.3" - } - }, "slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", @@ -4817,11 +4503,6 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" }, - "streamsearch": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", - "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" - }, "string-length": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz", @@ -5060,12 +4741,6 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" }, - "traverse": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", - "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=", - "dev": true - }, "trim-right": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", @@ -5143,47 +4818,11 @@ "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz", "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=" }, - "universalify": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz", - "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=" - }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" }, - "url": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", - "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" - } - } - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" - } - } - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -5374,23 +5013,6 @@ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz", "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=" }, - "xml2js": { - "version": "0.4.17", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.17.tgz", - "integrity": "sha1-F76T6q4/O3eTWceVtBlwWogX6Gg=", - "requires": { - "sax": "1.2.4", - "xmlbuilder": "4.2.1" - } - }, - "xmlbuilder": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.2.1.tgz", - "integrity": "sha1-qlijBBoGb5DqoWwvU4n/GfP0YaU=", - "requires": { - "lodash": "4.17.4" - } - }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", diff --git a/package.json b/package.json index f20c453..a9e156e 100644 --- a/package.json +++ b/package.json @@ -19,16 +19,18 @@ "superagent": "^3.8.1" }, "dependencies": { + "bcrypt": "^1.0.3", "body-parser": "^1.18.2", + "eslint": "^4.12.1", "express": "^4.16.2", "faker": "^4.1.0", "httperrors": "^2.3.0", + "jest": "^21.2.1", "jshashes": "^1.0.7", + "jsonwebtoken": "^8.1.1", "mongoose": "^4.13.7", - "winston": "^2.4.0", - "eslint": "^4.12.1", - "jest": "^21.2.1", - "superagent": "^3.8.1" + "superagent": "^3.8.1", + "winston": "^2.4.0" }, "engines": { "node": "8.9.3" diff --git a/route/auth-router.js b/route/auth-router.js new file mode 100644 index 0000000..2095c20 --- /dev/null +++ b/route/auth-router.js @@ -0,0 +1,30 @@ +'use strict'; +const {Router} = require('express'); +const jsonParser = require('body-parser').json(); +const Account = require('../model/account'); +const httpErrors = require('http-errors'); +const basicAuthMiddleware = require('../lib/basic-auth-middleware'); + +const authRouter = module.exports = new Router(); + +authRouter.post('/signup', jsonParser, (request, response, next) => { + if(!request.body.username || !request.body.email || !request.body.password){ + return next(new httpErrors(400, '__ERROR__ username, email, and password are required to create an account')); + } + Account.create(request.body.username, request.body.email, request.body.password) + .then(user => user.createToken()) + .then(token => { + response.json({token}); + + }) + .catch(next); +}); + +authRouter.get('/login', basicAuthMiddleware, (request, response, next) => { + if(!request.account) + return next(new httpErrors(404, '__ERROR__ not found')); + + return request.account.createToken() + .then(token => response.json({token})) + .catch(next); +});