Merge branch 'feature/notes' into develop

pull/1/head
sundowndev 2018-11-14 18:16:56 +01:00
commit 6e134f6187
33 changed files with 2359 additions and 141 deletions

2
.eslintignore Normal file
View File

@ -0,0 +1,2 @@
docs
ode_modules

3
.eslintrc.json Normal file
View File

@ -0,0 +1,3 @@
{
"extends": "airbnb-base"
}

9
.travis.yml Normal file
View File

@ -0,0 +1,9 @@
language: node_js
node_js:
- "7"
- "8"
before_script:
- npm install
script: npm run test

9
app/db/db.config.js Normal file
View File

@ -0,0 +1,9 @@
module.exports = {
name: 'api-mooc',
host: process.env.HOST_MONGODB || '127.0.0.1:27017',
opts: {
promiseLibrary: global.Promise,
useNewUrlParser: true,
useCreateIndex: true,
},
};

13
app/db/db.connect.js Normal file
View File

@ -0,0 +1,13 @@
const mongoose = require('mongoose');
const UserSchema = require('../models/user');
const NoteSchema = require('../models/note');
const db = require('./db.config');
mongoose.connect(`mongodb://${db.host}/${db.name}`, db.opts);
mongoose.connection.on('connected', () => {
mongoose.model('User', UserSchema);
mongoose.model('Note', NoteSchema);
});

View File

@ -1,9 +1,14 @@
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
const mongoose = require('mongoose');
var NoteSchema = new Schema({
title: String,
text: String
});
const { Schema } = mongoose;
module.exports = mongoose.model('Note', NoteSchema);
const NoteSchema = new Schema({
title: {
type: String, required: [true, "can't be blank"],
},
text: {
type: String, required: [true, "can't be blank"],
},
}, { timestamps: true });
module.exports = NoteSchema;

View File

@ -1,11 +1,20 @@
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
const mongoose = require('mongoose');
var UserSchema = new Schema({
firstname: String,
lastname: String,
username: String,
password: String
});
const { Schema } = mongoose;
module.exports = mongoose.model('User', UserSchema);
const UserSchema = new Schema({
firstname: {
type: String, required: [true, "can't be blank"],
},
lastname: {
type: String, required: [true, "can't be blank"],
},
username: {
type: String, lowercase: true, unique: true, required: [true, "can't be blank"], match: [/^[a-zA-Z0-9]+$/, 'is invalid'], index: true,
},
password: {
type: String, required: [true, "can't be blank"],
},
}, { timestamps: true });
module.exports = UserSchema;

36
app/routes/auth/index.js Normal file
View File

@ -0,0 +1,36 @@
const auth = require('express').Router();
const register = require('./register');
const login = require('./login');
const UserSchema = require('../../schemas/user');
/**
* @api {post} /auth/register Register
* @apiName Register
* @apiGroup Auth
*
* @apiParam {String} firstname Firstname of the user.
* @apiParam {String} lastname Lastname of the user.
* @apiParam {String} username username of the user.
* @apiParam {String} password password of the user.
*
* @apiSuccess {Array} Array Array of Note objects.
*/
auth.post('/register', UserSchema, register);
/**
* @api {post} /auth/login Get access token
* @apiName Login
* @apiGroup Auth
*
* @apiParam {String} username username of the user.
* @apiParam {String} password password of the user.
*
* @apiSuccess {string} access_token Access token.
*/
auth.post('/login', login);
// note.post('/rester-password', reset)
module.exports = auth;

29
app/routes/auth/login.js Normal file
View File

@ -0,0 +1,29 @@
const mongoose = require('mongoose');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt-nodejs');
module.exports = (req, res, next) => {
const User = mongoose.model('User');
User.findOne({
username: req.body.username,
}, (err, user) => {
if (err) throw err;
if (!user) {
next({ status: 400, message: 'Authentication failed. User not found.' });
} else {
// check if password matches
const isMatch = bcrypt.compare(req.body.password, User.password);
if (isMatch && !err) {
// if user is found and password is right create a token
const token = 'test';
// return the information including token as JSON
res.json({ success: true, access_token: `JWT ${token}` });
} else {
next({ status: 401, message: 'Authentication failed. User not found.' });
res.status(401).send({ success: false, msg: 'Authentication failed. Wrong password.' });
}
}
});
};

View File

@ -0,0 +1,29 @@
const mongoose = require('mongoose');
const bcrypt = require('bcrypt-nodejs');
module.exports = (req, res, next) => {
const UserModel = mongoose.model('User');
const passwordHash = bcrypt.hashSync(req.body.password);
const User = new UserModel({
firstname: req.body.firstname,
lastname: req.body.lastname,
username: req.body.username,
password: passwordHash,
});
UserModel.findOne({
username: req.body.username,
}, (err, user) => {
next({ status: 401, message: 'Username is already taken.' });
});
return User.save((saveErr) => {
if (saveErr) {
return next({ status: 500, message: 'Database error', error: [] });
}
return res.status(200).json(User);
});
};

View File

@ -2,6 +2,7 @@ const routes = require('express').Router();
const bodyParser = require('body-parser');
// Require routes
const auth = require('./auth');
const user = require('./user');
const note = require('./note');
@ -11,15 +12,16 @@ routes.use(bodyParser.urlencoded({ extended: true }));
routes.use(bodyParser.json());
routes.use((req, res, next) => {
// do logging
console.log('Something is happening.');
next(); // make sure we go to the next routes and don't stop here
// do logging
console.log(`Resource requested: ${req.method} ${req.originalUrl}`);
next(); // make sure we go to the next routes and don't stop here
});
routes.get('/', (req, res) => {
res.status(200).json({ message: 'Hello world!' });
});
routes.use('/auth', auth);
routes.use('/user', user);
routes.use('/note', note);

View File

@ -1,5 +0,0 @@
module.exports = (req, res) => {
const users = [];
res.status(200).json({ users });
};

17
app/routes/note/create.js Normal file
View File

@ -0,0 +1,17 @@
const mongoose = require('mongoose');
// TODO: verify auth
module.exports = (req, res) => {
const NoteModel = mongoose.model('Note');
const Note = new NoteModel({ title: req.body.title, text: req.body.text });
Note.save((err) => {
if (err) {
return res.status(400).json({ success: false, msg: 'Title and text must not be blank.' });
}
return res.status(200).json(Note);
});
};

19
app/routes/note/delete.js Normal file
View File

@ -0,0 +1,19 @@
const mongoose = require('mongoose');
// TODO: verify auth
// TODO: verify owner
module.exports = (req, res) => {
const NoteModel = mongoose.model('Note');
NoteModel.findOneAndDelete({ _id: req.params.id }, (err, note) => {
if (err) return res.status(500).send(err);
if (!note) return res.status(404).json({ message: 'Note does not exists.' });
const response = {
message: 'Note successfully deleted',
};
return res.status(200).send(response);
});
};

View File

@ -1,33 +1,49 @@
const note = require('express').Router();
const all = require('./all');
const single = require('./single');
//const create = require('./create');
//const update = require('./update');
//const delete = require('./delete');
const create = require('./create');
const update = require('./update');
const remove = require('./delete');
/**
* @api {get} /note Request all notes
* @api {get} /note/:id Get note
* @apiName GetNotes
* @apiGroup Note
*
* @apiSuccess {Array} Array Array of Note objects.
*/
note.get('/', all);
/**
* @api {get} /note/:id Request Note information
* @apiName GetNotes
* @apiGroup Note
*
* @apiParam {Number} id Notes unique ID.
* @apiParam {String} id Note unique ID.
*
* @apiSuccess {string} title Title of the note.
* @apiSuccess {string} text Text of the note.
*/
note.get('/:noteId', single);
note.get('/:id', single);
//note.post('/', create)
//note.post('/:noteId', update)
//note.post('/:noteId', delete)
/**
* @api {post} /note Create note
* @apiName CreateNote
* @apiGroup Note
*
* @apiSuccess {Object} Object Created note.
*/
note.post('/', create);
/**
* @api {delete} /note/:id Delete note
* @apiName DeleteNote
* @apiGroup Note
*
* @apiParam {String} id Note unique ID.
*/
note.delete('/:id', remove);
/**
* @api {put} /note/:id Update note
* @apiName UpdateNote
* @apiGroup Note
*
* @apiParam {String} id Note unique ID.
*
* @apiSuccess {Object} Object Updated note.
*/
note.put('/:id', update);
module.exports = note;

View File

@ -1,5 +1,21 @@
module.exports = (req, res) => {
const user = req.model;
const mongoose = require('mongoose');
res.status(200).json({ user });
// TODO: verify owner
module.exports = (req, res) => {
const NoteModel = mongoose.model('Note');
NoteModel.findOne({ _id: req.params.id })
.lean()
.exec()
.then((result) => {
if (result === null) {
res.status(404).json({ success: false, msg: 'Note does not exists.' });
}
res.status(200).json(result);
})
.catch(() => {
res.status(404).json({ success: false, msg: 'Note does not exists.' });
});
};

28
app/routes/note/update.js Normal file
View File

@ -0,0 +1,28 @@
const mongoose = require('mongoose');
// TODO: verify auth
// TODO: verify owner
module.exports = (req, res) => {
const NoteModel = mongoose.model('Note');
NoteModel.findOneAndUpdate(
// the id of the item to find
{ _id: req.params.id },
// the change to be made. Mongoose will smartly combine your existing
// document with this change, which allows for partial updates too
req.body,
// an option that asks mongoose to return the updated version
// of the document instead of the pre-updated one.
{ new: true },
// the callback function
(err, note) => {
// Handle any possible database errors
if (err) return res.status(500).send(err);
return res.json(note);
},
);
};

View File

@ -1,5 +0,0 @@
module.exports = (req, res) => {
const users = [];
res.status(200).json({ users });
};

View File

@ -1,5 +1,5 @@
module.exports = (req, res) => {
const user = req.model;
const user = {};
res.status(200).json({ user });
};

View File

@ -1,36 +1,44 @@
const user = require('express').Router();
const all = require('./all');
const single = require('./single');
//const create = require('./create');
//const update = require('./update');
//const delete = require('./delete');
const profile = require('./profile');
const update = require('./update');
const remove = require('./delete');
// const notes = require('./notes');
/**
* @api {get} /user Request all Users information
* @apiName GetUsers
* @apiGroup User
*
* @apiParam {Number} id Users unique ID.
*
* @apiSuccess {Array} Array Array of User objects.
*/
user.get('/', all);
/**
* @api {get} /user/:id Request User information
* @api {get} /user/me Get user information
* @apiName GetUser
* @apiGroup User
*
* @apiParam {Number} id Users unique ID.
*
* @apiSuccess {String} firstname Firstname of the User.
* @apiSuccess {String} lastname Lastname of the User.
* @apiSuccess {String} username Username of the User.
*/
user.get('/:userId', single);
user.get('/me', profile);
//user.post('/', create)
//user.post('/:userId', update)
//user.post('/:userId', delete)
/**
* @api {put} /user/me Update account information
* @apiName UpdateUser
* @apiGroup User
*
* @apiSuccess {Object} user User object.
*/
user.put('/me', update);
/**
* @api {delete} /user/me Delete account
* @apiName DeleteUser
* @apiGroup User
*/
user.delete('/me', remove);
/**
* @api {get} /user/me/notes Get all notes
* @apiName GetNotesByUserId
* @apiGroup User notes
*
* @apiSuccess {Array} Array Notes of the user.
*/
user.get('/me/notes', profile);
module.exports = user;

0
app/routes/user/notes.js Normal file
View File

View File

@ -0,0 +1,5 @@
module.exports = (req, res) => {
const user = {};
res.status(200).json({ user });
};

View File

@ -0,0 +1,5 @@
module.exports = (req, res) => {
const user = {};
res.status(200).json({ user });
};

25
app/schemas/user.js Normal file
View File

@ -0,0 +1,25 @@
const Joi = require('joi');
module.exports = (req, res, next) => {
const schema = Joi.object().keys({
firstname: Joi.string().min(2).required(),
lastname: Joi.string().min(2).required(),
username: Joi.string().alphanum().min(3).max(30)
.required(),
password: Joi.string().required(),
});
Joi.validate({
firstname: req.body.firstname,
lastname: req.body.lastname,
username: req.body.username,
password: req.body.password,
},
schema, (validateErr) => {
if (validateErr) {
return next({ status: 400, message: 'Form is invalid.', error: validateErr });
}
return next();
});
};

View File

@ -1,5 +0,0 @@
var mongoose = require('mongoose');
mongoose.connect('mongodb://node:node@novus.modulusmongo.net:27017/Iganiq8o');
var User = require('./app/models/user');

4
config/database.js Normal file
View File

@ -0,0 +1,4 @@
module.exports = {
secret: 'admin',
database: 'mongodb://localhost/mooc-api',
};

View File

@ -1,10 +1,87 @@
define({ "api": [
{
"type": "get",
"url": "/note",
"title": "Request all notes",
"name": "GetNotes",
"group": "Note",
"type": "post",
"url": "/auth/login",
"title": "Get access token",
"name": "Login",
"group": "Auth",
"parameter": {
"fields": {
"Parameter": [
{
"group": "Parameter",
"type": "String",
"optional": false,
"field": "username",
"description": "<p>username of the user.</p>"
},
{
"group": "Parameter",
"type": "String",
"optional": false,
"field": "password",
"description": "<p>password of the user.</p>"
}
]
}
},
"success": {
"fields": {
"Success 200": [
{
"group": "Success 200",
"type": "string",
"optional": false,
"field": "jwt_token",
"description": "<p>JWT token.</p>"
}
]
}
},
"version": "0.0.0",
"filename": "app/routes/auth/index.js",
"groupTitle": "Auth"
},
{
"type": "post",
"url": "/auth/register",
"title": "Register",
"name": "Register",
"group": "Auth",
"parameter": {
"fields": {
"Parameter": [
{
"group": "Parameter",
"type": "String",
"optional": false,
"field": "firstname",
"description": "<p>Firstname of the user.</p>"
},
{
"group": "Parameter",
"type": "String",
"optional": false,
"field": "lastname",
"description": "<p>Lastname of the user.</p>"
},
{
"group": "Parameter",
"type": "String",
"optional": false,
"field": "username",
"description": "<p>username of the user.</p>"
},
{
"group": "Parameter",
"type": "String",
"optional": false,
"field": "password",
"description": "<p>password of the user.</p>"
}
]
}
},
"success": {
"fields": {
"Success 200": [
@ -19,13 +96,59 @@ define({ "api": [
}
},
"version": "0.0.0",
"filename": "app/routes/auth/index.js",
"groupTitle": "Auth"
},
{
"type": "post",
"url": "/note",
"title": "Create note",
"name": "CreateNote",
"group": "Note",
"success": {
"fields": {
"Success 200": [
{
"group": "Success 200",
"type": "Object",
"optional": false,
"field": "Object",
"description": "<p>Created note.</p>"
}
]
}
},
"version": "0.0.0",
"filename": "app/routes/note/index.js",
"groupTitle": "Note"
},
{
"type": "delete",
"url": "/note/:id",
"title": "Delete note",
"name": "DeleteNote",
"group": "Note",
"parameter": {
"fields": {
"Parameter": [
{
"group": "Parameter",
"type": "String",
"optional": false,
"field": "id",
"description": "<p>Note unique ID.</p>"
}
]
}
},
"version": "0.0.0",
"filename": "app/routes/note/index.js",
"groupTitle": "Note"
},
{
"type": "get",
"url": "/note/:id",
"title": "Request Note information",
"title": "Get note",
"name": "GetNotes",
"group": "Note",
"parameter": {
@ -33,10 +156,10 @@ define({ "api": [
"Parameter": [
{
"group": "Parameter",
"type": "Number",
"type": "String",
"optional": false,
"field": "id",
"description": "<p>Notes unique ID.</p>"
"description": "<p>Note unique ID.</p>"
}
]
}
@ -66,24 +189,57 @@ define({ "api": [
"groupTitle": "Note"
},
{
"type": "get",
"url": "/user/:id",
"title": "Request User information",
"name": "GetUser",
"group": "User",
"type": "put",
"url": "/note/:id",
"title": "Update note",
"name": "UpdateNote",
"group": "Note",
"parameter": {
"fields": {
"Parameter": [
{
"group": "Parameter",
"type": "Number",
"type": "String",
"optional": false,
"field": "id",
"description": "<p>Users unique ID.</p>"
"description": "<p>Note unique ID.</p>"
}
]
}
},
"success": {
"fields": {
"Success 200": [
{
"group": "Success 200",
"type": "Object",
"optional": false,
"field": "Object",
"description": "<p>Updated note.</p>"
}
]
}
},
"version": "0.0.0",
"filename": "app/routes/note/index.js",
"groupTitle": "Note"
},
{
"type": "delete",
"url": "/user/me",
"title": "Delete account",
"name": "DeleteUser",
"group": "User",
"version": "0.0.0",
"filename": "app/routes/user/index.js",
"groupTitle": "User"
},
{
"type": "get",
"url": "/user/me",
"title": "Get user information",
"name": "GetUser",
"group": "User",
"success": {
"fields": {
"Success 200": [
@ -116,24 +272,34 @@ define({ "api": [
"groupTitle": "User"
},
{
"type": "get",
"url": "/user",
"title": "Request all Users information",
"name": "GetUsers",
"type": "put",
"url": "/user/me",
"title": "Update account information",
"name": "UpdateUser",
"group": "User",
"parameter": {
"success": {
"fields": {
"Parameter": [
"Success 200": [
{
"group": "Parameter",
"type": "Number",
"group": "Success 200",
"type": "Object",
"optional": false,
"field": "id",
"description": "<p>Users unique ID.</p>"
"field": "user",
"description": "<p>User object.</p>"
}
]
}
},
"version": "0.0.0",
"filename": "app/routes/user/index.js",
"groupTitle": "User"
},
{
"type": "get",
"url": "/user/me/notes",
"title": "Get all notes",
"name": "GetNotesByUserId",
"group": "User_notes",
"success": {
"fields": {
"Success 200": [
@ -142,13 +308,13 @@ define({ "api": [
"type": "Array",
"optional": false,
"field": "Array",
"description": "<p>Array of User objects.</p>"
"description": "<p>Notes of the user.</p>"
}
]
}
},
"version": "0.0.0",
"filename": "app/routes/user/index.js",
"groupTitle": "User"
"groupTitle": "User_notes"
}
] });

View File

@ -1,10 +1,87 @@
[
{
"type": "get",
"url": "/note",
"title": "Request all notes",
"name": "GetNotes",
"group": "Note",
"type": "post",
"url": "/auth/login",
"title": "Get access token",
"name": "Login",
"group": "Auth",
"parameter": {
"fields": {
"Parameter": [
{
"group": "Parameter",
"type": "String",
"optional": false,
"field": "username",
"description": "<p>username of the user.</p>"
},
{
"group": "Parameter",
"type": "String",
"optional": false,
"field": "password",
"description": "<p>password of the user.</p>"
}
]
}
},
"success": {
"fields": {
"Success 200": [
{
"group": "Success 200",
"type": "string",
"optional": false,
"field": "jwt_token",
"description": "<p>JWT token.</p>"
}
]
}
},
"version": "0.0.0",
"filename": "app/routes/auth/index.js",
"groupTitle": "Auth"
},
{
"type": "post",
"url": "/auth/register",
"title": "Register",
"name": "Register",
"group": "Auth",
"parameter": {
"fields": {
"Parameter": [
{
"group": "Parameter",
"type": "String",
"optional": false,
"field": "firstname",
"description": "<p>Firstname of the user.</p>"
},
{
"group": "Parameter",
"type": "String",
"optional": false,
"field": "lastname",
"description": "<p>Lastname of the user.</p>"
},
{
"group": "Parameter",
"type": "String",
"optional": false,
"field": "username",
"description": "<p>username of the user.</p>"
},
{
"group": "Parameter",
"type": "String",
"optional": false,
"field": "password",
"description": "<p>password of the user.</p>"
}
]
}
},
"success": {
"fields": {
"Success 200": [
@ -19,13 +96,59 @@
}
},
"version": "0.0.0",
"filename": "app/routes/auth/index.js",
"groupTitle": "Auth"
},
{
"type": "post",
"url": "/note",
"title": "Create note",
"name": "CreateNote",
"group": "Note",
"success": {
"fields": {
"Success 200": [
{
"group": "Success 200",
"type": "Object",
"optional": false,
"field": "Object",
"description": "<p>Created note.</p>"
}
]
}
},
"version": "0.0.0",
"filename": "app/routes/note/index.js",
"groupTitle": "Note"
},
{
"type": "delete",
"url": "/note/:id",
"title": "Delete note",
"name": "DeleteNote",
"group": "Note",
"parameter": {
"fields": {
"Parameter": [
{
"group": "Parameter",
"type": "String",
"optional": false,
"field": "id",
"description": "<p>Note unique ID.</p>"
}
]
}
},
"version": "0.0.0",
"filename": "app/routes/note/index.js",
"groupTitle": "Note"
},
{
"type": "get",
"url": "/note/:id",
"title": "Request Note information",
"title": "Get note",
"name": "GetNotes",
"group": "Note",
"parameter": {
@ -33,10 +156,10 @@
"Parameter": [
{
"group": "Parameter",
"type": "Number",
"type": "String",
"optional": false,
"field": "id",
"description": "<p>Notes unique ID.</p>"
"description": "<p>Note unique ID.</p>"
}
]
}
@ -66,24 +189,57 @@
"groupTitle": "Note"
},
{
"type": "get",
"url": "/user/:id",
"title": "Request User information",
"name": "GetUser",
"group": "User",
"type": "put",
"url": "/note/:id",
"title": "Update note",
"name": "UpdateNote",
"group": "Note",
"parameter": {
"fields": {
"Parameter": [
{
"group": "Parameter",
"type": "Number",
"type": "String",
"optional": false,
"field": "id",
"description": "<p>Users unique ID.</p>"
"description": "<p>Note unique ID.</p>"
}
]
}
},
"success": {
"fields": {
"Success 200": [
{
"group": "Success 200",
"type": "Object",
"optional": false,
"field": "Object",
"description": "<p>Updated note.</p>"
}
]
}
},
"version": "0.0.0",
"filename": "app/routes/note/index.js",
"groupTitle": "Note"
},
{
"type": "delete",
"url": "/user/me",
"title": "Delete account",
"name": "DeleteUser",
"group": "User",
"version": "0.0.0",
"filename": "app/routes/user/index.js",
"groupTitle": "User"
},
{
"type": "get",
"url": "/user/me",
"title": "Get user information",
"name": "GetUser",
"group": "User",
"success": {
"fields": {
"Success 200": [
@ -116,24 +272,34 @@
"groupTitle": "User"
},
{
"type": "get",
"url": "/user",
"title": "Request all Users information",
"name": "GetUsers",
"type": "put",
"url": "/user/me",
"title": "Update account information",
"name": "UpdateUser",
"group": "User",
"parameter": {
"success": {
"fields": {
"Parameter": [
"Success 200": [
{
"group": "Parameter",
"type": "Number",
"group": "Success 200",
"type": "Object",
"optional": false,
"field": "id",
"description": "<p>Users unique ID.</p>"
"field": "user",
"description": "<p>User object.</p>"
}
]
}
},
"version": "0.0.0",
"filename": "app/routes/user/index.js",
"groupTitle": "User"
},
{
"type": "get",
"url": "/user/me/notes",
"title": "Get all notes",
"name": "GetNotesByUserId",
"group": "User_notes",
"success": {
"fields": {
"Success 200": [
@ -142,13 +308,13 @@
"type": "Array",
"optional": false,
"field": "Array",
"description": "<p>Array of User objects.</p>"
"description": "<p>Notes of the user.</p>"
}
]
}
},
"version": "0.0.0",
"filename": "app/routes/user/index.js",
"groupTitle": "User"
"groupTitle": "User_notes"
}
]

View File

@ -8,7 +8,7 @@ define({
"apidoc": "0.3.0",
"generator": {
"name": "apidoc",
"time": "2018-11-12T15:27:44.007Z",
"time": "2018-11-14T16:18:06.827Z",
"url": "http://apidocjs.com",
"version": "0.17.7"
}

View File

@ -8,7 +8,7 @@
"apidoc": "0.3.0",
"generator": {
"name": "apidoc",
"time": "2018-11-12T15:27:44.007Z",
"time": "2018-11-14T16:18:06.827Z",
"url": "http://apidocjs.com",
"version": "0.17.7"
}

View File

@ -1,3 +1,5 @@
require('./app/db/db.connect');
const express = require('express');
const routes = require('./app/routes');
@ -7,6 +9,14 @@ const port = process.env.PORT || 8080; // set our port
app.use('/', routes);
app.use((err, req, res, next) => {
res.status(err.status || 400).json({ success: false, message: err.message || 'An error occured.', errors: err.error || [] });
});
app.use((req, res) => {
res.status(404).json({ message: 'Resource not found.' });
});
// Start the server
app.listen(port);
console.log('Server started on port ' + port);
console.log(`Server started on port ${port}`);

1592
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -4,19 +4,29 @@
"description": "",
"main": "index.js",
"dependencies": {
"bcrypt-nodejs": "0.0.3",
"body-parser": "^1.18.3",
"express": "^4.16.4",
"mongoose": "^5.3.11"
"joi": "^14.0.6",
"jsonwebtoken": "^8.3.0",
"mongoose": "^5.3.11",
"passport": "^0.4.0"
},
"devDependencies": {
"apidoc": "^0.17.7"
"apidoc": "^0.17.7",
"eslint": "^5.9.0",
"eslint-config-airbnb": "^17.1.0",
"eslint-config-airbnb-base": "^13.1.0",
"eslint-plugin-import": "^2.14.0",
"eslint-plugin-jsx-a11y": "^6.1.2",
"eslint-plugin-react": "^7.11.1"
},
"apidoc": {
"title": "Mooc API"
},
"scripts": {
"doc":"apidoc -i ./app/routes -o ./docs",
"test": "echo \"Error: no test specified\" && exit 1"
"docs": "apidoc -i ./app/routes -o ./docs",
"test": "eslint ./ && npm run docs"
},
"repository": {
"type": "git",