-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'ft-login-via-google-187584916' of https://github.com/at…
…lp-rwanda/e-commerce-ninjas-bn into ft-login-via-google-187584916
- Loading branch information
Showing
10 changed files
with
2,232 additions
and
1,824 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,23 @@ | ||
/* eslint-disable no-shadow */ | ||
/* eslint-disable @typescript-eslint/no-unused-vars */ | ||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
import { Request, Response } from "express"; | ||
import chai, { expect } from "chai"; | ||
import chaiHttp from "chai-http"; | ||
import sinon from "sinon"; | ||
import httpStatus from "http-status"; | ||
import app from "../../.."; | ||
import { isUserExist } from "../../../middlewares/validation"; | ||
import authRepositories from "../repository/authRepositories"; | ||
import Users from "../../../databases/models/users"; | ||
import Session from "../../../databases/models/session"; | ||
import { sendVerificationEmail, transporter } from "../../../services/sendEmail"; | ||
|
||
import passport, { PassportStatic } from "passport"; | ||
import { Strategy as GoogleStrategy } from "passport-google-oauth2"; | ||
import session from "express-session"; | ||
import dotenv from "dotenv"; | ||
import googleAuth from "../../../services/googleAuth"; | ||
import { generateToken } from "../../../helpers"; | ||
import app from "../../../index"; | ||
|
||
chai.use(chaiHttp); | ||
const router = () => chai.request(app); | ||
|
@@ -20,11 +27,12 @@ let verifyToken: string | null = null; | |
|
||
describe("Authentication Test Cases", () => { | ||
|
||
afterEach(async () => { | ||
afterEach(async (done) => { | ||
const tokenRecord = await Session.findOne({ where: { userId } }); | ||
if (tokenRecord) { | ||
verifyToken = tokenRecord.dataValues.token; | ||
} | ||
done(); | ||
}); | ||
|
||
it("should register a new user", (done) => { | ||
|
@@ -202,7 +210,7 @@ describe("isUserExist Middleware", () => { | |
expect(res).to.have.status(httpStatus.BAD_REQUEST); | ||
expect(res.body).to.be.an("object"); | ||
expect(res.body).to.have.property("status", httpStatus.BAD_REQUEST); | ||
expect(res.body).to.have.property("message", "Account already exists. Please verify your account"); | ||
expect(res.body).to.have.property("message", "Account already exists."); | ||
done(err); | ||
}); | ||
}); | ||
|
@@ -392,4 +400,52 @@ describe("sendVerificationEmail", () => { | |
} | ||
}); | ||
|
||
}); | ||
|
||
|
||
describe("Google Authentication", () => { | ||
describe("GET /api/auth/auth/google", () => { | ||
it("should redirect to Google login page", async () => { | ||
|
||
sinon.stub(passport, "authenticate").returns((req: Request, res: Response) => { | ||
|
||
res.redirect("https://accounts.google.com/o/oauth2/v2/auth"); | ||
}); | ||
|
||
|
||
const res = await chai.request(app).get("/api/auth/auth/google"); | ||
|
||
expect(res).to.redirect; | ||
expect(res).to.redirectTo("https://accounts.google.com/o/oauth2/v2/auth"); | ||
|
||
|
||
(passport.authenticate as sinon.SinonStub).restore(); | ||
}); | ||
}); | ||
}); | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
describe("Serialize and Deserialize User", () => { | ||
it("should serialize user", () => { | ||
const user = { id: "user-id", email: "[email protected]" }; | ||
passport.serializeUser((user, done) => { | ||
expect(user).to.deep.equal(user); | ||
done(null, user); | ||
}); | ||
}); | ||
|
||
it("should deserialize user", () => { | ||
const user = { id: "user-id", email: "[email protected]" }; | ||
passport.deserializeUser((user, done) => { | ||
expect(user).to.deep.equal(user); | ||
done(null, user); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,25 @@ | ||
/* eslint-disable @typescript-eslint/no-unused-vars */ | ||
/* eslint-disable @typescript-eslint/no-unused-vars */ | ||
import { Router } from "express"; | ||
import googleAuth from "../services/googleAuth"; | ||
import authControllers from "../modules/auth/controller/authControllers"; | ||
import { validation, isUserExist, isAccountVerified, verifyUserCredentials } from "../middlewares/validation"; | ||
import { emailSchema, credentialSchema } from "../modules/auth/validation/authValidations"; | ||
import passport from "passport"; | ||
const router: Router = Router(); | ||
|
||
router.use(passport.initialize()); | ||
router.use(googleAuth.SESSION) | ||
|
||
|
||
|
||
const router: Router = Router(); | ||
|
||
router.post("/register", validation(credentialSchema), isUserExist, authControllers.registerUser); | ||
router.get("/verify-email/:token", isAccountVerified, authControllers.verifyEmail); | ||
router.post("/send-verify-email", validation(emailSchema), isAccountVerified, authControllers.sendVerifyEmail); | ||
router.post("/login", validation(credentialSchema), verifyUserCredentials, authControllers.loginUser); | ||
router.get("/auth/google", googleAuth.googleVerify); | ||
router.get("/auth/google/callback", googleAuth.googlecallback, googleAuth.authenticated,authControllers.signInUser); | ||
|
||
|
||
export default router; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/* eslint-disable @typescript-eslint/no-namespace */ | ||
/* eslint-disable no-shadow */ | ||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
import { Request, Response, NextFunction } from "express"; | ||
import passport from "passport"; | ||
import session from "express-session"; | ||
import { Strategy as GoogleStrategy, VerifyCallback } from "passport-google-oauth2"; | ||
import dotenv from "dotenv"; | ||
import authRepositories from "../modules/auth/repository/authRepositories"; | ||
import { generateToken } from "../helpers"; | ||
import { userInfo } from "../types"; | ||
|
||
dotenv.config(); | ||
|
||
declare global { | ||
namespace Express { | ||
interface Request { | ||
user?: any; | ||
} | ||
} | ||
} | ||
const GOOGLE_CLIENT_ID = process.env.GOOGLE_CLIENT_ID as string; | ||
const GOOGLE_CLIENT_SECRET = process.env.GOOGLE_CLIENT_SECRET as string; | ||
|
||
passport.use( | ||
new GoogleStrategy( | ||
{ | ||
clientID: GOOGLE_CLIENT_ID, | ||
clientSecret: GOOGLE_CLIENT_SECRET, | ||
// eslint-disable-next-line quotes | ||
|
||
callbackURL: `${process.env.SERVER_URL_PRO}/api/auth/auth/google/callback`, | ||
|
||
passReqToCallback: true | ||
}, | ||
function ( | ||
request: Request, | ||
accessToken: string, | ||
refreshToken: string, | ||
profile: any, | ||
done: VerifyCallback | ||
) { | ||
const userId = profile.id; | ||
const email = profile.emails?.[0].value || null; | ||
const firstName = profile.name?.givenName || null; | ||
const lastName = profile.name?.familyName || null; | ||
const picture = profile.photos?.[0].value || null; | ||
const accToken = accessToken; | ||
const user = { | ||
userId, | ||
email, | ||
firstName, | ||
lastName, | ||
picture, | ||
accToken | ||
}; | ||
return done(null, user); | ||
} | ||
) | ||
); | ||
|
||
passport.serializeUser((user, done) => { | ||
done(null, user); | ||
}); | ||
|
||
passport.deserializeUser((user, done) => { | ||
done(null, user); | ||
}); | ||
|
||
const googleVerify = passport.authenticate("google", { | ||
scope: ["profile", "email"] | ||
}); | ||
|
||
const googlecallback = passport.authenticate("google", { | ||
failureRedirect: "/" | ||
}); | ||
|
||
const SESSION = session({ | ||
secret: process.env.Session_secret, | ||
resave: false, | ||
saveUninitialized: true | ||
}); | ||
|
||
const authenticated = async (req: Request,res: Response,next: NextFunction) => { | ||
if ((req as any).isAuthenticated()) { | ||
const { email } = req.user as userInfo; | ||
const register = await authRepositories.findUserByAttributes("email", email); | ||
if (register) { | ||
const token = generateToken(register.id); | ||
const sessions = { userId: register.id, device: req.headers["user-device"], token: token, otp: null }; | ||
await authRepositories.createSession(sessions); | ||
return res.status(200).json({ status: 200, token: token }); | ||
} else { | ||
next(); | ||
} | ||
} else { | ||
return res.json({ Error: "Something Went Wrong" }); | ||
} | ||
}; | ||
|
||
export default { | ||
passport, | ||
googleVerify, | ||
googlecallback, | ||
SESSION, | ||
authenticated | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters