Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions __test__/auth-router.test.js
Original file line number Diff line number Diff line change
@@ -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();
});
});
});
});
File renamed without changes.
File renamed without changes.
31 changes: 31 additions & 0 deletions __test__/lib/account-mock-factory.js
Original file line number Diff line number Diff line change
@@ -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({});
5 changes: 3 additions & 2 deletions __test__/lib/setup.js
Original file line number Diff line number Diff line change
@@ -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';
33 changes: 33 additions & 0 deletions lib/basic-auth-middleware.js
Original file line number Diff line number Diff line change
@@ -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);

};
4 changes: 3 additions & 1 deletion lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down
6 changes: 6 additions & 0 deletions log.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"}
68 changes: 68 additions & 0 deletions model/account.js
Original file line number Diff line number Diff line change
@@ -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();
});
};
Loading