diff --git a/customer-auth/controllers/userController.js b/customer-auth/controllers/userController.js index 4597e27..63be697 100644 --- a/customer-auth/controllers/userController.js +++ b/customer-auth/controllers/userController.js @@ -76,7 +76,7 @@ const authUser = asyncHandler(async (req, res) => { email: user.email, }); } else { - res.status(401); + res.status(400); throw new Error("Invalid email or password"); } } catch (error) { @@ -138,11 +138,11 @@ const logoutUser = (req, res) => { }; // @desc Get user profile -// @route GET api/users/profile +// @route POST api/users/profile // @access Private const getUserProfile = asyncHandler(async (req, res) => { try { - const user = await User.findOne(req.email); + const user = await User.findOne({email: req.body.email}); if (user) { res.json({ @@ -169,7 +169,7 @@ const getUserProfile = asyncHandler(async (req, res) => { // @access Private const updateUserProfile = asyncHandler(async (req, res) => { try { - const user = await User.findOne(req.email); + const user = await User.findOne({email: req.body.email}); if (user) { user.password = req.body.password || user.password; diff --git a/customer-auth/package-lock.json b/customer-auth/package-lock.json index 574c072..7844c66 100644 --- a/customer-auth/package-lock.json +++ b/customer-auth/package-lock.json @@ -19,6 +19,7 @@ "dotenv": "^16.0.3", "express": "^4.18.2", "express-async-handler": "^1.2.0", + "js-yaml": "^4.1.0", "jsonwebtoken": "^9.0.0", "loadtest": "^5.2.0", "mongoose": "^7.1.0", diff --git a/customer-auth/package.json b/customer-auth/package.json index d28cf9d..acbca9e 100644 --- a/customer-auth/package.json +++ b/customer-auth/package.json @@ -22,6 +22,7 @@ "dotenv": "^16.0.3", "express": "^4.18.2", "express-async-handler": "^1.2.0", + "js-yaml": "^4.1.0", "jsonwebtoken": "^9.0.0", "loadtest": "^5.2.0", "mongoose": "^7.1.0", diff --git a/customer-auth/routes/userRoutes.js b/customer-auth/routes/userRoutes.js index 203c55b..a73bfce 100644 --- a/customer-auth/routes/userRoutes.js +++ b/customer-auth/routes/userRoutes.js @@ -16,340 +16,13 @@ import { protect } from "../middleware/authMiddleware.js"; const router = express.Router(); -/** - * @openapi - * /api/users/: - * post: - * summary: Register a new user - * description: Register a new user with the provided name, email, and password. - * tags: - * - Authentication - * requestBody: - * required: true - * content: - * application/json: - * schema: - * type: object - * properties: - * name: - * type: string - * email: - * type: string - * password: - * type: string - * required: - * - name - * - email - * - password - * responses: - * '200': - * description: User successfully registered - * content: - * application/json: - * schema: - * type: object - * properties: - * _id: - * type: string - * description: The ID of the registered user - * name: - * type: string - * description: The name of the registered user - * email: - * type: string - * description: The email of the registered user - * headers: - * Set-Cookie: - * description: Authentication cookie containing the access token - * schema: - * type: string - * '400': - * description: Invalid user data or user already exists - * content: - * application/json: - * schema: - * type: object - * properties: - * message: - * type: string - * description: Error message describing the issue - * '500': - * description: Internal Server Error - * content: - * application/json: - * schema: - * type: object - * properties: - * message: - * type: string - * description: Error message or "Internal Server Error" - * stack: - * type: string - * description: Stack trace (only in development mode) - */ - router.post("/", registerUser); -/** - * @swagger - * /api/users/auth: - * post: - * summary: Authenticate user and get token - * description: Authenticate a user with the provided email and password and retrieve an access token. - * tags: - * - Authentication - * requestBody: - * required: true - * content: - * application/json: - * schema: - * type: object - * properties: - * email: - * type: string - * password: - * type: string - * required: - * - email - * - password - * responses: - * '200': - * description: User authenticated successfully - * content: - * application/json: - * schema: - * type: object - * properties: - * _id: - * type: string - * description: The ID of the authenticated user - * name: - * type: string - * description: The name of the authenticated user - * email: - * type: string - * description: The email of the authenticated user - * headers: - * Set-Cookie: - * description: Authentication cookie containing the access token - * schema: - * type: string - * '400': - * description: Invalid email or password - * content: - * application/json: - * schema: - * type: object - * properties: - * message: - * type: string - * description: Error message describing the issue - * '500': - * description: Internal Server Error - * content: - * application/json: - * schema: - * type: object - * properties: - * message: - * type: string - * description: Error message or "Internal Server Error" - * stack: - * type: string - * description: Stack trace (only in development mode) - */ router.post("/auth", authUser); -/** - * @swagger - * /api/users/logout: - * post: - * summary: Logout user and clear authentication - * description: Logout the currently authenticated user and clear the JWT token from the request headers. - * tags: - * - Authentication - * parameters: - * - in: header - * name: Authorization - * description: JWT token in the format "\" - * required: true - * schema: - * type: string - * responses: - * '200': - * description: User logged out successfully - * content: - * application/json: - * schema: - * type: object - * properties: - * message: - * type: string - * description: Success message indicating successful logout - * '400': - * description: No JWT token found in the request headers - * content: - * application/json: - * schema: - * type: object - * properties: - * message: - * type: string - * description: Error message indicating the absence of a JWT token - * '500': - * description: Internal Server Error - * content: - * application/json: - * schema: - * type: object - * properties: - * message: - * type: string - * description: Error message or "Internal Server Error" - * stack: - * type: string - * description: Stack trace (only in development mode) - */ router.post("/logout", logoutUser); -/** - * @swagger - * /api/users/profile: - * get: - * summary: Get user profile - * description: Get the profile of the currently authenticated user. - * tags: - * - User Profile - * security: - * - cookieAuth: [] - * responses: - * '200': - * description: User profile retrieved successfully - * content: - * application/json: - * schema: - * type: object - * properties: - * _id: - * type: string - * description: The ID of the user - * name: - * type: string - * description: The name of the user - * email: - * type: string - * description: The email of the user - * createdAt: - * type: string - * format: date-time - * description: The creation date of the user profile - * updatedAt: - * type: string - * format: date-time - * description: The last update date of the user profile - * '401': - * description: User is not authenticated or the token is invalid - * content: - * application/json: - * schema: - * type: object - * properties: - * message: - * type: string - * description: Error message indicating authentication failure - * '500': - * description: Internal Server Error - * content: - * application/json: - * schema: - * type: object - * properties: - * message: - * type: string - * description: Error message or "Internal Server Error" - * stack: - * type: string - * description: Stack trace (only in development mode) - * put: - * summary: Update user profile - * description: Update the profile of the currently authenticated user. - * tags: - * - User Profile - * security: - * - cookieAuth: [] - * requestBody: - * required: true - * content: - * application/json: - * schema: - * type: object - * properties: - * name: - * type: string - * description: The new name of the user - * required: - * - name - * responses: - * '200': - * description: User profile updated successfully - * content: - * application/json: - * schema: - * type: object - * properties: - * _id: - * type: string - * description: The ID of the updated user profile - * name: - * type: string - * description: The updated name of the user - * email: - * type: string - * description: The email of the user - * createdAt: - * type: string - * format: date-time - * description: The creation date of the user profile - * updatedAt: - * type: string - * format: date-time - * description: The last update date of the user profile - * '400': - * description: Invalid request data or missing required fields - * content: - * application/json: - * schema: - * type: object - * properties: - * message: - * type: string - * description: Error message describing the issue - * '401': - * description: User is not authenticated or the token is invalid - * content: - * application/json: - * schema: - * type: object - * properties: - * message: - * type: string - * description: Error message indicating authentication failure - * '500': - * description: Internal Server Error - * content: - * application/json: - * schema: - * type: object - * properties: - * message: - * type: string - * description: Error message or "Internal Server Error" - * stack: - * type: string - * description: Stack trace (only in development mode) - */ - -router.route("/profile").get(getUserProfile).put(updateUserProfile); +router.route("/profile").post(getUserProfile).put(updateUserProfile); // router // .route("/profile") diff --git a/customer-auth/utils/swagger.js b/customer-auth/utils/swagger.js index 2a5847f..1d3201c 100644 --- a/customer-auth/utils/swagger.js +++ b/customer-auth/utils/swagger.js @@ -6,17 +6,30 @@ import swaggerJSDoc from "swagger-jsdoc"; import swaggerUI from "swagger-ui-express"; +import fs from "fs/promises"; +import yaml from "js-yaml"; +import { fileURLToPath } from "url"; +import { dirname, join } from "path"; + +const getYamlContent = async () => { + try { + const swaggerSpecsFile = join( + dirname(fileURLToPath(import.meta.url)), + "swagger.yaml" + ); + const yamlContent = await fs.readFile(swaggerSpecsFile, "utf8"); + return yamlContent; + } catch (error) { + console.error("Error reading file:", error); + throw error; + } +}; + +const parsedData = yaml.load(await getYamlContent()); // Swagger options const swaggerOptions = { - definition: { - openapi: "3.0.0", - info: { - title: "customer-auth", - version: "1.0.0", - description: "API documentation for the customer-auth microservice", - }, - }, + definition: parsedData, apis: ["./routes/userRoutes.js"], }; diff --git a/customer-auth/utils/swagger.yaml b/customer-auth/utils/swagger.yaml new file mode 100644 index 0000000..98e5867 --- /dev/null +++ b/customer-auth/utils/swagger.yaml @@ -0,0 +1,132 @@ +openapi: 3.0.0 +info: + title: User Authentication and Profile API + description: API for user registration, authentication, and profile management + version: 1.0.0 + +paths: + /api/users/: + post: + summary: Register a new user + description: Register a new user with the provided name, email, and password. + tags: + - Authentication + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + name: + type: string + email: + type: string + password: + type: string + required: + - name + - email + - password + responses: + '200': + description: User successfully registered + '400': + description: Invalid user data or user already exists + '500': + description: Internal Server Error + /api/users/auth: + post: + summary: Authenticate user and get token + description: Authenticate a user with the provided email and password and retrieve an access token. + tags: + - Authentication + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + email: + type: string + password: + type: string + required: + - email + - password + responses: + '200': + description: User authenticated successfully + '400': + description: Invalid email or password + '500': + description: Internal Server Error + /api/users/logout: + post: + summary: Logout user and clear authentication + description: Logout the currently authenticated user and clear the JWT token from the request headers. + tags: + - Authentication + responses: + '200': + description: User logged out successfully + '500': + description: Internal Server Error + /api/users/profile: + post: + summary: Get user profile + description: Get the profile of the currently authenticated user. + tags: + - User Profile + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + email: + type: string + required: + - email + responses: + '200': + description: User profile retrieved successfully + '400': + description: User is not authenticated or the token is invalid + '404': + description: User is not found. + '500': + description: Internal Server Error + put: + summary: Update user profile + description: Update the profile of the currently authenticated user. + tags: + - User Profile + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + name: + type: string + email: + type: string + password: + type: string + required: + - name + - email + - password + responses: + '200': + description: User profile updated successfully + '400': + description: Invalid request data or missing required fields + '404': + description: User is not found. + '500': + description: Internal Server Error diff --git a/ui/src/screens/ProfileScreen.jsx b/ui/src/screens/ProfileScreen.jsx index d6a9ee0..19bdc92 100644 --- a/ui/src/screens/ProfileScreen.jsx +++ b/ui/src/screens/ProfileScreen.jsx @@ -40,10 +40,9 @@ const ProfileScreen = () => { } else { try { const res = await updateProfile({ - _id: userInfo._id, - name, - email, - password, + name: name, + email: email, + password: password, // token: Cookies.get("jwt"), }).unwrap(); dispatch(setCredentials(res)); diff --git a/ui/src/slices/usersApiSlice.js b/ui/src/slices/usersApiSlice.js index f18f210..932efe8 100644 --- a/ui/src/slices/usersApiSlice.js +++ b/ui/src/slices/usersApiSlice.js @@ -51,12 +51,7 @@ export const userApiSlice = apiSlice.injectEndpoints({ query: (data) => ({ url: `${usersUrl}/profile`, method: "PUT", - body: { - _id: data._id, - name: data.name, - email: data.email, - password: data.password, - }, + body: data, // headers: { // 'Content-Type': 'application/json', // 'Authorization': data.token