Skip to content

Commit

Permalink
Merge pull request #96 from irshadjsr21/issue-79
Browse files Browse the repository at this point in the history
Closes issue #79
  • Loading branch information
rajatmw1999 authored Mar 5, 2020
2 parents 2da572c + 09e144b commit 5e3a936
Show file tree
Hide file tree
Showing 13 changed files with 508 additions and 126 deletions.
19 changes: 19 additions & 0 deletions back-end/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions back-end/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"cors": "^2.8.5",
"dotenv": "^8.1.0",
"express": "^4.17.1",
"express-validator": "^6.4.0",
"jsonwebtoken": "^8.5.1",
"mongoose": "^5.7.5",
"mongoose-unique-validator": "^2.0.3",
Expand Down
21 changes: 21 additions & 0 deletions back-end/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const app = express();
const bodyParser = require("body-parser");
const cors = require("cors");
const errorHandler = require("error-handler");
const createError = require("http-errors");
const mongoose = require("mongoose");

require("./src/models/User");
Expand Down Expand Up @@ -40,6 +41,26 @@ mongoose.set("debug", true);

app.use(require("./src/routes"));

app.use("*", (req, res, next) => {
next(new createError(404, "Page not found."));
});

app.use((error, req, res, next) => {
if (error instanceof createError.HttpError) {
const obj = {
status: error.status,
message: error.message
};
if (error.errors) {
obj.errors = error.errors;
}
res.status(error.status).json(obj);
} else {
console.log(error);
res.status(500).json({ status: 500, message: 'Server error.' });
}
});

app.listen(app.get("port"), () => {
console.log(`Listening on port ${app.get("port")}`);
});
38 changes: 37 additions & 1 deletion back-end/src/models/User.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const mongoose = require('mongoose')
const { Schema } = mongoose
const bcrypt = require('bcryptjs')
const uniqueValidator = require('mongoose-unique-validator')
const { Schema } = mongoose

const UserSchema = new Schema({
username: {
Expand Down Expand Up @@ -71,6 +72,41 @@ UserSchema.methods.toJSON = function() {
}
}

const hashPassword = function(next) {
var user = this;
if (this.isModified('hash') || this.isNew) {
bcrypt.genSalt(10, function(err, salt) {
if (err) {
return next(err);
}
bcrypt.hash(user.hash, salt, function(err, hash) {
if (err) {
return next(err);
}
user.hash = hash;
next();
});
});
} else {
return next();
}
}

const checkPassword = async function(pass) {
return new Promise((resolve, reject) => {
bcrypt.compare(pass, this.hash, function(err, isMatch) {
if (err) {
reject(err);
}
resolve(isMatch);
});
});
}

UserSchema.plugin(uniqueValidator, { message: 'is already taken.'})

UserSchema.pre('save', hashPassword);

UserSchema.methods.checkPassword = checkPassword;

module.exports = mongoose.model('User', UserSchema)
31 changes: 20 additions & 11 deletions back-end/src/routes/api/books.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@

const router = require("express").Router();
const router = require('express').Router();
const request = require('request');
const createController = require('../createController');

router.post(
'/getBooks',
createController(async (req, res) => {
const query = req.body.bookQuery.split(/\s*\s/).join('+');

router.post("/getBooks", async (req, res) => {
const query = req.body.bookQuery.split(/\s*\s/).join("+");

request("https://www.googleapis.com/books/v1/volumes?q=" + query, {json: true}, (err, response, body) => {
if(err) { return console.log(err); }
return res.json(response);
});
});
request(
'https://www.googleapis.com/books/v1/volumes?q=' + query,
{ json: true },
(err, response, body) => {
if (err) {
return console.log(err);
}
return res.json(response);
},
);
}),
);

module.exports = router;
module.exports = router;
13 changes: 6 additions & 7 deletions back-end/src/routes/api/courses.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const router = require('express').Router();
const axios = require('axios');
const querystring = require('querystring');

const createController = require('../createController');
const udemyClientId = process.env.UDEMY_CLIENT_ID || '';
const udemyClientSecret = process.env.UDEMY_CLIENT_SECRET || '';
const udemyAuthKey = Buffer.from(
Expand All @@ -14,8 +15,9 @@ const http = axios.create({
},
});

router.get('/udemy', async (req, res, next) => {
try {
router.get(
'/udemy',
createController(async (req, res, next) => {
const fields = [
'search',
'price',
Expand All @@ -39,10 +41,7 @@ router.get('/udemy', async (req, res, next) => {
if (!data) throw new Error('No data present');

res.json({ courses: data.results });
} catch (error) {
console.log(error);
res.status(500).send();
}
});
}),
);

module.exports = router;
167 changes: 81 additions & 86 deletions back-end/src/routes/api/users.js
Original file line number Diff line number Diff line change
@@ -1,98 +1,93 @@
const router = require("express").Router();
const User = require("../../models/User");
const jwt = require("jsonwebtoken");
const bcrypt = require("bcryptjs");
const {
STATUS_OK,
USER_NOT_FOUND,
TOKEN_ERROR,
INCORRECT_PASSWORD
} = require("../../utils/constants");
const router = require('express').Router();
const createError = require('http-errors');
const createController = require('../createController');
const User = require('../../models/User');
const authValidator = require('../../validators/auth');
const jwt = require('../../utils/jwt');
const { USER_NOT_FOUND, INCORRECT_PASSWORD } = require('../../utils/constants');

router.post("/login", async (req, res, next) => {
let errors = {};
const { username, password } = req.body;
await User.findOne({ username }).then(user => {
if (!user) {
errors.user = USER_NOT_FOUND;
return res.status(404).json(errors);
}
bcrypt.compare(password, user.hash).then(isMatch => {
if (isMatch) {
const payload = {
id: user._id,
username: user.username
};
jwt.sign(
payload,
process.env.SECRET,
{
expiresIn: 3600
router.post(
'/login',
createController(
async (req, res) => {
const { username, password } = res.locals.inputBody;

const user = await User.findOne({ username });
if (!user)
throw new createError(404, USER_NOT_FOUND, {
errors: {
username: USER_NOT_FOUND,
},
(err, token) => {
if (err) console.error(TOKEN_ERROR, err);
else {
res.json({
success: true,
token
});
}
}
);
});
const isMatch = await user.checkPassword(password);
if (isMatch) {
const token = await jwt.sign(user);
res.status(200).json({
token,
});
} else {
errors.password = INCORRECT_PASSWORD;
return res.json(400).json(errors);
throw new createError(401, INCORRECT_PASSWORD, {
errors: { password: INCORRECT_PASSWORD },
});
}
});
});
});

router.post("/register", async (req, res) => {
const { username, password, email, name, birth } = req.body;
if (await User.findOne({ username })) {
return res.json({ error: 'Username "' + username + '" is already taken' });
}
},
{
validation: {
throwError: true,
asObject: true,
validators: [authValidator.login],
},
inputs: ['username', 'password'],
},
),
);

if (await User.findOne({ email })) {
return res.json({ error: 'Email "' + email + '" is already taken' });
}
router.post(
'/register',
createController(
async (req, res) => {
const body = res.locals.inputBody;

const newUser = new User({ username, email, name, birth: new Date(birth) });

if (password) {
newUser.hash = bcrypt.hashSync(password, 10);
}
if (body.birth) {
body.birth = new Date(body.birth);
}

await newUser.save().then((user, err) => {
bcrypt.compare(password, user.hash).then(isMatch => {
if (isMatch) {
const payload = {
id: user._id,
username: user.username
};
jwt.sign(
payload,
process.env.SECRET,
{
expiresIn: 3600
if (await User.findOne({ username: body.username })) {
throw new createError(409, 'This username aleady exists.', {
errors: {
username: `Username '${body.username}' is already taken.'`,
},
(err, token) => {
if (err) console.error(TOKEN_ERROR, err);
});
}

return res.json({
status: STATUS_OK,
newUser: user,
success: true,
token
});
}
);
} else {
errors.password = INCORRECT_PASSWORD;
return res.json(400).json(errors);
if (await User.findOne({ email: body.email })) {
throw new createError(409, 'This email aleady exists.', {
errors: {
email: `Email '${body.email}' is already taken.'`,
},
});
}
});
});
});

const newUser = new User(body);

await newUser.save();

const token = await jwt.sign(newUser);

res.status(201).json({
user: newUser,
token,
});
},
{
validation: {
throwError: true,
asObject: true,
validators: [authValidator.register],
},
inputs: ['name', 'username', ['password', 'hash'], 'email', 'birth'],
},
),
);

module.exports = router;
Loading

0 comments on commit 5e3a936

Please sign in to comment.