Skip to content

Commit

Permalink
Merge pull request #413 from masterchief-Dave/feature/auth-forgot-res…
Browse files Browse the repository at this point in the history
…et-password

feat: test api route
  • Loading branch information
AdeGneus authored Jul 31, 2024
2 parents 566e2f2 + 178a044 commit 7601748
Show file tree
Hide file tree
Showing 12 changed files with 238 additions and 35 deletions.
149 changes: 148 additions & 1 deletion src/controllers/AuthController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,79 @@ const changePassword = async (

const googleSignIn = async () => {};

/**
* @swagger
* /api/v1/auth/magic-link:
* post:
* tags:
* - Auth
* summary: Passwordless sign-in with email
* description: API endpoint to initiate passwordless sign-in by sending email to the registered user
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* email:
* type: string
* format: email
* example: [email protected]
* responses:
* 200:
* description: Sign-in token sent to email
* content:
* application/json:
* schema:
* type: object
* properties:
* status_code:
* type: integer
* example: 200
* message:
* type: string
* example: Sign-in token sent to email
* 400:
* description: Bad request
* content:
* application/json:
* schema:
* type: object
* properties:
* status_code:
* type: integer
* example: 400
* message:
* type: string
* example: Invalid request body
* 404:
* description: User not found
* content:
* application/json:
* schema:
* type: object
* properties:
* status_code:
* type: integer
* example: 404
* message:
* type: string
* example: User not found
* 500:
* description: Internal server error
* content:
* application/json:
* schema:
* type: object
* properties:
* status_code:
* type: integer
* example: 500
* message:
* type: string
* example: Internal server error
*/
const createMagicToken = async (
req: Request,
res: Response,
Expand All @@ -419,6 +492,80 @@ const createMagicToken = async (
}
};

/**
* @swagger
* /api/v1/auth/magic-link:
* get:
* tags:
* - Auth
* summary: Authenticate user with magic link
* description: Validates the magic link token and authenticates the user
* parameters:
* - in: query
* name: token
* required: true
* schema:
* type: string
* description: Magic link token
* - in: query
* name: redirect
* schema:
* type: boolean
* description: Whether to redirect after authentication (true/false)
* responses:
* 200:
* description: User authenticated successfully
* headers:
* Authorization:
* schema:
* type: string
* description: Bearer token for authentication
* Set-Cookie:
* schema:
* type: string
* description: Contains the hng_token
* content:
* application/json:
* schema:
* type: object
* properties:
* status:
* type: string
* example: ok
* data:
* type: object
* properties:
* id:
* type: string
* example: user123
* email:
* type: string
* example: [email protected]
* name:
* type: string
* example: John Doe
* access_token:
* type: string
* example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
* 302:
* description: Redirect to home page (when redirect=true)
* 400:
* description: Bad request
* content:
* application/json:
* schema:
* type: object
* properties:
* status:
* type: string
* example: error
* message:
* type: string
* example: Invalid Request
* 500:
* description: Internal server error
* security: []
*/
const authenticateUserMagicLink = async (
req: Request,
res: Response,
Expand Down Expand Up @@ -461,7 +608,7 @@ const authenticateUserMagicLink = async (
return res.redirect("/");
} else {
return res.status(200).json({
status: "ok",
status_code: 200,
data: responseData,
access_token,
});
Expand Down
55 changes: 31 additions & 24 deletions src/controllers/runTestController.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,35 @@
import { Request, Response } from "express";
import { exec } from "child_process";
import { Request, Response } from "express";

export const runTestController = async (req: Request, res: Response) => {
exec("python3 ./tests/run_test.py", (error, stdout, stderr) => {
if (stderr) {
console.error(`stderr: ${stderr}`);
res.status(500).json({
status_code: 500,
message: "Script error",
error: stderr,
});
} else if (error) {
res.status(500).json({
status_code: 500,
message: "Script error",
error: error,
});
} else {
console.log(`stdout: ${stdout}`);
res.status(200).json({
status_code: 200,
message: "Script executed successfully",
data: stdout,
});
}
});
exec(
"python3 src/controllers/tests/tests/run_tests.py",
(error, stdout, stderr) => {
if (stderr) {
res.status(500).json({
status_code: 500,
message: "Script error",
error: stderr,
});
} else if (error) {
res.status(500).json({
status_code: 500,
message: "Script error",
error: error,
});
} else {
const formattedOutput = stdout
.split("\n")
.map((line) => line.trim())
.filter((line) => line.length > 0)
.join("\n");

res.status(200).json({
status_code: 200,
message: "Script executed successfully",
data: formattedOutput,
});
}
},
);
};
1 change: 1 addition & 0 deletions src/controllers/tests/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ python-dateutil==2.9.0.post0
requests==2.32.3
six==1.16.0
urllib3==2.2.2
pprintpp==0.4.0
Binary file not shown.
Binary file not shown.
5 changes: 4 additions & 1 deletion src/controllers/tests/tests/run_tests.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import subprocess
import sys
import pprintpp

def run_tests():
python_executable = sys.executable
Expand All @@ -9,8 +10,10 @@ def run_tests():

if __name__ == "__main__":
output, exit_code = run_tests()
print(output)
# print(output)
pprintpp.pprint(output)
if exit_code != 0:
print("Some tests failed.")
else:
print("All tests passed.")

3 changes: 3 additions & 0 deletions src/controllers/tests/tests/test_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
fake = Faker()

BASE_URL = "https://deployment.api-expressjs.boilerplate.hng.tech/api/v1"
# BASE_URL = "http://localhost:5000/api/v1"

# Utility function to generate random data for tests
def generate_random_user():
Expand All @@ -25,6 +26,8 @@ def login_and_get_token(email, password):
response = requests.post(url, json=payload)
assert response.status_code == 200
data = response.json()
print(data)
print("hello world, this is a python script")
return data["data"]["token"]

def test_register_user():
Expand Down
7 changes: 2 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,15 @@ import {
paymentRouter,
paymentStripeRouter,
productRouter,
runTestRouter,
sendEmailRoute,
testimonialRoute,
userRouter,
runTestRouter,
} from "./routes";
import { orgRouter } from "./routes/organisation";
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";
dotenv.config();
Expand All @@ -52,7 +51,6 @@ server.use(
}),
);

server.use(Limiter);
server.use(express.json());
server.use(express.urlencoded({ extended: true }));
server.use(passport.initialize());
Expand All @@ -63,11 +61,10 @@ server.get("/api/v1", (req: Request, res: Response) => {
server.get("/api/v1/probe", (req: Request, res: Response) => {
res.send("I am the express api responding for team panther");
});
server.use("/api/v1", runTestRouter);
server.use("/run-tests", runTestRouter);
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
4 changes: 2 additions & 2 deletions src/middleware/request-validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ const requestBodyValidator = (schema: ZodSchema<any>) => {
} catch (err) {
if (err instanceof ZodError) {
return res.status(400).json({
message: "Validation Error",
errors: err.errors,
message: "Invalid request body",
// errors: err.errors,
});
}
next(err);
Expand Down
4 changes: 2 additions & 2 deletions src/routes/run-test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Router, Response, Request } from "express";
import { Router } from "express";
import { runTestController } from "../controllers";

const runTestRouter = Router();

runTestRouter.get("/run-test", runTestController);
runTestRouter.get("/", runTestController);

export { runTestRouter };
44 changes: 44 additions & 0 deletions src/schema/auth.schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { object, string, TypeOf } from "zod";
import { emailSchema } from "../utils/request-body-validator";

/**
* @openapi
* components:
* schemas:
* CreateMagicLink:
* type: object
* required:
* - email
* properties:
* email:
* type: string
* format: email
* example: [email protected]
* ValidateMagicLink:
* type: object
* required:
* - token
* properties:
* token:
* type: string
* example: "exampleToken123"
*/

const createMagicLinkPayload = {
body: object({
email: emailSchema,
}),
};

const magicLinkQuery = object({
token: string().min(1, "Token is required"),
});

export const validateMagicLinkSchema = object({
query: magicLinkQuery,
});

export const createMagicLinkSchema = object({ ...createMagicLinkPayload });

export type validateMagicLinkInput = TypeOf<typeof validateMagicLinkSchema>;
export type CreateMagicLinkInput = TypeOf<typeof createMagicLinkSchema>;
1 change: 1 addition & 0 deletions src/services/blog.services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export class BlogService {
const author = await this.userRepository.findOne({
where: { id: authorId },
});
newBlog.author = author;

const tagsContent = tags.split(",");
const categoriesContent = categories.split(",");
Expand Down

0 comments on commit 7601748

Please sign in to comment.