Skip to content

Commit

Permalink
fix(google-auth): resolve API redirect issue on same port during goog…
Browse files Browse the repository at this point in the history
…le authentication

- ensure correct redirect to client URL
- send appropriate response to client
  • Loading branch information
aimedivin committed Jun 24, 2024
1 parent 1077386 commit 3291418
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 21 deletions.
4 changes: 2 additions & 2 deletions src/entities/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ export interface UserInterface {
phoneNumber: string;
photoUrl?: string;
verified?: boolean;
twoFactorEnabled?: boolean;
status?: 'active' | 'suspended';
userType: 'Admin' | 'Buyer' | 'Vendor';
role?: string;
twoFactorEnabled?: boolean;
twoFactorCode?: string;
twoFactorCodeExpiresAt?: Date;
createdAt?: Date;
Expand Down Expand Up @@ -119,7 +119,7 @@ export class User {
feedbacks!: Feedback[];

@BeforeInsert()
setRole (): void {
setRole(): void {
this.role = this.userType === 'Vendor' ? roles.vendor : roles.buyer;
}
}
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ app.use(passport.initialize());
app.use(passport.session());
app.use(express.json());
app.use(cookieParser());
app.use(cors({ origin: '*' }));
app.use(cors({ origin: process.env.CLIENT_URL, credentials: true }));
app.use(router);
addDocumentation(app);
app.all('*', (req: Request, res: Response, next) => {
Expand Down
2 changes: 1 addition & 1 deletion src/routes/ProductRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
createOrder,
getOrders, getOrder,
updateOrder,
getOrdersHistory,Payment,
getOrdersHistory, Payment,
getSingleVendorOrder,
getVendorOrders,
updateVendorOrder,
Expand Down
49 changes: 38 additions & 11 deletions src/routes/UserRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ import { hasRole } from '../middlewares/roleCheck';
import { isTokenValide } from '../middlewares/isValid';
import passport from 'passport';
import '../utils/auth';
import { start2FAProcess } from '../services/userServices/userStartTwoFactorAuthProcess';
import { otpTemplate } from '../helper/emailTemplates';
import { sendOTPEmail } from '../services/userServices/userSendOTPEmail';
import { sendOTPSMS } from '../services/userServices/userSendOTPMessage';
import { authMiddleware } from '../middlewares/verifyToken';
const router = Router();

Expand All @@ -41,29 +45,52 @@ router.get('/google-auth', passport.authenticate('google', { scope: ['profile',
router.get(
'/auth/google/callback',
passport.authenticate('google', {
successRedirect: '/user/login/success',
failureRedirect: '/user/login/failed',
successRedirect: `${process.env.CLIENT_URL}/login/google-auth`,
failureRedirect: `${process.env.CLIENT_URL}/login/google-auth`,
})
);
router.get('/login/success', async (req, res) => {
const user = req.user as UserInterface;

if (!user) {
responseError(res, 404, 'user not found');
return;
}

if (user.status === 'suspended') {
return res.status(400).json({ status: 'error', message: 'Your account has been suspended' });
}
const payload = {
id: user?.id,
email: user?.email,
role: user?.role,
};
const token = jwt.sign(payload, process.env.JWT_SECRET as string, { expiresIn: '24h' });
res.status(200).json({

if (!user.twoFactorEnabled) {
const payload = {
id: user?.id,
firstName: user.firstName,
lastName: user.lastName,
email: user?.email,
role: user?.role,
};
const token = jwt.sign(payload, process.env.JWT_SECRET as string, { expiresIn: '24h' });
return res.status(200).json({
status: 'success',
data: {
token: token,
message: 'Login success',
},
});
}
const otpCode = await start2FAProcess(user.email);
const OTPEmailcontent = otpTemplate(user.firstName, otpCode.toString());
await sendOTPEmail('Login OTP Code', user.email, OTPEmailcontent);
await sendOTPSMS(user.phoneNumber, otpCode.toString());
return res.status(200).json({
status: 'success',
data: {
token: token,
message: 'Login success',
email: user.email,
message: 'Please provide the OTP sent to your email or phone',
},
});
});

router.get('/login/failed', async (req, res) => {
res.status(401).json({
status: false,
Expand Down
5 changes: 4 additions & 1 deletion src/services/userServices/userLoginService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@ export const userLoginService = async (req: Request, res: Response) => {
const token = jwt.sign(
{
id: user.id,
firstName: user.firstName,
lastName: user.lastName,
email: user.email,
userType: user.userType,
role: user.role,
},
process.env.JWT_SECRET as string,
{ expiresIn: '24h' }
Expand Down Expand Up @@ -71,6 +73,7 @@ export const userLoginService = async (req: Request, res: Response) => {
return res.status(200).json({
status: 'success',
data: {
email: user.email,
message: 'Please provide the OTP sent to your email or phone',
},
});
Expand Down
3 changes: 1 addition & 2 deletions src/services/userServices/userProfileUpdateServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import { Request, Response } from 'express';
import { responseError, responseSuccess } from '../../utils/response.utils';
import { User, UserInterface } from '../../entities/User';
import { getRepository } from 'typeorm';
import { userProfileUpdate } from '../../controllers/authController';

import { userProfileUpdate } from '../../controllers/authController'

export const userProfileUpdateServices = async (req: Request, res: Response) => {
try {
Expand Down
4 changes: 3 additions & 1 deletion src/services/userServices/userValidateOTP.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ export const userValidateOTP = async (req: Request, res: Response) => {
const token = jwt.sign(
{
id: user?.id,
firstName: user?.firstName,
lastName: user?.lastName,
email: user?.email,
userType: user?.userType,
role: user?.role,
},
process.env.JWT_SECRET as string,
{ expiresIn: '24h' }
Expand Down
5 changes: 3 additions & 2 deletions src/utils/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import { User } from '../entities/User';
import { getRepository } from 'typeorm';
import bcrypt from 'bcrypt';
import '../utils/auth';
import { v4 as uuid } from 'uuid';
passport.use(
new Strategy(
{
clientID: process.env.GOOGLE_CLIENT_ID as string,
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
callbackURL: 'http://localhost:6890/user/auth/google/callback/',
callbackURL: `http://localhost:${process.env.PORT || 8000}/user/auth/google/callback/`,
scope: ['email', 'profile'],
},
async (accessToken: any, refreshToken: any, profile: any, cb: any) => {
Expand All @@ -27,7 +28,7 @@ passport.use(
return await cb(null, existingUser);
}
const saltRounds = 10;
const hashedPassword = await bcrypt.hash('password', saltRounds);
const hashedPassword = await bcrypt.hash(uuid(), saltRounds);
const newUser = new User();
newUser.firstName = givenName;
newUser.lastName = family_name ?? familyName ?? 'undefined';
Expand Down

0 comments on commit 3291418

Please sign in to comment.