From bd2193c6e9a589951b4e21275d43f5a1755757f1 Mon Sep 17 00:00:00 2001 From: OmSingh Date: Mon, 5 Oct 2020 16:03:35 +0530 Subject: [PATCH] created google login --- Backend/App.js | 6 ++ Backend/config.js | 4 +- Backend/controllers/profileCtrl.js | 22 +++++++ Backend/controllers/signInCtrl.js | 10 +++- Backend/middlewares/verifyMW.js | 5 ++ Backend/package-lock.json | 37 ++++++++++++ Backend/package.json | 3 + Backend/passport.js | 11 ++++ Backend/routes/profileRouter.js | 9 +++ Backend/routes/signinRouter.js | 3 +- Frontend/package-lock.json | 9 +++ Frontend/package.json | 1 + Frontend/src/app/Main.js | 11 +--- .../app/components/atoms/GoogleLoginButton.js | 31 +++++++--- .../src/app/components/screens/LoginScreen.js | 57 ++++++++++++++++--- Frontend/src/app/config.js | 7 ++- Frontend/src/app/scripts/googleSignin.js | 2 - .../app/utils/api/controllers/profileCtrl.js | 22 +++++++ .../app/utils/api/controllers/signInCtrl.js | 13 +++++ Frontend/src/app/utils/api/endpoints.js | 13 +++++ Frontend/src/app/utils/authentication.js | 34 +++++++++++ .../src/app/utils/firebase/firebaseAuth.js | 7 +++ .../{localStorage/user.js => localStorage.js} | 2 +- 23 files changed, 284 insertions(+), 35 deletions(-) create mode 100644 Backend/controllers/profileCtrl.js create mode 100644 Backend/middlewares/verifyMW.js create mode 100644 Backend/passport.js create mode 100644 Backend/routes/profileRouter.js create mode 100644 Frontend/src/app/utils/api/controllers/profileCtrl.js create mode 100644 Frontend/src/app/utils/api/controllers/signInCtrl.js create mode 100644 Frontend/src/app/utils/api/endpoints.js create mode 100644 Frontend/src/app/utils/authentication.js create mode 100644 Frontend/src/app/utils/firebase/firebaseAuth.js rename Frontend/src/app/utils/{localStorage/user.js => localStorage.js} (97%) diff --git a/Backend/App.js b/Backend/App.js index 9ea3cbf..bf2091a 100644 --- a/Backend/App.js +++ b/Backend/App.js @@ -3,16 +3,22 @@ const app = express(); const config = require('./config'); const database = require('./database/database'); const session = require('express-session'); +const cors = require('cors'); + +require('./passport'); //Applying middlewares app.use(express.json()); app.use(session(config.session)); +app.use(cors()); //Importing rotues const signInRoute = require('./routes/signinRouter'); +const profileRoute =require('./routes/profileRouter'); //Applying routes app.use('/api/signin',signInRoute); +app.use('/api/profile',profileRoute); app.listen(config.app.local.port, ()=>{ console.log("\n\n App listening... \n\n"); diff --git a/Backend/config.js b/Backend/config.js index 5ee7631..de6b914 100644 --- a/Backend/config.js +++ b/Backend/config.js @@ -26,8 +26,8 @@ const config = { } }, gcp:{ - clientId: "541374752269-86ein6vehn2elteuea39arj5nnaok92o.apps.googleusercontent.com", - clientSecret:"iKd6K67CdlmgVEvKHSclJ9Mf" + clientId: "41880489918-ff5sebqstbkdjru2po7gmgsepqhnuio7.apps.googleusercontent.com", + clientSecret:"-1JWDbVE3ytYo5_qpXwPYHje" }, } diff --git a/Backend/controllers/profileCtrl.js b/Backend/controllers/profileCtrl.js new file mode 100644 index 0000000..3079118 --- /dev/null +++ b/Backend/controllers/profileCtrl.js @@ -0,0 +1,22 @@ +const Interviewer = require('../database/schema/interviewer'); + +const getProfile = async (req,res)=>{ + const id = req.user.id; + + try{ + const profile = await Interviewer.findOne({id:id}); + + return res.status(200).json({ + success:true, + profile:profile, + }) + }catch(err){ + console.log("Error",err); + return res.status(500).json({ + success:false, + msg:"Internal Server Error", + }) + } +} + +module.exports = {getProfile}; \ No newline at end of file diff --git a/Backend/controllers/signInCtrl.js b/Backend/controllers/signInCtrl.js index 1f916e5..9368b73 100644 --- a/Backend/controllers/signInCtrl.js +++ b/Backend/controllers/signInCtrl.js @@ -3,7 +3,7 @@ const jwt = require('jsonwebtoken'); const config = require('../config'); const Interviewer = require('../database/schema/interviewer'); -const createUser = async (req,res)=>{ +const googleSignIn= async (req,res)=>{ const idToken = req.body.idToken; const client = new OAuth2Client(config.gcp.clientId); @@ -66,4 +66,10 @@ const createUser = async (req,res)=>{ } } -module.exports = {createUser}; \ No newline at end of file +const emailSignIn = (req,res)=>{ + +} + + + +module.exports = {googleSignIn,emailSignIn}; \ No newline at end of file diff --git a/Backend/middlewares/verifyMW.js b/Backend/middlewares/verifyMW.js new file mode 100644 index 0000000..8b9978f --- /dev/null +++ b/Backend/middlewares/verifyMW.js @@ -0,0 +1,5 @@ +var passport = require('passport'); + +const user = passport.authenticate('jwt', { session: false }); + +module.exports = {user} \ No newline at end of file diff --git a/Backend/package-lock.json b/Backend/package-lock.json index 557d1e6..927dfe9 100644 --- a/Backend/package-lock.json +++ b/Backend/package-lock.json @@ -508,6 +508,15 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, "crypto-random-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", @@ -1643,11 +1652,39 @@ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, + "passport": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.1.tgz", + "integrity": "sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg==", + "requires": { + "passport-strategy": "1.x.x", + "pause": "0.0.1" + } + }, + "passport-jwt": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/passport-jwt/-/passport-jwt-4.0.0.tgz", + "integrity": "sha512-BwC0n2GP/1hMVjR4QpnvqA61TxenUMlmfNjYNgK0ZAs0HK4SOQkHcSv4L328blNTLtHq7DbmvyNJiH+bn6C5Mg==", + "requires": { + "jsonwebtoken": "^8.2.0", + "passport-strategy": "^1.0.0" + } + }, + "passport-strategy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", + "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=" + }, "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, + "pause": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", + "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" + }, "pg": { "version": "8.3.3", "resolved": "https://registry.npmjs.org/pg/-/pg-8.3.3.tgz", diff --git a/Backend/package.json b/Backend/package.json index 30ba3bd..8d25bf1 100644 --- a/Backend/package.json +++ b/Backend/package.json @@ -11,12 +11,15 @@ "license": "ISC", "dependencies": { "@material-ui/core": "^4.11.0", + "cors": "^2.8.5", "express": "^4.17.1", "express-session": "^1.17.1", "google-auth-library": "^6.1.0", "jsonwebtoken": "^8.5.1", "mongoose": "^5.10.7", "nodemon": "^2.0.4", + "passport": "^0.4.1", + "passport-jwt": "^4.0.0", "pg": "^8.3.3", "sequelize": "^6.3.5" } diff --git a/Backend/passport.js b/Backend/passport.js new file mode 100644 index 0000000..79e50eb --- /dev/null +++ b/Backend/passport.js @@ -0,0 +1,11 @@ +var passport = require('passport'); +var JWTStrategy = require('passport-jwt').Strategy + +var config = require('./config') + +passport.use(new JWTStrategy({ + jwtFromRequest: req => req.headers.token, + secretOrKey: config.jwt.TOKEN_SECRET +},(jwtPayload, done) => { + return done(null, jwtPayload) +})) diff --git a/Backend/routes/profileRouter.js b/Backend/routes/profileRouter.js new file mode 100644 index 0000000..d3936b0 --- /dev/null +++ b/Backend/routes/profileRouter.js @@ -0,0 +1,9 @@ +const express = require('express'); +const router = express.Router(); + +const profileCtrl = require('../controllers/profileCtrl') +const verifyUser = require('../middlewares/verifyMW').user; + +router.get('/interviewer/own',verifyUser,profileCtrl.getProfile); + +module.exports = router; \ No newline at end of file diff --git a/Backend/routes/signinRouter.js b/Backend/routes/signinRouter.js index bea5da8..916b91f 100644 --- a/Backend/routes/signinRouter.js +++ b/Backend/routes/signinRouter.js @@ -3,6 +3,7 @@ const router = express.Router(); const signInCtrl = require('../controllers/signInCtrl'); -router.post('/interviewer',signInCtrl.createUser); +router.post('/interviewer/google',signInCtrl.googleSignIn); +router.post('/interviewer/email',signInCtrl.emailSignIn); module.exports = router; \ No newline at end of file diff --git a/Frontend/package-lock.json b/Frontend/package-lock.json index 76ddfe4..b22f111 100644 --- a/Frontend/package-lock.json +++ b/Frontend/package-lock.json @@ -11643,6 +11643,15 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.7.tgz", "integrity": "sha512-TAv1KJFh3RhqxNvhzxj6LeT5NWklP6rDr2a0jaTfsZ5wSZWHOGeqQyejUp3xxLfPt2UpyJEcVQB/zyPcmonNFA==" }, + "react-google-login": { + "version": "5.1.21", + "resolved": "https://registry.npmjs.org/react-google-login/-/react-google-login-5.1.21.tgz", + "integrity": "sha512-z5LtNOc9FZgrkwnqpnzN/hWqG/Tg5+9gKDz0hIHx82U48TkcXvD3HjhhbAzM5OsyFGRE39GnaC4SdB3mpWGX6A==", + "requires": { + "@types/react": "*", + "prop-types": "^15.6.0" + } + }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", diff --git a/Frontend/package.json b/Frontend/package.json index e1157c4..32354f5 100644 --- a/Frontend/package.json +++ b/Frontend/package.json @@ -11,6 +11,7 @@ "firebase": "^7.22.0", "react": "^16.13.1", "react-dom": "^16.13.1", + "react-google-login": "^5.1.21", "react-router-dom": "^5.2.0", "react-scripts": "3.4.3" }, diff --git a/Frontend/src/app/Main.js b/Frontend/src/app/Main.js index 4a4146b..be8f0ba 100644 --- a/Frontend/src/app/Main.js +++ b/Frontend/src/app/Main.js @@ -2,6 +2,7 @@ import React from 'react' import {HashRouter,Switch, Route,withRouter} from 'react-router-dom' import {useEffect} from 'react' import {firebaseConfig} from './config' +import firebase from 'firebase' import LoginScreen from './components/screens/LoginScreen' @@ -24,14 +25,8 @@ function Main(props){ googleSigninScript.src = "https://apis.google.com/js/platform.js"; googleSigninScript.onload = ()=>{setScriptLoading(scriptLoading+1)}; - const firebaseScript = document.createElement('script'); - firebaseScript.src = "https://www.gstatic.com/firebasejs/7.22.0/firebase-app.js"; - firebaseScript.onload = ()=>{ - window.firebase.initializeApp(firebaseConfig); - setScriptLoading(scriptLoading+1); - }; - - document.body.append(firebaseScript); + firebase.initializeApp(firebaseConfig); + document.body.append(googleSigninScript); },[1]) diff --git a/Frontend/src/app/components/atoms/GoogleLoginButton.js b/Frontend/src/app/components/atoms/GoogleLoginButton.js index 9b66211..d182b6a 100644 --- a/Frontend/src/app/components/atoms/GoogleLoginButton.js +++ b/Frontend/src/app/components/atoms/GoogleLoginButton.js @@ -2,21 +2,34 @@ import React from 'react' import {ButtonBase,Typography} from '@material-ui/core' import GoogleLogo from '../../res/icons/google.png' +import {GoogleLogin} from 'react-google-login' + +import {googleConfig} from '../../config' function GoogleLoginButton(props){ - const onClick = props.onClick; + const onSuccess = props.onSuccess; + const onFailure = props.onFailure; return(
- -
- - - SignIn with Google - -
-
+ ( + +
+ + + SignIn with Google + +
+
+ )} + onSuccess={onSuccess} + onFailure={onFailure} + clientId={googleConfig.clientId} + cookiePolicy={'single_host_origin'} + /> +
) diff --git a/Frontend/src/app/components/screens/LoginScreen.js b/Frontend/src/app/components/screens/LoginScreen.js index 27a22c5..4303613 100644 --- a/Frontend/src/app/components/screens/LoginScreen.js +++ b/Frontend/src/app/components/screens/LoginScreen.js @@ -2,14 +2,56 @@ import React from 'react' import {Button,Dialog, DialogContent, DialogTitle,DialogActions, ButtonBase} from '@material-ui/core' import './style.css'; +import {withRouter} from 'react-router-dom' import IntervierLogin from '../molecules/InterViewerLogin'; import JoinRoomForm from '../molecules/JoinRoomForm'; import GoogleLoginButton from '../atoms/GoogleLoginButton'; -function InterviewerDialog(props){ +import {googleSignIn} from '../../utils/api/controllers/signInCtrl' +import {getOwnProfile} from '../../utils/api/controllers/profileCtrl' + +import {UserData} from '../../utils/localStorage'; + +const InterviewerDialog = withRouter((props)=>{ const isOpen = props.isOpen; const onClose = props.onClose; + + const googleLoginSuccess = (response)=>{ + var profile = response.profileObj + console.log("Login"); + googleSignIn(response).then((res)=>(res.json())) + .then((data)=>{ + console.log("login successfull"); + //Saving data in + //Getting Success. + if(data.success){ + UserData.setToken(data.jwt); + //setting email + UserData.setEmail(profile.email); + if(data.newUser){ + props.history.push('/register'); + }else{ + console.log(UserData.getToken()); + getOwnProfile().then((res)=>(res.json())) + .then((res)=>{ + if(res.success){ + UserData.setProfileData(res.profile); + props.history.push('/interviewer'); + }else{ + console.log(res.msg); + } + + }) + + } + }else{ + console.log(data.msg); + } + }).catch((err)=>{ + console.log("Error",err); + }) + } return( Sign In As An Interviewer @@ -21,7 +63,7 @@ function InterviewerDialog(props){
- {}}/> + {console.log("Error",response)}}/>
{}} > @@ -30,9 +72,6 @@ function InterviewerDialog(props){
- - -
) -} +}); -function CandidateDialog(props){ +const CandidateDialog = withRouter((props)=>{ const isOpen = props.isOpen; const onClose = props.onClose; return( @@ -61,7 +100,7 @@ function CandidateDialog(props){ ) -} +}) function LoginScreen(props){ const [interviewerDialog,setInterviewDialog] = React.useState(false); @@ -109,4 +148,4 @@ function LoginScreen(props){ ) } -export default LoginScreen; \ No newline at end of file +export default withRouter(LoginScreen); \ No newline at end of file diff --git a/Frontend/src/app/config.js b/Frontend/src/app/config.js index cc6f5bd..723e31e 100644 --- a/Frontend/src/app/config.js +++ b/Frontend/src/app/config.js @@ -10,7 +10,12 @@ const firebaseConfig = { }; const googleConfig = { - + clientId: '41880489918-ff5sebqstbkdjru2po7gmgsepqhnuio7.apps.googleusercontent.com', + clientSecret: "-1JWDbVE3ytYo5_qpXwPYHje", + apiKey:'AIzaSyDOy1JRRQfHO7TD-vbFuHqxcw4PQiXaUOc', + redirectUris:["http://localhost:3000/"], + scope: "https://www.googleapis.com/auth/calendar", + discoveryDocs: ["https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest"], } export {firebaseConfig,googleConfig}; \ No newline at end of file diff --git a/Frontend/src/app/scripts/googleSignin.js b/Frontend/src/app/scripts/googleSignin.js index 139597f..e69de29 100644 --- a/Frontend/src/app/scripts/googleSignin.js +++ b/Frontend/src/app/scripts/googleSignin.js @@ -1,2 +0,0 @@ - - diff --git a/Frontend/src/app/utils/api/controllers/profileCtrl.js b/Frontend/src/app/utils/api/controllers/profileCtrl.js new file mode 100644 index 0000000..a84bce6 --- /dev/null +++ b/Frontend/src/app/utils/api/controllers/profileCtrl.js @@ -0,0 +1,22 @@ +import {profileEndPoints} from '../endpoints' +import {UserData} from '../../localStorage' + +export const updateProfile = (data)=>{ + const requestOptions = { + method:"POST", + headers:{ "token": UserData.getToken(),'Content-Type': 'application/json'}, + body: JSON.stringify(data) + } + + return fetch(profileEndPoints.update, requestOptions); + +} + +export const getOwnProfile = ()=>{ + const requestOptions = { + method:"GET", + headers:{ "token": UserData.getToken(),'Content-Type': 'application/json'}, + } + + return fetch(profileEndPoints.getOwnProfile, requestOptions); +} \ No newline at end of file diff --git a/Frontend/src/app/utils/api/controllers/signInCtrl.js b/Frontend/src/app/utils/api/controllers/signInCtrl.js new file mode 100644 index 0000000..c2df176 --- /dev/null +++ b/Frontend/src/app/utils/api/controllers/signInCtrl.js @@ -0,0 +1,13 @@ +import {signInEndpoints} from '../endpoints' + +const googleSignIn= (response)=>{ + const requestOptions = { + method:"POST", + headers:{ 'Content-Type': 'application/json' }, + body: JSON.stringify({ idToken: response.tokenId }) + } + + return fetch(signInEndpoints.googleSignIn,requestOptions); +} + +export {googleSignIn}; \ No newline at end of file diff --git a/Frontend/src/app/utils/api/endpoints.js b/Frontend/src/app/utils/api/endpoints.js new file mode 100644 index 0000000..882b279 --- /dev/null +++ b/Frontend/src/app/utils/api/endpoints.js @@ -0,0 +1,13 @@ +const BASE_URL = "http://localhost:8000/api"; + +export const signInEndpoints = { + googleSignIn:BASE_URL+"/signin/interviewer/google", + emailSignIn:BASE_URL+"/signin/interviewer/email", +} + +export const profileEndPoints = { + getOwnProfile:BASE_URL+"/profile/interviewer/own", + getOthersProfile:BASE_URL+"/profile/interviewer/others", + updateProfile:BASE_URL+"", + +} \ No newline at end of file diff --git a/Frontend/src/app/utils/authentication.js b/Frontend/src/app/utils/authentication.js new file mode 100644 index 0000000..be1bb9b --- /dev/null +++ b/Frontend/src/app/utils/authentication.js @@ -0,0 +1,34 @@ +const googleLogin = (response)=>{ + var profile = response.profileObj + signInWithGoogle(response).then((res)=>(res.json())) + .then((data)=>{ + console.log("login successfull"); + //Saving data in + //Getting Success. + if(data.success){ + UserData.setIdToken(data.authToken); + //setting email + UserData.setEmail(profile.email); + if(data.newUser){ + this.props.history.push('/register'); + }else{ + getProfile().then((res)=>(res.json())) + .then((res)=>{ + if(res.success){ + UserData.setUserData(res.profile); + this.props.history.push('/homepage'); + }else{ + console.log(res.msg); + } + + }) + + } + + }else{ + console.log(data.msg); + } + }) +} + +export {googleLogin} \ No newline at end of file diff --git a/Frontend/src/app/utils/firebase/firebaseAuth.js b/Frontend/src/app/utils/firebase/firebaseAuth.js new file mode 100644 index 0000000..92f3575 --- /dev/null +++ b/Frontend/src/app/utils/firebase/firebaseAuth.js @@ -0,0 +1,7 @@ +import firebase from 'firebase'; + +const googleSignIn = (response)=>{ + +} + +export {googleSignIn} \ No newline at end of file diff --git a/Frontend/src/app/utils/localStorage/user.js b/Frontend/src/app/utils/localStorage.js similarity index 97% rename from Frontend/src/app/utils/localStorage/user.js rename to Frontend/src/app/utils/localStorage.js index c821b5f..ddefabe 100644 --- a/Frontend/src/app/utils/localStorage/user.js +++ b/Frontend/src/app/utils/localStorage.js @@ -1,4 +1,4 @@ -export default UserData = function(){ +export const UserData = function(){ var data = { userExists:false, tokenExists:false,