Skip to content

Commit

Permalink
feat: implemented Google oauth
Browse files Browse the repository at this point in the history
  • Loading branch information
omodauda committed Jun 20, 2020
1 parent 0d0e88b commit 70efa7e
Show file tree
Hide file tree
Showing 8 changed files with 578 additions and 1 deletion.
58 changes: 58 additions & 0 deletions Controllers/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
require('dotenv').config();
const JWT = require('jsonwebtoken');
const User = require('../Models/authModel');


signToken = user => {
return JWT.sign({
iss: 'CodeWorkr',
sub: user.id,
iat: new Date().getTime(), // current time
exp: new Date().setDate(new Date().getDate() + 1) // current time + 1 day ahead
}, process.env.JWT_SECRET);
}

module.exports = {
signUp: async (req, res, next) => {
const { email, password } = req.body;

// Check if there is a user with the same email
const foundUser = await User.findOne({ "local.email": email });
const existingUser = await User.findOne({"google.email": email});
if (foundUser || existingUser) {
return res.status(403).json({ error: 'Email is already in use'});
}


// Create a new user
const newUser = new User({
method: 'local',
local: {
email: email,
password: password
}
});

await newUser.save();

// Generate the token
const token = signToken(newUser);
// Respond with token
// res.status(200).json({ token });
return res.status(200).json({status: "success", message: `user with email ${email} successfully registered!`});
},

signIn: async (req, res, next) => {
// Generate token
const token = signToken(req.user);
res.status(200).json({ token });
},

googleOAuth: async (req, res, next) => {
// Generate token
console.log('got here');
const token = signToken(req.user);
res.status(200).json({ token });
},

}
23 changes: 23 additions & 0 deletions Helpers/routeHelpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const Joi = require('joi');

module.exports = {
validateBody: (schema) => {
return (req, res, next) => {
const result = Joi.validate(req.body, schema);
if (result.error) {
return res.status(400).json(result.error);
}

if (!req.value) { req.value = {}; }
req.value['body'] = result.value;
next();
}
},

schemas: {
authSchema: Joi.object().keys({
email: Joi.string().email().required(),
password: Joi.string().required()
})
}
}
73 changes: 73 additions & 0 deletions Models/authModel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const Schema = mongoose.Schema;

// Create a schema
const userSchema = new Schema({
method: {
type: String,
enum: ['local', 'google', 'facebook'],
required: true
},
local: {
email: {
type: String,
lowercase: true
},
password: {
type: String
}
},
google: {
id: {
type: String
},
email: {
type: String,
lowercase: true
}
},
facebook: {
id: {
type: String
},
email: {
type: String,
lowercase: true
}
}
});

userSchema.pre('save', async function(next) {
try {
console.log('entered');
if (this.method !== 'local') {
next();
}

// Generate a salt
const salt = await bcrypt.genSalt(10);
// Generate a password hash (salt + hash)
const passwordHash = await bcrypt.hash(this.local.password, salt);
// Re-assign hashed version over original, plain text password
this.local.password = passwordHash;
console.log('exited');
next();
} catch(error) {
next(error);
}
});

userSchema.methods.isValidPassword = async function(newPassword) {
try {
return await bcrypt.compare(newPassword, this.local.password);
} catch(error) {
throw new Error(error);
}
}

// Create a model
const User = mongoose.model('user', userSchema);

// Export the model
module.exports = User;
21 changes: 21 additions & 0 deletions Routes/authRoute.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const express = require('express');
const router = require('express-promise-router')();
const passport = require('passport');
const passportConf = require('../passport');

const { validateBody, schemas } = require('../Helpers/routeHelpers');
const UsersController = require('../Controllers/auth');
const passportSignIn = passport.authenticate('local', { session: false });
const passportJWT = passport.authenticate('jwt', { session: false });

router.route('/signup')
.post(validateBody(schemas.authSchema), UsersController.signUp);

router.route('/signin')
.post(validateBody(schemas.authSchema), passportSignIn, UsersController.signIn);

router.route('/oauth/google')
.post(passport.authenticate('googleToken', { session: false }), UsersController.googleOAuth);


module.exports = router;
9 changes: 9 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,17 @@ const app = express();

app.use(bodyParser.json());

const authRoute = require('../mobileforce-iCook-backend/Routes/authRoute');


//Routes

//home route
app.get('/api/v1', (req, res) => {
res.status(200).json({status: "success", message: "Welcome to iCook app"});
});
//auth route
app.use('/api/v1', authRoute);

//connect to mongoDB Atlas
mongoose
Expand Down
Loading

0 comments on commit 70efa7e

Please sign in to comment.