Skip to content

Commit

Permalink
Merge branch 'development' of https://github.com/segunolalive/helloBooks
Browse files Browse the repository at this point in the history
 into feature/google-signin
  • Loading branch information
segunolalive committed Nov 14, 2017
2 parents 1c3b03a + 3c92451 commit 6a8153c
Show file tree
Hide file tree
Showing 3 changed files with 247 additions and 21 deletions.
8 changes: 4 additions & 4 deletions client/components/auth/Login.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class Login extends Component {
};
this.handleLogin = this.handleLogin.bind(this);
this.handleChange = this.handleChange.bind(this);
this.responseGoogle = this.responseGoogle.bind(this);
this.handleGoogleLogin = this.handleGoogleLogin.bind(this);
}

/**
Expand All @@ -39,7 +39,7 @@ class Login extends Component {
* @memberof Login
* @returns {Undefined} redirects to dashboard
*/
responseGoogle(response) {
handleGoogleLogin(response) {
const googleProfile = response.profileObj;
this.props.login(googleProfile);
}
Expand Down Expand Up @@ -136,8 +136,8 @@ class Login extends Component {
<div className="input-field">
<GoogleLogin
clientId={GOOGLE_CLIENT_ID}
onSuccess={this.responseGoogle}
onFailure={this.responseGoogle}
onSuccess={this.handleGoogleLogin}
onFailure={this.handleGoogleLogin}
className="btn red darken-4"
style={{ width: '100%' }}
>
Expand Down
17 changes: 0 additions & 17 deletions client/components/auth/SignUp.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,6 @@ class SignUp extends Component {
this.handleGoogleSignUp = this.handleGoogleSignUp.bind(this);
}

/**
* handler for google sign in
* @param {any} response
* @memberof Login
* @returns {Undefined} redirects to dashboard
*/
responseGoogle(response) {
const googleProfile = response.getBasicProfile();
const email = googleProfile.getEmail();
const id = googleProfile.getId();
const username = email.slice(0, email.indexOf('@'));
const firstName = googleProfile.getGivenName();
const lastName = googleProfile.getFamilyName();
console.log(username, firstName, lastName, email);
}


/**
* sign up handler
* @param {any} event
Expand Down
243 changes: 243 additions & 0 deletions server/controllers/users.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
import bcrypt from 'bcrypt';
import dotenv from 'dotenv';

import { User, Book } from '../models';
import { getJWT } from '../helpers/helpers';
import { transporter, mailOptions } from '../config/mail';

dotenv.config();


export default {
/**
* Create new user account.
* It sends a an object containing a success boolean
* and a json web token or error
* @public
* @method
* @param {object} req - express http request object
* @param {object} res - express http response object
* @return {Object} - returns an http response object
*/

createUser(req, res) {
const username = req.body.username;
const email = req.body.email;
return User.find({
where: { $or: [{ username }, { email }] }
}).then((existingUser) => {
if (existingUser && existingUser.username === username) {
return res.status(409).json({
message: 'username is taken',
});
}
if (existingUser && existingUser.email === email) {
return res.status(409).json({
message: 'email is associated with an account',
});
}
User.create(req.body)
.then((user) => {
const {
id,
isAdmin,
membershipType,
} = user;
const jwtOptions = { id, email, username, isAdmin, membershipType };
const token = getJWT(jwtOptions);
const { firstName, lastName } = user;
return res.status(201).json({
token,
id,
firstName,
lastName,
isAdmin,
message: `Welcome ${firstName}. This is your dashboard`,
});
})
.catch(error => res.status(400).send({
error
}));
})
.catch(error => res.status(500).send({
error
}));
},

/**
* Edit user Information
* @public
* @method
* @param {object} req - express http request object
* @param {object} res - express http response object
* @return {Object} - returns an http response object
*/
updateUserInfo(req, res) {
const updateData = req.body;
updateData.passwordResetToken = null;
return User.findById(req.user.id)
.then((user) => {
user.update(updateData, { returning: true, plain: true })
.then(() => {
const {
id,
email,
username,
isAdmin,
membershipType,
} = user;
const jwtOptions = { id, email, username, isAdmin, membershipType };
const token = getJWT(jwtOptions);
const { firstName, lastName } = user;
return res.status(200).json({
token,
id,
firstName,
lastName,
isAdmin,
message: 'Your information was successfully updated',
});
}, (error) => {
res.status(500).send({
error,
});
});
})
.catch(error => res.status(500).send({
error,
}));
},

/**
* Get user data on sign in.
* It sends a an object containing a success boolean
* and a json web token or error
* @public
* @method
* @param {object} req - express http request object
* @param {object} res - express http response object
* @return {Object} - returns an http response object
*/

getUser(req, res) {
const username = req.body.username;
const password = req.body.password;
return User.findOne({ where: { username } }).then((user) => {
if (!user) {
return res.status(403).send({
message: 'user does not exist',
});
}
bcrypt.compare(password, user.password).then((result) => {
if (!result) {
return res.status(403).send({
message: 'wrong username and password combination',
});
}
const {
id,
email,
isAdmin,
membershipType,
} = user;
const jwtOptions = { id, email, username, isAdmin, membershipType };
const token = getJWT(jwtOptions);
const { firstName, lastName } = user;
return res.status(200).json({
token,
id,
firstName,
lastName,
isAdmin,
message: `Welcome back ${firstName}`,
});
}).catch(error => res.status(500).send({
error,
}));
}).catch(error => res.status(400).send({
error,
}));
},

/**
* Get list of books borrowed by specific user
* It sends a an object containing a success boolean
* and a data key, an array of borrowed books or an error
* Response can be filtered by returned status
* @public
* @method
* @param {object} req - express http request object
* @param {object} res - express http response object
* @return {Object} - returns an http rresponse object
*/
getBorrowedBooks(req, res) {
const id = req.params.id;
User.findOne({
where: { id },
include: [{ model: Book }]
}).then((user) => {
let books;
if (req.query && req.query.returned === 'false') {
books = user.Books.filter(
book => book.BorrowedBook.returned === false
);
} else if (req.query && req.query.returned === 'true') {
books = user.Books.filter(
book => book.BorrowedBook.returned === true
);
} else {
books = user.Books;
}
return res.status(200).send({
books
});
})
.catch(error => res.status(500).send({
message: 'An error occured while fetching borrowing history',
error,
}));
},

passwordResetMail(req, res) {
return User.findOne({
where: { email: req.body.email },
attributes: ['id', 'email'],
plain: true,
})
.then((user) => {
if (!user) {
return res.status(404).send({
message: 'Email does not match any account in our records',
});
}
const BASE_URL = process.env.NODE_ENV === 'development' ?
'http://localhost:8080' :
'https://segunolalive-hellobooks.com';
const token = getJWT({ id: user.id }, '1h');
user.passwordResetToken = token;
user.save();
const to = user.email;
const bcc = null;
const subject = 'no-reply: Password reset link';
const html = `<h3>Use this link to reset your password.</h3>
${BASE_URL}/reset-password?token=${token}}
<p>This link is valid only for an hour</p>`;
transporter.sendMail(mailOptions(to, bcc, subject, html),
(err) => {
if (err) {
return res.status(500).send({
message: 'An error occured while sending you a link. Try again',
});
}
return res.status(200).send({
message: 'An password reset link has been sent to your email',
});
});
})
.catch(() => (
res.status(500).send({
message: 'An error occured while sending you a link. Try again',
})
));
}
};

0 comments on commit 6a8153c

Please sign in to comment.