Skip to content

Commit

Permalink
Merge pull request #386 from masterchief-Dave/feature/api-auth-magic-…
Browse files Browse the repository at this point in the history
…link

feat: add auth magic link
  • Loading branch information
AdeGneus authored Jul 31, 2024
2 parents c9cd0b9 + 31999b9 commit 9257cfb
Show file tree
Hide file tree
Showing 29 changed files with 866 additions and 224 deletions.
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ DB_PASSWORD=,
DB_PORT=,
DB_NAME=,
TOKEN_SECRET=
TOKEN_EXPIRY=
SMTP_USER=,
SMTP_PASSWORD=,
SMTP_HOST=,
Expand All @@ -28,3 +29,4 @@ GOOGLE_AUTH_CALLBACK_URL=
FLW_PUBLIC_KEY=
FLW_SECRET_KEY=
FLW_ENCRYPTION_KEY=
BASE_URL=
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@ package-lock.json
docker-compose.yml
package-lock.json

.mail.ts.bk
src/bk
swagger.json
7 changes: 7 additions & 0 deletions src/config/app.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import config from ".";

const APP_CONFIG = Object.freeze({
USE_HTTPS: config.NODE_ENV !== "development" ? true : false,
});

export default APP_CONFIG;
2 changes: 2 additions & 0 deletions src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const config = {
DB_PORT: process.env.DB_PORT,
DB_NAME: process.env.DB_NAME,
TOKEN_SECRET: process.env.AUTH_SECRET,
TOKEN_EXPIRY: process.env.AUTH_EXPIRY,
SMTP_USER: process.env.SMTP_USER,
SMTP_PASSWORD: process.env.SMTP_PASSWORD,
SMTP_HOST: process.env.SMTP_HOST,
Expand All @@ -30,6 +31,7 @@ const config = {
FLW_SECRET_KEY: process.env.FLW_SECRET_KEY,
FLW_ENCRYPTION_KEY: process.env.FLW_ENCRYPTION_KEY,
LEMONSQUEEZY_SIGNING_KEY: process.env.LEMONSQUEEZY_SIGNING_KEY,
BASE_URL: process.env.BASE_URL,
};

export default config;
123 changes: 100 additions & 23 deletions src/controllers/AuthController.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { Request, Response, NextFunction } from "express";
import { AuthService } from "../services/auth.services";
import { BadRequest } from "../middleware";
import { GoogleUserInfo } from "../services/google.auth.service";
import { verifyToken } from "../config/google.passport.config";
import { NextFunction, Request, Response } from "express";
import jwt from "jsonwebtoken";
import config from "../config";
import { verifyToken } from "../config/google.passport.config";
import { BadRequest } from "../middleware";
import { User } from "../models";
import { AuthService } from "../services/auth.services";
import { GoogleUserInfo } from "../services/google.auth.service";
import RequestUtils from "../utils/request.utils";

const authService = new AuthService();

Expand Down Expand Up @@ -205,19 +207,8 @@ const login = async (req: Request, res: Response, next: NextFunction) => {
* 500:
* description: Internal server error.
*/
// const forgotPassword = async (
// req: Request,
// res: Response,
// next: NextFunction,
// ) => {
// try {
// const { email } = req.body;
// const { message } = await authService.forgotPassword(email);
// res.status(200).json({ status: "sucess", status_code: 200, message });
// } catch (error) {
// next(error);
// }
// };

const forgotPassword = async () => {};

/**
* @swagger
Expand Down Expand Up @@ -274,6 +265,7 @@ const login = async (req: Request, res: Response, next: NextFunction) => {
// next(error);
// }
// };
const resetPassword = async () => {};

/**
* @swagger
Expand Down Expand Up @@ -399,6 +391,89 @@ const changePassword = async (
* description: Internal Server Error - An unexpected error occurred
*/

const googleSignIn = async () => {};

const createMagicToken = async (
req: Request,
res: Response,
next: NextFunction,
) => {
try {
const email = req.body?.email;
if (!email) {
throw new BadRequest("Email is missing in request body.");
}
const response = await authService.generateMagicLink(email);
if (!response.ok) {
throw new BadRequest("Error processing request");
}
const requestUtils = new RequestUtils(req, res);
requestUtils.addDataToState("localUser", response.user);

return res.status(200).json({
status_code: 200,
message: `Sign-in token sent to email` || response.message,
});
} catch (error) {
next(error);
}
};

const authenticateUserMagicLink = async (
req: Request,
res: Response,
next: NextFunction,
) => {
try {
const token = req.query.token;
const response = await authService.validateMagicLinkToken(token as string);
if (response.status !== "ok") {
throw new BadRequest("Invalid Request");
}
const { access_token } = await authService.passwordlessLogin(
response.userId,
);

const requestUtils = new RequestUtils(req, res);
let user: User = requestUtils.getDataFromState("local_user");
if (!user?.email && !user?.id) {
user = await User.findOne({
where: { email: response.email },
});
}

const responseData = {
id: user.id,
email: user.email,
name: user.name,
};

res.header("Authorization", access_token);
res.cookie("hng_token", access_token, {
maxAge: 24 * 60 * 60 * 1000,
httpOnly: true,
secure: config.NODE_ENV !== "development",
sameSite: config.NODE_ENV === "development" ? "lax" : "none",
path: "/",
});

if (req.query?.redirect === "true") {
return res.redirect("/");
} else {
return res.status(200).json({
status: "ok",
data: responseData,
access_token,
});
}
} catch (err) {
if (err instanceof BadRequest) {
return res.status(400).json({ status: "error", message: err.message });
}
next(err);
}
};

const googleAuthCall = async (req: Request, res: Response) => {
try {
const { id_token } = req.body;
Expand All @@ -417,17 +492,19 @@ const googleAuthCall = async (req: Request, res: Response) => {
// Return the JWT and User
res.json({ user, access_token: token });
} catch (error) {
console.error(error);
res.status(400).json({ error: "Authentication failed" });
}
};

export {
signUp,
verifyOtp,
authenticateUserMagicLink,
changePassword,
createMagicToken,
googleAuthCall,
// handleGoogleAuth,
login,
signUp,
// forgotPassword,
// resetPassword,
changePassword,
googleAuthCall,
verifyOtp,
};
36 changes: 35 additions & 1 deletion src/controllers/BlogController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import { Request, Response } from "express";
import { BlogService } from "../services";

export class BlogController {
private blogService = new BlogService();
private blogService: BlogService;

constructor() {
this.blogService = new BlogService();
}

/**
* @swagger
Expand Down Expand Up @@ -379,4 +383,34 @@ export class BlogController {
});
}
}

async createBlogController(req: Request, res: Response) {
const { title, content, image_url, tags, categories } = req.body;

try {
const newBlog = await this.blogService.createBlogPost(
title,
content,
req.user.id,
image_url,
tags,
categories,
);
res.status(201).json({
status: "success",
status_code: 201,
message: "Blog post created successfully",
data: {
blog: newBlog,
author: req.user.id,
},
});
} catch (error) {
res.status(500).json({
status: "unsuccessful",
status_code: 500,
message: error.message,
});
}
}
}
2 changes: 0 additions & 2 deletions src/controllers/GoogleAuthController.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import passport from "../config/google.passport.config";
import { ServerError, Unauthorized } from "../middleware";
import { Request, Response, NextFunction } from "express";

/**
* @swagger
Expand Down
30 changes: 0 additions & 30 deletions src/controllers/createBlogController.ts

This file was deleted.

4 changes: 2 additions & 2 deletions src/controllers/sendEmail.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,10 @@
*/

import { Request, Response } from "express";
import AppDataSource from "../data-source";
import { User } from "../models";
import { EmailService } from "../services";
import { EmailQueuePayload } from "../types";
import { User } from "../models";
import AppDataSource from "../data-source";

const emailService = new EmailService();

Expand Down
45 changes: 24 additions & 21 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
// src/index.ts
import "reflect-metadata";
import AppDataSource from "./data-source";
import log from "./utils/logger";
import cors from "cors";
import dotenv from "dotenv";
import express, { Express, Request, Response } from "express";
import "reflect-metadata";
import swaggerUi from "swagger-ui-express";
import config from "./config";
import dotenv from "dotenv";
import cors from "cors";
import passport from "./config/google.passport.config";
import AppDataSource from "./data-source";
import { errorHandler, routeNotFound } from "./middleware";
import {
userRouter,
adminRouter,
authRoute,
helpRouter,
testimonialRoute,
notificationRouter,
productRouter,
jobRouter,
blogRouter,
adminRouter,
exportRouter,
sendEmailRoute,
paymentRouter,
contactRouter,
exportRouter,
faqRouter,
helpRouter,
jobRouter,
notificationRouter,
paymentFlutterwaveRouter,
paymentRouter,
paymentStripeRouter,
faqRouter,
productRouter,
sendEmailRoute,
testimonialRoute,
userRouter,
} from "./routes";
import { smsRouter } from "./routes/sms";
import { routeNotFound, errorHandler } from "./middleware";
import { orgRouter } from "./routes/organisation";
import swaggerUi from "swagger-ui-express";
import swaggerSpec from "./swaggerConfig";
import { smsRouter } from "./routes/sms";
import updateRouter from "./routes/updateOrg";
import swaggerSpec from "./swaggerConfig";
import { Limiter } from "./utils";
import log from "./utils/logger";
import ServerAdapter from "./views/bull-board";
import passport from "./config/google.passport.config";
dotenv.config();

const port = config.port;
Expand Down Expand Up @@ -64,6 +64,9 @@ server.get("/api/v1/probe", (req: Request, res: Response) => {
});
server.use("/api/v1", authRoute);
server.use("/api/v1", userRouter);

server.use("/api/v1", authRoute);

server.use("/api/v1", adminRouter);
server.use("/api/v1", sendEmailRoute);
server.use("/api/v1", helpRouter);
Expand Down
14 changes: 4 additions & 10 deletions src/middleware/auth.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
import { Request, Response, NextFunction } from "express";
import { verifyToken } from "../utils";
import { User } from "../models";
import {
HttpError,
ResourceNotFound,
ServerError,
Unauthorized,
} from "./error";
import log from "../utils/logger";
import { NextFunction, Request, Response } from "express";
import jwt from "jsonwebtoken";
import config from "../config";
import { User } from "../models";
import log from "../utils/logger";
import { ServerError } from "./error";

export const authMiddleware = async (
req: Request & { user?: User },
Expand Down
Loading

0 comments on commit 9257cfb

Please sign in to comment.