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
2 changes: 1 addition & 1 deletion .babelrc.karma
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"presets": [ "es2015" ],
"presets": ["es2015"],
"plugins": [
["istanbul", {
"exclude": [
Expand Down
15 changes: 15 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,21 @@
"sourceType": "commonjs"
},
"rules": {
"arrow-spacing": "error",
"comma-dangle": "error",
"comma-style": ["error", "last"],
"comma-spacing": ["error", {
"before": false,
"after": true
}],
"complexity": "warn",
"curly": "error",
"eol-last": "error",
"indent": ["error", 2],
"key-spacing": ["error", {
"beforeColon": false,
"afterColon": true
}],
"keyword-spacing": "error",
"max-len": ["error", 120],
"no-console": "off",
Expand All @@ -28,11 +37,17 @@
"no-trailing-spaces": "error",
"no-var": "error",
"no-warning-comments": "warn",
"object-curly-spacing": ["error", "always"],
"object-shorthand": "error",
"prefer-arrow-callback": "error",
"prefer-const": "warn",
"semi": "error",
"semi-spacing": ["error", {
"before": false,
"after": true
}],
"space-before-blocks": "error",
"template-curly-spacing": ["error", "never"],
"quotes": ["error", "single"]
}
}
10 changes: 5 additions & 5 deletions build_signature_loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ const path = require('path');
const cwd = path.join(__dirname, '.');
const exec = Promise.promisify(require('child_process').exec);

function inspectRepository() {
function revParse(args) {
return exec(`git rev-parse ${args}`, { cwd })
.then((result) => result.trim());
}
function revParse(args) {
return exec(`git rev-parse ${args}`, { cwd })
.then((result) => result.trim());
}

function inspectRepository() {
return Promise.all([
revParse('--abbrev-ref HEAD'),
revParse('HEAD')
Expand Down
5 changes: 4 additions & 1 deletion gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ gulp.task('tdd', () => {
});

gulp.task('server:test', (done) => {
process.env.NODE_ENV = 'test';

const istanbul = require('gulp-istanbul');
const mocha = require('gulp-mocha');

Expand All @@ -84,7 +86,8 @@ gulp.task('server:test', (done) => {
gulp.src(['server/**/*.spec.js'], { read: false })
.pipe(mocha({
ui: 'bdd',
reporter: 'dot'
reporter: 'dot',
timeout: 250
}))
.pipe(istanbul.writeReports({
dir: 'artifacts/server/coverage',
Expand Down
2 changes: 1 addition & 1 deletion karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ module.exports = function(config) {


coverageReporter: {
dir : 'artifacts/client/coverage',
dir: 'artifacts/client/coverage',
subdir: (browser) => {
return browser.toLowerCase().split(/[ /-]/)[0];
},
Expand Down
17 changes: 10 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"devDependencies": {
"angular-mocks": "^1.5.8",
"babel-core": "^6.18.0",
"babel-loader": "^6.2.5",
"babel-loader": "^6.2.7",
"babel-plugin-istanbul": "^2.0.3",
"babel-preset-es2015": "^6.18.0",
"chai": "^3.5.0",
Expand All @@ -32,7 +32,7 @@
"eslint-plugin-angular": "^1.4.1",
"eslint-plugin-jasmine": "^1.8.1",
"eslint-plugin-mocha": "^4.7.0",
"eslint-plugin-promise": "^3.1.0",
"eslint-plugin-promise": "^3.3.0",
"eslint-plugin-protractor": "^1.28.0",
"extract-text-webpack-plugin": "^1.0.1",
"favicons-webpack-plugin": "0.0.7",
Expand Down Expand Up @@ -63,16 +63,16 @@
"nodemon": "^1.11.0",
"null-loader": "^0.1.1",
"progress-bar-webpack-plugin": "^1.9.0",
"protractor": "^4.0.9",
"protractor": "^4.0.10",
"request": "^2.76.0",
"run-sequence": "^1.2.2",
"sass-loader": "^4.0.2",
"sinon": "^1.17.6",
"style-loader": "^0.13.1",
"supertest": "^2.0.0",
"supertest": "^2.0.1",
"url-loader": "^0.5.7",
"webdriver-manager": "^10.2.5",
"webpack": "^1.13.2",
"webdriver-manager": "^10.2.6",
"webpack": "^1.13.3",
"webpack-combine-loaders": "^2.0.0",
"webpack-dev-server": "^1.16.2"
},
Expand All @@ -85,12 +85,15 @@
"angular-resource": "^1.5.8",
"angular-toastr": "^2.1.1",
"angular-ui-router": "^1.0.0-beta.3",
"bcrypt": "^0.8.7",
"bluebird": "^3.4.6",
"body-parser": "^1.15.2",
"bootstrap-sass": "^3.3.7",
"express": "^4.14.0",
"faker": "^3.1.0",
"jquery": "^3.1.1",
"lodash": "^4.16.4"
"jsonwebtoken": "^7.1.9",
"lodash": "^4.16.4",
"morgan": "^1.7.0"
}
}
4 changes: 1 addition & 3 deletions server.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
const app = require('./server/app');
const db = require('./server/db');

db.seed().then((contacts) => {
console.log(`Database populated with ${contacts.length} contacts`);

db.seed().then(() => {
const port = process.env.PORT || 9090;
app.listen(port, () => {
console.log('Server is running on port', port);
Expand Down
41 changes: 41 additions & 0 deletions server/api/authentication.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const Promise = require('bluebird');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const router = require('express').Router();
const _ = require('lodash');

const config = require('../config');
const db = require('../db');

function checkPassword(password, passwordHash) {
const compare = Promise.promisify(bcrypt.compare);
return compare(password, passwordHash).then((success) => {
if (success) {
return Promise.resolve(true);
} else {
return Promise.reject(true);
}
});
}

router.post('/', (req, res) => {
const { email, password } = req.body;

db.users.findOne({ email }).then((user) => {
const { passwordHash } = user;

return checkPassword(password, passwordHash).then(() => {
const data = _.pick(user, ['id', 'email']);

const token = jwt.sign(data, config.secret, {
expiresIn: '7 days'
});

res.json({ token });
});
}).catch(() => {
res.sendStatus(422);
});
});

module.exports = router;
59 changes: 59 additions & 0 deletions server/api/authentication.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
const expect = require('chai').expect;
const jwt = require('jsonwebtoken');
const request = require('supertest');

const app = require('../app');
const config = require('../config');
const db = require('../db');

describe('authentication API', () => {

beforeEach(() => {
return db.seed();
});

describe('POST /api/authentication', () => {

describe('with valid credentials', () => {

const email = 'demo@email.com';
const password = 'password';

it('creates a contact', (done) => {
request(app)
.post('/api/authentication')
.send({ email, password })
.expect(200)
.expect((res) => {
const { token } = res.body;
const payload = jwt.verify(token, config.secret);

expect(payload).to.have.property('id');
expect(payload).to.have.property('email', email);
expect(payload).to.not.have.property('passwordHash');
expect(payload).to.have.property('iat');
expect(payload).to.have.property('exp');
})
.end(done);
});

});

describe('with invalid credentials', () => {

const email = 'demo@email.com';
const password = 'wrong';

it('creates a contact', (done) => {
request(app)
.post('/api/authentication')
.send({ email, password })
.expect(422)
.end(done);
});

});

});

});
4 changes: 4 additions & 0 deletions server/api/contacts.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
const router = require('express').Router();

const db = require('../db');
const { requireAuthorization } = require('../middlewares');

router.use(requireAuthorization);

router.param('id', (req, res, next, id) => {
id = parseInt(id);
Expand Down
Loading