commit
03701bc0de
|
@ -1,3 +1,9 @@
|
|||
{
|
||||
"extends": "airbnb-base"
|
||||
}
|
||||
"extends": "airbnb-base",
|
||||
"rules": {
|
||||
"max-len": ["error", { "code": 90, "comments": 120 }],
|
||||
"no-param-reassign": ["error", { "props": false }],
|
||||
"no-underscore-dangle": ["error", { "allow": ["_id"] }],
|
||||
"no-unused-vars": ["error", {"args":"none"}]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,11 @@ const UserSchema = new Schema({
|
|||
type: String, required: [true, "can't be blank"],
|
||||
},
|
||||
email: {
|
||||
type: String, lowercase: true, unique: true, required: [true, "can't be blank"], index: true,
|
||||
type: String,
|
||||
lowercase: true,
|
||||
unique: true,
|
||||
required: [true, "can't be blank"],
|
||||
index: true,
|
||||
},
|
||||
password: {
|
||||
type: String, required: [true, "can't be blank"],
|
||||
|
|
|
@ -4,8 +4,8 @@ const register = require('./register');
|
|||
const login = require('./login');
|
||||
const reset = require('./reset');
|
||||
|
||||
const RegisterValidation = require.main.require('./app/validation/register');
|
||||
const LoginValidation = require.main.require('./app/validation/login');
|
||||
const RegisterValidation = require.main.require('./app/validation/auth/register');
|
||||
const LoginValidation = require.main.require('./app/validation/auth/login');
|
||||
|
||||
/**
|
||||
* @api {post} /auth/register Register
|
||||
|
@ -29,7 +29,7 @@ auth.post('/register', RegisterValidation, register);
|
|||
* @apiParam {String} email email of the user.
|
||||
* @apiParam {String} password password of the user.
|
||||
*
|
||||
* @apiSuccess {string} access_token Access token.
|
||||
* @apiSuccess {String} access_token Access token.
|
||||
*/
|
||||
auth.post('/login', LoginValidation, login);
|
||||
|
||||
|
|
|
@ -13,7 +13,10 @@ module.exports = (req, res, next) => {
|
|||
if (err) throw err;
|
||||
|
||||
if (!user) {
|
||||
return next({ status: 400, message: 'Authentication failed. User not found.' });
|
||||
return next({
|
||||
status: 400,
|
||||
message: 'Authentication failed. User not found.',
|
||||
});
|
||||
}
|
||||
|
||||
// check if password matches
|
||||
|
@ -25,7 +28,11 @@ module.exports = (req, res, next) => {
|
|||
email: user.email,
|
||||
};
|
||||
|
||||
const token = jwt.sign({ user: dataUser }, secret, { expiresIn: '12h' });
|
||||
const token = jwt.sign({
|
||||
user: dataUser,
|
||||
}, secret, {
|
||||
expiresIn: '3h',
|
||||
});
|
||||
|
||||
// return the information including token as JSON
|
||||
return res.json({
|
||||
|
@ -40,7 +47,10 @@ module.exports = (req, res, next) => {
|
|||
});
|
||||
}
|
||||
|
||||
return next({ status: 401, message: 'Authentication failed. Wrong password.' });
|
||||
return next({
|
||||
status: 401,
|
||||
message: 'Authentication failed. Wrong password.',
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
|
@ -13,14 +13,21 @@ module.exports = (req, res, next) => {
|
|||
password: passwordHash,
|
||||
});
|
||||
|
||||
UserModel.countDocuments({ email: req.body.email }, (err, c) => {
|
||||
if (c !== 0) {
|
||||
return next({ status: 401, message: 'Email is already taken by another user.' });
|
||||
UserModel.countDocuments({ email: req.body.email }, (err, count) => {
|
||||
if (count !== 0) {
|
||||
return next({
|
||||
status: 401,
|
||||
message: 'Email is already taken by another user.',
|
||||
});
|
||||
}
|
||||
|
||||
return User.save((saveErr) => {
|
||||
if (saveErr) {
|
||||
return next({ status: 500, message: 'Database error', error: [saveErr] });
|
||||
return next({
|
||||
status: 500,
|
||||
message: 'Database error',
|
||||
error: [saveErr],
|
||||
});
|
||||
}
|
||||
|
||||
return res.status(201).json({ success: true, message: 'Success' });
|
||||
|
|
|
@ -6,7 +6,11 @@ module.exports = (req, res, next) => {
|
|||
|
||||
const { user } = jwt.decode(req.headers.authorization);
|
||||
|
||||
const Note = new NoteModel({ title: req.body.title, text: req.body.text, user: user.id });
|
||||
const Note = new NoteModel({
|
||||
title: req.body.title,
|
||||
text: req.body.text,
|
||||
user: user.id,
|
||||
});
|
||||
|
||||
Note.save((err) => {
|
||||
if (err) {
|
||||
|
|
|
@ -7,7 +7,7 @@ const remove = require('./delete');
|
|||
|
||||
const CreateValidation = require.main.require('./app/validation/note/create');
|
||||
const UpdateValidation = require.main.require('./app/validation/note/update');
|
||||
const Authentication = require.main.require('./app/validation/auth');
|
||||
const Authentication = require.main.require('./app/validation/auth/auth');
|
||||
|
||||
/**
|
||||
* @api {get} /note/:id Get note
|
||||
|
@ -16,8 +16,8 @@ const Authentication = require.main.require('./app/validation/auth');
|
|||
*
|
||||
* @apiParam {String} id Note unique ID.
|
||||
*
|
||||
* @apiSuccess {string} title Title of the note.
|
||||
* @apiSuccess {string} text Text of the note.
|
||||
* @apiSuccess {String} title Title of the note.
|
||||
* @apiSuccess {String} text Text of the note.
|
||||
*/
|
||||
note.get('/:id', Authentication, single);
|
||||
|
||||
|
@ -30,8 +30,8 @@ note.get('/:id', Authentication, single);
|
|||
* "Authorization": "<Access_Token>"
|
||||
* }
|
||||
*
|
||||
* @apiSuccess {string} title Title of the note.
|
||||
* @apiSuccess {string} text Text of the note.
|
||||
* @apiSuccess {String} title Title of the note.
|
||||
* @apiSuccess {String} text Text of the note.
|
||||
*/
|
||||
note.post('/', Authentication, CreateValidation, create);
|
||||
|
||||
|
@ -42,8 +42,8 @@ note.post('/', Authentication, CreateValidation, create);
|
|||
*
|
||||
* @apiParam {String} id Note unique ID.
|
||||
*
|
||||
* @apiSuccess {string} title Title of the note.
|
||||
* @apiSuccess {string} text Text of the note.
|
||||
* @apiSuccess {String} title Title of the note.
|
||||
* @apiSuccess {String} text Text of the note.
|
||||
*/
|
||||
note.put('/:id', Authentication, UpdateValidation, update);
|
||||
|
||||
|
@ -58,7 +58,7 @@ note.put('/:id', Authentication, UpdateValidation, update);
|
|||
* "message": "Note successfully deleted."
|
||||
* }
|
||||
* @apiErrorExample {json} Error-Response:
|
||||
* HTTP/1.1 403 Not Found
|
||||
* HTTP/1.1 403 Forbidden
|
||||
* {
|
||||
* "success": false,
|
||||
* "message": "Access forbidden.",
|
||||
|
|
|
@ -1,5 +1,42 @@
|
|||
module.exports = (req, res) => {
|
||||
const user = {};
|
||||
const mongoose = require('mongoose');
|
||||
const jwt = require('jsonwebtoken');
|
||||
const bcrypt = require('bcrypt-nodejs');
|
||||
|
||||
res.status(200).json({ user });
|
||||
module.exports = (req, res, next) => {
|
||||
const UserModel = mongoose.model('User');
|
||||
|
||||
const { user } = jwt.decode(req.headers.authorization);
|
||||
|
||||
return UserModel.findOne({ _id: user.id })
|
||||
.lean()
|
||||
.exec()
|
||||
.then((User) => {
|
||||
if (User === null) {
|
||||
return next({ status: 404, message: 'User does not exists.' });
|
||||
}
|
||||
|
||||
return bcrypt.compare(
|
||||
req.body.password,
|
||||
User.password,
|
||||
(error, result) => {
|
||||
if (!result || error) {
|
||||
return next({
|
||||
status: 401,
|
||||
message: 'Authentication failed. Wrong password.',
|
||||
});
|
||||
}
|
||||
|
||||
return UserModel.deleteOne({ _id: User._id }, (err) => {
|
||||
if (err) {
|
||||
return next({ status: 500 });
|
||||
}
|
||||
|
||||
return res.status(204).json({
|
||||
success: true,
|
||||
message: 'Account deleted.',
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
};
|
||||
|
|
|
@ -5,13 +5,16 @@ const update = require('./update');
|
|||
const remove = require('./delete');
|
||||
const notes = require('./notes');
|
||||
|
||||
const Authentication = require.main.require('./app/validation/auth');
|
||||
const Authentication = require.main.require('./app/validation/auth/auth');
|
||||
const UpdateValidation = require.main.require('./app/validation/user/update');
|
||||
const DeleteValidation = require.main.require('./app/validation/user/delete');
|
||||
|
||||
/**
|
||||
* @api {get} /user/me Get account information
|
||||
* @apiName GetUser
|
||||
* @apiGroup User
|
||||
*
|
||||
* @apiSuccess {String} id Unique ID of the User.
|
||||
* @apiSuccess {String} firstname Firstname of the User.
|
||||
* @apiSuccess {String} lastname Lastname of the User.
|
||||
* @apiSuccess {String} email Email of the User.
|
||||
|
@ -22,21 +25,29 @@ user.get('/me', Authentication, profile);
|
|||
* @api {put} /user/me Update account information
|
||||
* @apiName UpdateUser
|
||||
* @apiGroup User
|
||||
* @apiDescription Send only password and new_password to change the password. Otherwise they will be ignored.
|
||||
*
|
||||
* @apiParam {String} Firstname new firstname.
|
||||
* @apiParam {String} Lastname new lastname.
|
||||
* @apiParam {String} Email new email address.
|
||||
* @apiParam {String} firstname New firstname. (optional)
|
||||
* @apiParam {String} lastname New lastname. (optional)
|
||||
* @apiParam {String} email New email address. (optional)
|
||||
* @apiParam {String} password Actual password. (optional)
|
||||
* @apiParam {String} new_password New password (only if you passed password parameter).
|
||||
*
|
||||
* @apiSuccess {Object} user User object.
|
||||
* @apiSuccess {String} id Unique ID of the User.
|
||||
* @apiSuccess {String} firstname Firstname of the User.
|
||||
* @apiSuccess {String} lastname Lastname of the User.
|
||||
* @apiSuccess {String} email Email of the User.
|
||||
*/
|
||||
user.put('/me', Authentication, update);
|
||||
user.put('/me', Authentication, UpdateValidation, update);
|
||||
|
||||
/**
|
||||
* @api {delete} /user/me Delete account
|
||||
* @apiName DeleteUser
|
||||
* @apiGroup User
|
||||
*
|
||||
* @apiParam {String} password Account password.
|
||||
*/
|
||||
user.delete('/me', Authentication, remove);
|
||||
user.delete('/me', Authentication, DeleteValidation, remove);
|
||||
|
||||
/**
|
||||
* @api {get} /user/me/notes Get all notes
|
||||
|
|
|
@ -9,12 +9,6 @@ module.exports = (req, res, next) => {
|
|||
return UserModel.findById(user.id, 'id firstname lastname email')
|
||||
.lean()
|
||||
.exec()
|
||||
.then((result) => {
|
||||
if (result === null) {
|
||||
return next({ status: 401, message: 'User does not exists.' });
|
||||
}
|
||||
|
||||
return res.status(200).json(result);
|
||||
})
|
||||
.then(result => res.status(200).json(result))
|
||||
.catch(() => next({ status: 401, message: 'User does not exists.' }));
|
||||
};
|
||||
|
|
|
@ -1,5 +1,56 @@
|
|||
module.exports = (req, res) => {
|
||||
const user = {};
|
||||
const mongoose = require('mongoose');
|
||||
const jwt = require('jsonwebtoken');
|
||||
const bcrypt = require('bcrypt-nodejs');
|
||||
|
||||
res.status(200).json({ user });
|
||||
module.exports = (req, res, next) => {
|
||||
const UserModel = mongoose.model('User');
|
||||
|
||||
const { user } = jwt.decode(req.headers.authorization);
|
||||
|
||||
return UserModel.findOne({ _id: user.id }, (err, userObj) => {
|
||||
if (!userObj) {
|
||||
return next({ status: 401, message: 'User does not exists.' });
|
||||
}
|
||||
|
||||
if (req.body.password && req.body.new_password) {
|
||||
return bcrypt.compare(req.body.password, userObj.password, (error, result) => {
|
||||
if (!result || error) {
|
||||
return next(
|
||||
{
|
||||
status: 401,
|
||||
message: 'Authentication failed. Wrong password.',
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
return bcrypt.hash(req.body.new_password, null, null, (hashErr, hash) => {
|
||||
userObj.password = hash;
|
||||
|
||||
const response = {
|
||||
_id: userObj._id,
|
||||
firstname: userObj.firstname,
|
||||
lastname: userObj.lastname,
|
||||
email: userObj.email,
|
||||
createdAt: userObj.createdAt,
|
||||
};
|
||||
|
||||
return userObj.save(() => res.status(200).json(response));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
userObj.firstname = req.body.firstname || userObj.firstname;
|
||||
userObj.lastname = req.body.lastname || userObj.lastname;
|
||||
userObj.email = req.body.email || userObj.email;
|
||||
|
||||
const response = {
|
||||
_id: userObj._id,
|
||||
firstname: userObj.firstname,
|
||||
lastname: userObj.lastname,
|
||||
email: userObj.email,
|
||||
createdAt: userObj.createdAt,
|
||||
};
|
||||
|
||||
return userObj.save(() => res.status(200).json(response));
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
const Joi = require('joi');
|
||||
const jwt = require('jsonwebtoken');
|
||||
const mongoose = require('mongoose');
|
||||
|
||||
const secret = require.main.require('./config/secret');
|
||||
|
||||
module.exports = (req, res, next) => {
|
||||
const UserModel = mongoose.model('User');
|
||||
|
||||
const schema = Joi.object().keys({
|
||||
access_token: Joi.string().required(),
|
||||
});
|
||||
|
@ -21,7 +24,21 @@ module.exports = (req, res, next) => {
|
|||
return next({ status: 401, message: 'Token error.', error: [err] });
|
||||
}
|
||||
|
||||
return next();
|
||||
return UserModel.countDocuments(
|
||||
{
|
||||
_id: decoded.user.id,
|
||||
}, (QueryError, count) => {
|
||||
if (count !== 1) {
|
||||
return next({
|
||||
status: 401,
|
||||
message: 'Your session is invalid. Please try sign in again.',
|
||||
error: [],
|
||||
});
|
||||
}
|
||||
|
||||
return next();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
};
|
|
@ -12,7 +12,11 @@ module.exports = (req, res, next) => {
|
|||
},
|
||||
schema, (validateErr) => {
|
||||
if (validateErr) {
|
||||
return next({ status: 400, message: 'Form is invalid.', error: validateErr.details });
|
||||
return next({
|
||||
status: 400,
|
||||
message: 'Form is invalid.',
|
||||
error: validateErr.details,
|
||||
});
|
||||
}
|
||||
|
||||
return next();
|
|
@ -16,7 +16,11 @@ module.exports = (req, res, next) => {
|
|||
},
|
||||
schema, (validateErr) => {
|
||||
if (validateErr) {
|
||||
return next({ status: 400, message: 'Form is invalid.', error: validateErr.details });
|
||||
return next({
|
||||
status: 400,
|
||||
message: 'Form is invalid.',
|
||||
error: validateErr.details,
|
||||
});
|
||||
}
|
||||
|
||||
return next();
|
|
@ -12,7 +12,11 @@ module.exports = (req, res, next) => {
|
|||
},
|
||||
schema, (validateErr) => {
|
||||
if (validateErr) {
|
||||
return next({ status: 400, message: 'Form is invalid.', error: validateErr.details });
|
||||
return next({
|
||||
status: 400,
|
||||
message: 'Form is invalid.',
|
||||
error: validateErr.details,
|
||||
});
|
||||
}
|
||||
|
||||
return next();
|
||||
|
|
|
@ -12,7 +12,11 @@ module.exports = (req, res, next) => {
|
|||
},
|
||||
schema, (validateErr) => {
|
||||
if (validateErr) {
|
||||
return next({ status: 400, message: 'Form is invalid.', error: validateErr.details });
|
||||
return next({
|
||||
status: 400,
|
||||
message: 'Form is invalid.',
|
||||
error: validateErr.details,
|
||||
});
|
||||
}
|
||||
|
||||
return next();
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
const Joi = require('joi');
|
||||
|
||||
module.exports = (req, res, next) => {
|
||||
const schema = Joi.object().keys({
|
||||
password: Joi.string().required(),
|
||||
});
|
||||
|
||||
Joi.validate({
|
||||
password: req.body.password,
|
||||
},
|
||||
schema, (validateErr) => {
|
||||
if (validateErr) {
|
||||
return next({
|
||||
status: 400,
|
||||
message: 'Form is invalid.',
|
||||
error: validateErr.details,
|
||||
});
|
||||
}
|
||||
|
||||
return next();
|
||||
});
|
||||
};
|
|
@ -0,0 +1,33 @@
|
|||
const Joi = require('joi');
|
||||
|
||||
module.exports = (req, res, next) => {
|
||||
const schema = Joi.object().keys({
|
||||
firstname: Joi.string().min(2),
|
||||
lastname: Joi.string().min(2),
|
||||
email: Joi.string().email({ minDomainAtoms: 2 }),
|
||||
password: Joi.string(),
|
||||
new_password: Joi.string(),
|
||||
}).with('password', 'new_password')
|
||||
.without('firstname', 'password')
|
||||
.without('lastname', 'password')
|
||||
.without('email', 'password');
|
||||
|
||||
Joi.validate({
|
||||
firstname: req.body.firstname,
|
||||
lastname: req.body.lastname,
|
||||
email: req.body.email,
|
||||
password: req.body.password,
|
||||
new_password: req.body.new_password,
|
||||
},
|
||||
schema, (validateErr) => {
|
||||
if (validateErr) {
|
||||
return next({
|
||||
status: 400,
|
||||
message: 'Form is invalid.',
|
||||
error: validateErr.details,
|
||||
});
|
||||
}
|
||||
|
||||
return next();
|
||||
});
|
||||
};
|
145
docs/api_data.js
145
docs/api_data.js
|
@ -12,8 +12,8 @@ define({ "api": [
|
|||
"group": "Parameter",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "username",
|
||||
"description": "<p>username of the user.</p>"
|
||||
"field": "email",
|
||||
"description": "<p>email of the user.</p>"
|
||||
},
|
||||
{
|
||||
"group": "Parameter",
|
||||
|
@ -30,7 +30,7 @@ define({ "api": [
|
|||
"Success 200": [
|
||||
{
|
||||
"group": "Success 200",
|
||||
"type": "string",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "access_token",
|
||||
"description": "<p>Access token.</p>"
|
||||
|
@ -69,8 +69,8 @@ define({ "api": [
|
|||
"group": "Parameter",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "username",
|
||||
"description": "<p>username of the user.</p>"
|
||||
"field": "email",
|
||||
"description": "<p>email of the user.</p>"
|
||||
},
|
||||
{
|
||||
"group": "Parameter",
|
||||
|
@ -99,6 +99,36 @@ define({ "api": [
|
|||
"filename": "app/routes/auth/index.js",
|
||||
"groupTitle": "Auth"
|
||||
},
|
||||
{
|
||||
"type": "post",
|
||||
"url": "/auth/reset-password",
|
||||
"title": "Reset password",
|
||||
"name": "ResetPass",
|
||||
"group": "Auth",
|
||||
"parameter": {
|
||||
"fields": {
|
||||
"Parameter": [
|
||||
{
|
||||
"group": "Parameter",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "email",
|
||||
"description": "<p>email of the user.</p>"
|
||||
},
|
||||
{
|
||||
"group": "Parameter",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "password",
|
||||
"description": "<p>password of the user.</p>"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"version": "0.0.0",
|
||||
"filename": "app/routes/auth/index.js",
|
||||
"groupTitle": "Auth"
|
||||
},
|
||||
{
|
||||
"type": "post",
|
||||
"url": "/note",
|
||||
|
@ -119,14 +149,14 @@ define({ "api": [
|
|||
"Success 200": [
|
||||
{
|
||||
"group": "Success 200",
|
||||
"type": "string",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "title",
|
||||
"description": "<p>Title of the note.</p>"
|
||||
},
|
||||
{
|
||||
"group": "Success 200",
|
||||
"type": "string",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "text",
|
||||
"description": "<p>Text of the note.</p>"
|
||||
|
@ -157,7 +187,7 @@ define({ "api": [
|
|||
"examples": [
|
||||
{
|
||||
"title": "Error-Response:",
|
||||
"content": "HTTP/1.1 403 Not Found\n{\n \"success\": false,\n \"message\": \"Access forbidden.\",\n \"errors\": []\n}",
|
||||
"content": "HTTP/1.1 403 Forbidden\n{\n \"success\": false,\n \"message\": \"Access forbidden.\",\n \"errors\": []\n}",
|
||||
"type": "json"
|
||||
}
|
||||
]
|
||||
|
@ -203,14 +233,14 @@ define({ "api": [
|
|||
"Success 200": [
|
||||
{
|
||||
"group": "Success 200",
|
||||
"type": "string",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "title",
|
||||
"description": "<p>Title of the note.</p>"
|
||||
},
|
||||
{
|
||||
"group": "Success 200",
|
||||
"type": "string",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "text",
|
||||
"description": "<p>Text of the note.</p>"
|
||||
|
@ -246,14 +276,14 @@ define({ "api": [
|
|||
"Success 200": [
|
||||
{
|
||||
"group": "Success 200",
|
||||
"type": "string",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "title",
|
||||
"description": "<p>Title of the note.</p>"
|
||||
},
|
||||
{
|
||||
"group": "Success 200",
|
||||
"type": "string",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "text",
|
||||
"description": "<p>Text of the note.</p>"
|
||||
|
@ -271,6 +301,19 @@ define({ "api": [
|
|||
"title": "Delete account",
|
||||
"name": "DeleteUser",
|
||||
"group": "User",
|
||||
"parameter": {
|
||||
"fields": {
|
||||
"Parameter": [
|
||||
{
|
||||
"group": "Parameter",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "password",
|
||||
"description": "<p>Account password.</p>"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"version": "0.0.0",
|
||||
"filename": "app/routes/user/index.js",
|
||||
"groupTitle": "User"
|
||||
|
@ -278,12 +321,19 @@ define({ "api": [
|
|||
{
|
||||
"type": "get",
|
||||
"url": "/user/me",
|
||||
"title": "Get user information",
|
||||
"title": "Get account information",
|
||||
"name": "GetUser",
|
||||
"group": "User",
|
||||
"success": {
|
||||
"fields": {
|
||||
"Success 200": [
|
||||
{
|
||||
"group": "Success 200",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "id",
|
||||
"description": "<p>Unique ID of the User.</p>"
|
||||
},
|
||||
{
|
||||
"group": "Success 200",
|
||||
"type": "String",
|
||||
|
@ -318,15 +368,78 @@ define({ "api": [
|
|||
"title": "Update account information",
|
||||
"name": "UpdateUser",
|
||||
"group": "User",
|
||||
"description": "<p>Send only password and new_password to change the password. Otherwise they will be ignored.</p>",
|
||||
"parameter": {
|
||||
"fields": {
|
||||
"Parameter": [
|
||||
{
|
||||
"group": "Parameter",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "firstname",
|
||||
"description": "<p>New firstname. (optional)</p>"
|
||||
},
|
||||
{
|
||||
"group": "Parameter",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "lastname",
|
||||
"description": "<p>New lastname. (optional)</p>"
|
||||
},
|
||||
{
|
||||
"group": "Parameter",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "email",
|
||||
"description": "<p>New email address. (optional)</p>"
|
||||
},
|
||||
{
|
||||
"group": "Parameter",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "password",
|
||||
"description": "<p>Actual password. (optional)</p>"
|
||||
},
|
||||
{
|
||||
"group": "Parameter",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "new_password",
|
||||
"description": "<p>New password (only if you passed password parameter).</p>"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"success": {
|
||||
"fields": {
|
||||
"Success 200": [
|
||||
{
|
||||
"group": "Success 200",
|
||||
"type": "Object",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "user",
|
||||
"description": "<p>User object.</p>"
|
||||
"field": "id",
|
||||
"description": "<p>Unique ID of the User.</p>"
|
||||
},
|
||||
{
|
||||
"group": "Success 200",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "firstname",
|
||||
"description": "<p>Firstname of the User.</p>"
|
||||
},
|
||||
{
|
||||
"group": "Success 200",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "lastname",
|
||||
"description": "<p>Lastname of the User.</p>"
|
||||
},
|
||||
{
|
||||
"group": "Success 200",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "email",
|
||||
"description": "<p>Email of the User.</p>"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
"group": "Parameter",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "username",
|
||||
"description": "<p>username of the user.</p>"
|
||||
"field": "email",
|
||||
"description": "<p>email of the user.</p>"
|
||||
},
|
||||
{
|
||||
"group": "Parameter",
|
||||
|
@ -30,7 +30,7 @@
|
|||
"Success 200": [
|
||||
{
|
||||
"group": "Success 200",
|
||||
"type": "string",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "access_token",
|
||||
"description": "<p>Access token.</p>"
|
||||
|
@ -69,8 +69,8 @@
|
|||
"group": "Parameter",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "username",
|
||||
"description": "<p>username of the user.</p>"
|
||||
"field": "email",
|
||||
"description": "<p>email of the user.</p>"
|
||||
},
|
||||
{
|
||||
"group": "Parameter",
|
||||
|
@ -99,6 +99,36 @@
|
|||
"filename": "app/routes/auth/index.js",
|
||||
"groupTitle": "Auth"
|
||||
},
|
||||
{
|
||||
"type": "post",
|
||||
"url": "/auth/reset-password",
|
||||
"title": "Reset password",
|
||||
"name": "ResetPass",
|
||||
"group": "Auth",
|
||||
"parameter": {
|
||||
"fields": {
|
||||
"Parameter": [
|
||||
{
|
||||
"group": "Parameter",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "email",
|
||||
"description": "<p>email of the user.</p>"
|
||||
},
|
||||
{
|
||||
"group": "Parameter",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "password",
|
||||
"description": "<p>password of the user.</p>"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"version": "0.0.0",
|
||||
"filename": "app/routes/auth/index.js",
|
||||
"groupTitle": "Auth"
|
||||
},
|
||||
{
|
||||
"type": "post",
|
||||
"url": "/note",
|
||||
|
@ -119,14 +149,14 @@
|
|||
"Success 200": [
|
||||
{
|
||||
"group": "Success 200",
|
||||
"type": "string",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "title",
|
||||
"description": "<p>Title of the note.</p>"
|
||||
},
|
||||
{
|
||||
"group": "Success 200",
|
||||
"type": "string",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "text",
|
||||
"description": "<p>Text of the note.</p>"
|
||||
|
@ -157,7 +187,7 @@
|
|||
"examples": [
|
||||
{
|
||||
"title": "Error-Response:",
|
||||
"content": "HTTP/1.1 403 Not Found\n{\n \"success\": false,\n \"message\": \"Access forbidden.\",\n \"errors\": []\n}",
|
||||
"content": "HTTP/1.1 403 Forbidden\n{\n \"success\": false,\n \"message\": \"Access forbidden.\",\n \"errors\": []\n}",
|
||||
"type": "json"
|
||||
}
|
||||
]
|
||||
|
@ -203,14 +233,14 @@
|
|||
"Success 200": [
|
||||
{
|
||||
"group": "Success 200",
|
||||
"type": "string",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "title",
|
||||
"description": "<p>Title of the note.</p>"
|
||||
},
|
||||
{
|
||||
"group": "Success 200",
|
||||
"type": "string",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "text",
|
||||
"description": "<p>Text of the note.</p>"
|
||||
|
@ -246,14 +276,14 @@
|
|||
"Success 200": [
|
||||
{
|
||||
"group": "Success 200",
|
||||
"type": "string",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "title",
|
||||
"description": "<p>Title of the note.</p>"
|
||||
},
|
||||
{
|
||||
"group": "Success 200",
|
||||
"type": "string",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "text",
|
||||
"description": "<p>Text of the note.</p>"
|
||||
|
@ -271,6 +301,19 @@
|
|||
"title": "Delete account",
|
||||
"name": "DeleteUser",
|
||||
"group": "User",
|
||||
"parameter": {
|
||||
"fields": {
|
||||
"Parameter": [
|
||||
{
|
||||
"group": "Parameter",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "password",
|
||||
"description": "<p>Account password.</p>"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"version": "0.0.0",
|
||||
"filename": "app/routes/user/index.js",
|
||||
"groupTitle": "User"
|
||||
|
@ -278,12 +321,19 @@
|
|||
{
|
||||
"type": "get",
|
||||
"url": "/user/me",
|
||||
"title": "Get user information",
|
||||
"title": "Get account information",
|
||||
"name": "GetUser",
|
||||
"group": "User",
|
||||
"success": {
|
||||
"fields": {
|
||||
"Success 200": [
|
||||
{
|
||||
"group": "Success 200",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "id",
|
||||
"description": "<p>Unique ID of the User.</p>"
|
||||
},
|
||||
{
|
||||
"group": "Success 200",
|
||||
"type": "String",
|
||||
|
@ -318,15 +368,78 @@
|
|||
"title": "Update account information",
|
||||
"name": "UpdateUser",
|
||||
"group": "User",
|
||||
"description": "<p>Send only password and new_password to change the password. Otherwise they will be ignored.</p>",
|
||||
"parameter": {
|
||||
"fields": {
|
||||
"Parameter": [
|
||||
{
|
||||
"group": "Parameter",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "firstname",
|
||||
"description": "<p>New firstname. (optional)</p>"
|
||||
},
|
||||
{
|
||||
"group": "Parameter",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "lastname",
|
||||
"description": "<p>New lastname. (optional)</p>"
|
||||
},
|
||||
{
|
||||
"group": "Parameter",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "email",
|
||||
"description": "<p>New email address. (optional)</p>"
|
||||
},
|
||||
{
|
||||
"group": "Parameter",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "password",
|
||||
"description": "<p>Actual password. (optional)</p>"
|
||||
},
|
||||
{
|
||||
"group": "Parameter",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "new_password",
|
||||
"description": "<p>New password (only if you passed password parameter).</p>"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"success": {
|
||||
"fields": {
|
||||
"Success 200": [
|
||||
{
|
||||
"group": "Success 200",
|
||||
"type": "Object",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "user",
|
||||
"description": "<p>User object.</p>"
|
||||
"field": "id",
|
||||
"description": "<p>Unique ID of the User.</p>"
|
||||
},
|
||||
{
|
||||
"group": "Success 200",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "firstname",
|
||||
"description": "<p>Firstname of the User.</p>"
|
||||
},
|
||||
{
|
||||
"group": "Success 200",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "lastname",
|
||||
"description": "<p>Lastname of the User.</p>"
|
||||
},
|
||||
{
|
||||
"group": "Success 200",
|
||||
"type": "String",
|
||||
"optional": false,
|
||||
"field": "email",
|
||||
"description": "<p>Email of the User.</p>"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ define({
|
|||
"apidoc": "0.3.0",
|
||||
"generator": {
|
||||
"name": "apidoc",
|
||||
"time": "2018-11-15T18:00:50.902Z",
|
||||
"time": "2018-11-17T00:00:47.768Z",
|
||||
"url": "http://apidocjs.com",
|
||||
"version": "0.17.7"
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
"apidoc": "0.3.0",
|
||||
"generator": {
|
||||
"name": "apidoc",
|
||||
"time": "2018-11-15T18:00:50.902Z",
|
||||
"time": "2018-11-17T00:00:47.768Z",
|
||||
"url": "http://apidocjs.com",
|
||||
"version": "0.17.7"
|
||||
}
|
||||
|
|
6
index.js
6
index.js
|
@ -10,7 +10,11 @@ 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 || [] });
|
||||
res.status(err.status || 400).json({
|
||||
success: false,
|
||||
message: err.message || 'An error occured.',
|
||||
errors: err.error || [],
|
||||
});
|
||||
});
|
||||
|
||||
app.use((req, res) => {
|
||||
|
|
44
todo.md
44
todo.md
|
@ -2,11 +2,49 @@
|
|||
|
||||
### Routes
|
||||
|
||||
- PUT /user/me (tous les champs sauf password) (200 ok avec en body le user après édition)
|
||||
- PUT /user/me (si tu vois password et new password, ou mets une autre route si tu veux) (200 ok avec le user après édition mais sans mot de passe bien sûr)
|
||||
- DELETE /users/me (supprimer le profil) (204 no content, car le user est supprimé et tu ne me renvoi rien)
|
||||
- POST /auth/rester-password (email) (optionnel si tu te sens pas chaud) (200 ok)
|
||||
|
||||
### Other
|
||||
|
||||
- eslint test
|
||||
- build test
|
||||
- ESlint test
|
||||
|
||||
## Specs
|
||||
|
||||
**Pourvoir s'inscrire, se connecter, réinitialiser mot de passe (non connecté) :**
|
||||
|
||||
- POST /auth/register (firstname, lastname, email, password)
|
||||
(201 created)
|
||||
- POST /auth/login (email, password) (200 ok avec en body le user et en header le token d'authentification)
|
||||
- POST /auth/rester-password (email) (optionnel si tu te sens pas chaud)
|
||||
(200 ok)
|
||||
|
||||
**Pouvoir voir / modifier / supprimer son profil (connecté):**
|
||||
|
||||
- PUT /user/me (tous les champs sauf password) (200 ok avec en body le user après édition)
|
||||
- PUT /user/me (si tu vois password et new password, ou mets une autre route si tu veux) (200 ok avec le user après édition mais sans mot de passe bien sûr)
|
||||
- DELETE /users/me (supprimer le profil) (204 no content, car le user est supprimé et tu ne me renvoi rien)
|
||||
- GET /users/me (renvoi le user) (200 ok avec en body le user) pouvoir gérer les notes (connecté)
|
||||
|
||||
**Notes:**
|
||||
|
||||
- POST /notes (title optionnel, text optionnel, lié a user connecté) (201 creatred)
|
||||
- PUT /notes/id (title optionnel, text optionnel) (200 ok avec en body la noté modifiée)
|
||||
- DELETE /notes/id (supprimer la note) (204 no content)
|
||||
- GET /user/me/ notes (toutes notes du user connecté)
|
||||
- GET /notes/id (get la note de cet id si elle appartient au user connecté)
|
||||
|
||||
**Finito ! C'est un crud avec un minimum de vérif qui sont :**
|
||||
|
||||
- Est-ce que le user est connecté ou non
|
||||
- Est-ce que le user est propriétaire de la ressource qu'il modifie ou supprime
|
||||
|
||||
C'est tout ce qu'il y a besoin de vérifier.
|
||||
|
||||
**Pour tout ce qui est erreur il n'y a que 4 règles à respecter :**
|
||||
|
||||
- Pas le droit car pas connecté : 401
|
||||
- Pas le droit car connecté mais ne t'appartient pas : 403
|
||||
- Ressource n'existe pas : 404
|
||||
- Erreur de validation (si tu veux en faire) : 400 bad request
|
||||
|
|
Loading…
Reference in New Issue