Skip to content

Commit

Permalink
Merge branch 'dev' of github.com:hngprojects/hng_boilerplate_expressj…
Browse files Browse the repository at this point in the history
…s into chore/fixes-on-change-password

merg#
  • Loading branch information
incredible-phoenix246 committed Jul 29, 2024
2 parents 0aafecc + 4c53a9d commit f40c3ae
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 79 deletions.
43 changes: 27 additions & 16 deletions src/config/google.passport.config.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
import passport from "passport";
import { Strategy as GoogleStrategy, Profile, VerifyCallback } from "passport-google-oauth2";
import {
Strategy as GoogleStrategy,
Profile,
VerifyCallback,
} from "passport-google-oauth2";
import config from ".";

passport.use(new GoogleStrategy({
clientID: config.GOOGLE_CLIENT_ID,
clientSecret: config.GOOGLE_CLIENT_SECRET,
callbackURL: config.GOOGLE_AUTH_CALLBACK_URL
},
async (_accessToken: string, _refreshToken: string, profile: Profile, done: VerifyCallback) => {
try {
return done(null, profile);
} catch (error) {
return done(error);
}
}
));
passport.use(
new GoogleStrategy(
{
clientID: config.GOOGLE_CLIENT_ID,
clientSecret: config.GOOGLE_CLIENT_SECRET,
callbackURL: config.GOOGLE_AUTH_CALLBACK_URL,
},
async (
_accessToken: string,
_refreshToken: string,
profile: Profile,
done: VerifyCallback,
) => {
try {
return done(null, profile);
} catch (error) {
return done(error);
}
},
),
);


export default passport;
export default passport;
39 changes: 23 additions & 16 deletions src/controllers/GoogleAuthController.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import passport from "../config/google.passport.config";
import {ServerError, Unauthorized } from "../middleware";
import { ServerError, Unauthorized } from "../middleware";
import { Request, Response, NextFunction } from "express";
import { GoogleAuthService } from "../services/google.auth.service";


/**
* @swagger
* api/v1/auth/google:
Expand All @@ -25,8 +24,9 @@ import { GoogleAuthService } from "../services/google.auth.service";
* description: Internal Server Error - An error occurred during the initiation of the authentication process
*/

export const initiateGoogleAuthRequest = passport.authenticate('google', { scope: [ 'openid', 'email', 'profile' ] })

export const initiateGoogleAuthRequest = passport.authenticate("google", {
scope: ["openid", "email", "profile"],
});

/**
* @swagger
Expand Down Expand Up @@ -90,22 +90,29 @@ export const initiateGoogleAuthRequest = passport.authenticate('google', { scope
* 500:
* description: Internal Server Error - An error occurred during the authentication process
*/
export const googleAuthCallback = (req: Request, res: Response, next: NextFunction) => {
const authenticate = passport.authenticate('google', async (error, user, info) => {
const googleAuthService = new GoogleAuthService();
export const googleAuthCallback = (
req: Request,
res: Response,
next: NextFunction,
) => {
const authenticate = passport.authenticate(
"google",
async (error, user, info) => {
const googleAuthService = new GoogleAuthService();
try {
if (error) {
throw new ServerError("Authentication error");
if (error) {
throw new ServerError("Authentication error");
}
if (!user) {
throw new Unauthorized("Authentication failed!")
throw new Unauthorized("Authentication failed!");
}
const isDbUser = await googleAuthService.getUserByGoogleId(user.id);
const dbUser = await googleAuthService.handleGoogleAuth(user, isDbUser)
const dbUser = await googleAuthService.handleGoogleAuth(user, isDbUser);
res.status(200).json(dbUser);
} catch(error) {
next(error)
} catch (error) {
next(error);
}
});
authenticate(req, res, next)
}
},
);
authenticate(req, res, next);
};
2 changes: 1 addition & 1 deletion src/controllers/exportController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Request, Response } from "express";
import ExportService from "../services/export.services";
/**
* @swagger
* /api/v1/export-data:
* /api/v1/organisation/members/export:
* get:
* summary: Export signed-in user information
* tags: [Export user data by csv or pdf format]
Expand Down
6 changes: 3 additions & 3 deletions src/data-source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ const AppDataSource = new DataSource({
migrationsTableName: "migrations",
// ssl: true,
// extra: {
// ssl: {
// rejectUnauthorized: false,
// },
// ssl: {
// rejectUnauthorized: false,
// },
// },
});

Expand Down
1 change: 1 addition & 0 deletions src/routes/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ authRoute.get("/auth/test-google-auth", (req, res) => {

authRoute.get("/auth/social/google?provider=google", initiateGoogleAuthRequest);


authRoute.get("/auth/google/callback", googleAuthCallback);

authRoute.patch("/auth/change-password", authMiddleware, changePassword);
Expand Down
9 changes: 8 additions & 1 deletion src/routes/export.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import { Router } from "express";
import exportController from "../controllers/exportController";
import { authMiddleware } from "../middleware";
import { checkPermissions } from "../middleware/checkUserRole";
import { UserRole } from "../enums/userRoles";

const exportRouter = Router();

exportRouter.get("/export-data", authMiddleware, exportController.exportData);
exportRouter.get(
"/organisation/members/export",
authMiddleware,
checkPermissions([UserRole.SUPER_ADMIN, UserRole.USER]),
exportController.exportData,
);

export { exportRouter };
85 changes: 43 additions & 42 deletions src/services/google.auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ interface IGoogleAuthService {
getUserByGoogleId(google_id: string): Promise<User | null>;
handleGoogleAuth(
payload: Profile,
authUser: User | null
authUser: User | null,
): Promise<{
user: Partial<User>;
access_token: string;
Expand All @@ -42,7 +42,7 @@ export class GoogleAuthService implements IGoogleAuthService {
user = new User();
profile = new UserProfile();

const [first_name = '', last_name = ''] = name.split(" ");
const [first_name = "", last_name = ""] = name.split(" ");

user.name = `${first_name} ${last_name}`;
user.email = email;
Expand Down Expand Up @@ -102,59 +102,60 @@ export class GoogleAuthService implements IGoogleAuthService {
}
}

public async handleGoogleAuth(payload: Profile, authUser: User | null): Promise<{
status: string,
message: string,
public async handleGoogleAuth(
payload: Profile,
authUser: User | null,
): Promise<{
status: string;
message: string;
user: Partial<User>;
access_token: string;
}> {
try {

let user: User;
let profile: UserProfile;
if (!authUser) {
}> {
try {
let user: User;
let profile: UserProfile;
if (!authUser) {
user = new User();
profile = new UserProfile()
}
else {
profile = new UserProfile();
} else {
user = authUser;
profile = user.profile;
}
}

user.name = payload.displayName;
user.email = payload.email;
user.google_id = payload.id;
user.otp = 1234;
user.isverified = true;
user.otp_expires_at = new Date(Date.now());
profile.phone_number = "";
profile.first_name = payload.given_name;
profile.last_name = payload.family_name;
profile.avatarUrl = payload.picture;
user.profile = profile
user.name = payload.displayName;
user.email = payload.email;
user.google_id = payload.id;
user.otp = 1234;
user.isverified = true;
user.otp_expires_at = new Date(Date.now());
profile.phone_number = "";
profile.first_name = payload.given_name;
profile.last_name = payload.family_name;
profile.avatarUrl = payload.picture;
user.profile = profile;

const createdUser = await AppDataSource.manager.save(user);
const access_token = jwt.sign(
{ userId: createdUser.id },
config.TOKEN_SECRET,
{
expiresIn: "1d",
}
);
const createdUser = await AppDataSource.manager.save(user);
const access_token = jwt.sign(
{ userId: createdUser.id },
config.TOKEN_SECRET,
{
expiresIn: "1d",
},
);

const { password: _, ...rest } = createdUser;
const { password: _, ...rest } = createdUser;

return {
return {
status: "success",
message: "User successfully authenticated",
access_token,
user: rest,
};
} catch (error) {
if (error instanceof HttpError) {
throw error;
};
} catch (error) {
if (error instanceof HttpError) {
throw error;
}
throw new HttpError(error.status || 500, error.message || error);
}
throw new HttpError(error.status || 500, error.message || error);
}
}
}

0 comments on commit f40c3ae

Please sign in to comment.