From 318900cba811aae20ea5e95b868e69d87002a68e Mon Sep 17 00:00:00 2001 From: Mohamed Dawoud Date: Fri, 4 Apr 2025 17:58:25 +0200 Subject: [PATCH 1/5] docs: add custom docs for auth controller functions --- src/controllers/auth.controller.js | 271 +++-------------------------- 1 file changed, 28 insertions(+), 243 deletions(-) diff --git a/src/controllers/auth.controller.js b/src/controllers/auth.controller.js index e7b6831..6e13dd9 100644 --- a/src/controllers/auth.controller.js +++ b/src/controllers/auth.controller.js @@ -20,41 +20,10 @@ import { googleVerifyIdToken } from '../utils/googleVerifyToken.utils.js'; /* eslint no-undef:off */ /** - * @swagger - * /api/auth/signup: - * post: - * summary: Register a new user - * tags: [Auth] - * requestBody: - * required: true - * content: - * application/json: - * schema: - * type: object - * required: - * - email - * - password - * - firstName - * - lastName - * - username - * properties: - * email: - * type: string - * password: - * type: string - * firstName: - * type: string - * lastName: - * type: string - * username: - * type: string - * responses: - * 201: - * description: User created successfully - * 400: - * description: Bad request - * 500: - * description: Server error + * @desc Creates a new user account and sends verification OTP to email + * @route /api/auth/signup + * @method POST + * @access public */ export const signup = async (req, res, next) => { try { @@ -120,34 +89,10 @@ export const signup = async (req, res, next) => { }; /** - * @swagger - * /api/auth/verifyEmail: - * post: - * summary: Verify user's email address using OTP - * tags: [Auth] - * requestBody: - * required: true - * content: - * application/json: - * schema: - * type: object - * required: - * - email - * - otp - * properties: - * email: - * type: string - * otp: - * type: string - * responses: - * 200: - * description: Email verified successfully - * 400: - * description: Invalid or expired OTP - * 404: - * description: User not found - * 500: - * description: Server error + * @desc Verify user's email address using the OTP sent to their email + * @route /api/auth/verifyEmail + * @method POST + * @access public */ export const verifyEmail = async (req, res, next) => { try { @@ -191,54 +136,10 @@ export const verifyEmail = async (req, res, next) => { }; /** - * @swagger - * /api/auth/signin: - * post: - * summary: Authenticate user and get access token - * tags: [Auth] - * requestBody: - * required: true - * content: - * application/json: - * schema: - * type: object - * required: - * - email - * - password - * properties: - * email: - * type: string - * password: - * type: string - * responses: - * 200: - * description: Login successful - * content: - * application/json: - * schema: - * type: object - * properties: - * accessToken: - * type: string - * refreshToken: - * type: string - * user: - * type: object - * properties: - * id: - * type: string - * email: - * type: string - * name: - * type: string - * role: - * type: string - * 401: - * description: Invalid credentials - * 403: - * description: Account not activated - * 500: - * description: Server error + * @desc Authenticate user and return JWT tokens + * @route /api/auth/signin + * @method POST + * @access public */ export const signin = async (req, res, next) => { try { @@ -299,27 +200,10 @@ export const signin = async (req, res, next) => { }; /** - * @swagger - * /api/auth/forgotPassword: - * post: - * summary: Request password reset OTP - * tags: [Auth] - * requestBody: - * required: true - * content: - * application/json: - * schema: - * type: object - * required: - * - email - * properties: - * email: - * type: string - * responses: - * 200: - * description: Password reset OTP sent if account exists - * 500: - * description: Server error + * @desc Initiate password reset process by sending OTP to user's email + * @route /api/auth/forgotPassword + * @method POST + * @access public */ export const forgotPassword = async (req, res, next) => { try { @@ -369,37 +253,10 @@ export const forgotPassword = async (req, res, next) => { }; /** - * @swagger - * /api/auth/resetPassword: - * post: - * summary: Reset password using OTP - * tags: [Auth] - * requestBody: - * required: true - * content: - * application/json: - * schema: - * type: object - * required: - * - email - * - otp - * - newPassword - * properties: - * email: - * type: string - * otp: - * type: string - * newPassword: - * type: string - * responses: - * 200: - * description: Password reset successful - * 400: - * description: Invalid or expired OTP - * 404: - * description: User not found - * 500: - * description: Server error + * @desc Reset user password using the OTP received via email + * @route /api/auth/resetPassword + * @method POST + * @access public */ export const resetPassword = async (req, res, next) => { try { @@ -449,38 +306,10 @@ export const resetPassword = async (req, res, next) => { }; /** - * @swagger - * /api/auth/refreshAccessToken: - * post: - * summary: Get new access token using refresh token - * tags: [Auth] - * requestBody: - * required: true - * content: - * application/json: - * schema: - * type: object - * required: - * - refreshToken - * properties: - * refreshToken: - * type: string - * responses: - * 200: - * description: New access token generated - * content: - * application/json: - * schema: - * type: object - * properties: - * accessToken: - * type: string - * 400: - * description: Refresh token is required - * 401: - * description: Invalid refresh token - * 500: - * description: Server error + * @desc Generate new access token using refresh token + * @route /api/auth/refreshAccessToken + * @method POST + * @access public */ export const refreshAccessToken = async (req, res, next) => { try { @@ -527,54 +356,10 @@ export const googleOAuthCallback = (req, res) => { }; /** - * @swagger - * /auth/google: - * post: - * summary: Authenticate or register user using Google OAuth (for mobile/SPA) - * tags: [Auth] - * requestBody: - * required: true - * content: - * application/json: - * schema: - * type: object - * required: - * - idToken - * properties: - * idToken: - * type: string - * responses: - * 200: - * description: Google authentication successful - * content: - * application/json: - * schema: - * type: object - * properties: - * user: - * type: object - * properties: - * id: - * type: string - * email: - * type: string - * name: - * type: string - * role: - * type: string - * profilePic: - * type: string - * tokens: - * type: object - * properties: - * accessToken: - * type: string - * refreshToken: - * type: string - * 400: - * description: Google authentication failed - * 500: - * description: Server error + * @desc Authenticate or register user using Google OAuth + * @route /api/auth/google + * @method POST + * @access public */ export const googleOAuthLogin = async (req, res) => { try { From 1977acc9223618d4d2111f24de29bc4e420c212f Mon Sep 17 00:00:00 2001 From: Mohamed Dawoud Date: Fri, 4 Apr 2025 18:00:43 +0200 Subject: [PATCH 2/5] refactor: routes docs --- src/routes/auth.routes.js | 274 -------------------------------------- 1 file changed, 274 deletions(-) diff --git a/src/routes/auth.routes.js b/src/routes/auth.routes.js index 77e8e02..a8b0ecf 100644 --- a/src/routes/auth.routes.js +++ b/src/routes/auth.routes.js @@ -14,253 +14,11 @@ import { apiLimiter } from '../utils/apiLimiter.utils.js'; const router = Router(); -/** - * @swagger - * tags: - * name: Auth - * description: Authentication endpoints - */ - -/** - * @swagger - * components: - * securitySchemes: - * bearerAuth: - * type: http - * scheme: bearer - * bearerFormat: JWT - * schemas: - * SignupRequest: - * type: object - * required: - * - email - * - password - * - firstName - * - lastName - * - username - * properties: - * email: - * type: string - * format: email - * description: User's email address - * password: - * type: string - * format: password - * description: User's password (min 8 characters) - * firstName: - * type: string - * description: User's first name - * lastName: - * type: string - * description: User's last name - * username: - * type: string - * description: Unique username - * SigninRequest: - * type: object - * required: - * - email - * - password - * properties: - * email: - * type: string - * format: email - * password: - * type: string - * format: password - * VerifyEmailRequest: - * type: object - * required: - * - email - * - otp - * properties: - * email: - * type: string - * format: email - * otp: - * type: string - * ForgotPasswordRequest: - * type: object - * required: - * - email - * properties: - * email: - * type: string - * format: email - * ResetPasswordRequest: - * type: object - * required: - * - email - * - otp - * - newPassword - * properties: - * email: - * type: string - * format: email - * otp: - * type: string - * newPassword: - * type: string - * format: password - * RefreshTokenRequest: - * type: object - * required: - * - refreshToken - * properties: - * refreshToken: - * type: string - * GoogleOAuthRequest: - * type: object - * required: - * - idToken - * properties: - * idToken: - * type: string - * description: Google OAuth ID token - */ - -/** - * @swagger - * /api/auth/signup: - * post: - * summary: Register a new user - * tags: [Auth] - * requestBody: - * required: true - * content: - * application/json: - * schema: - * $ref: '#/components/schemas/SignupRequest' - * responses: - * 201: - * description: User created successfully - * 400: - * description: Bad request - Invalid input - * 409: - * description: Conflict - Email or username already exists - */ router.post('/api/auth/signup', apiLimiter, signup); - -/** - * @swagger - * /api/auth/verifyEmail: - * post: - * summary: Verify user's email using OTP - * tags: [Auth] - * requestBody: - * required: true - * content: - * application/json: - * schema: - * $ref: '#/components/schemas/VerifyEmailRequest' - * responses: - * 200: - * description: Email verified successfully - * 400: - * description: Invalid or expired OTP - * 404: - * description: User not found - */ router.post('/api/auth/verifyEmail', apiLimiter, verifyEmail); - -/** - * @swagger - * /api/auth/signin: - * post: - * summary: Authenticate user and get tokens - * tags: [Auth] - * requestBody: - * required: true - * content: - * application/json: - * schema: - * $ref: '#/components/schemas/SigninRequest' - * responses: - * 200: - * description: Login successful - * content: - * application/json: - * schema: - * type: object - * properties: - * accessToken: - * type: string - * refreshToken: - * type: string - * user: - * type: object - * 401: - * description: Invalid credentials - * 403: - * description: Account not activated - */ router.post('/api/auth/signin', apiLimiter, signin); - -/** - * @swagger - * /api/auth/forgotPassword: - * post: - * summary: Request password reset OTP - * tags: [Auth] - * requestBody: - * required: true - * content: - * application/json: - * schema: - * $ref: '#/components/schemas/ForgotPasswordRequest' - * responses: - * 200: - * description: Reset OTP sent if account exists - */ router.post('/api/auth/forgotPassword', apiLimiter, forgotPassword); - -/** - * @swagger - * /api/auth/resetPassword: - * post: - * summary: Reset password using OTP - * tags: [Auth] - * requestBody: - * required: true - * content: - * application/json: - * schema: - * $ref: '#/components/schemas/ResetPasswordRequest' - * responses: - * 200: - * description: Password reset successful - * 400: - * description: Invalid or expired OTP - * 404: - * description: User not found - */ router.post('/api/auth/resetPassword', apiLimiter, resetPassword); - -/** - * @swagger - * /api/auth/refreshAccessToken: - * post: - * summary: Get new access token using refresh token - * tags: [Auth] - * requestBody: - * required: true - * content: - * application/json: - * schema: - * $ref: '#/components/schemas/RefreshTokenRequest' - * responses: - * 200: - * description: New access token generated - * content: - * application/json: - * schema: - * type: object - * properties: - * accessToken: - * type: string - * 401: - * description: Invalid refresh token - */ router.post('/api/auth/refreshAccessToken', apiLimiter, refreshAccessToken); // Google OAuth Routes @@ -283,38 +41,6 @@ router.get( googleOAuthCallback, ); -/** - * @swagger - * /auth/google: - * post: - * summary: Authenticate with Google ID token (mobile/SPA) - * tags: [Auth] - * requestBody: - * required: true - * content: - * application/json: - * schema: - * $ref: '#/components/schemas/GoogleOAuthRequest' - * responses: - * 200: - * description: Google authentication successful - * content: - * application/json: - * schema: - * type: object - * properties: - * user: - * type: object - * tokens: - * type: object - * properties: - * accessToken: - * type: string - * refreshToken: - * type: string - * 400: - * description: Google authentication failed - */ router.post('/auth/google', googleOAuthLogin); export default router; From 7cf90051ffc540e58cd188695dca0ecb1bfae307 Mon Sep 17 00:00:00 2001 From: Mohamed Dawoud Date: Fri, 4 Apr 2025 18:06:28 +0200 Subject: [PATCH 3/5] docs: add custom docs for organization controller functions --- src/controllers/organization.controller.js | 60 ++++++++++++---------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/src/controllers/organization.controller.js b/src/controllers/organization.controller.js index 6678b64..52bfc32 100644 --- a/src/controllers/organization.controller.js +++ b/src/controllers/organization.controller.js @@ -8,32 +8,10 @@ import { } from '../validations/organization.validation.js'; /** - * @swagger - * /api/organization: - * post: - * summary: Create a new organization - * tags: [Organization] - * security: - * - bearerAuth: [] - * requestBody: - * required: true - * content: - * application/json: - * schema: - * $ref: '#/components/schemas/CreateOrganizationRequest' - * responses: - * 201: - * description: Organization created successfully - * content: - * application/json: - * schema: - * $ref: '#/components/schemas/CreateOrganizationResponse' - * 400: - * description: Bad request - Validation error - * 409: - * description: Conflict - Organization already exists - * 500: - * description: Server error + * @desc Create a new organization with the current user as owner + * @route /api/organization + * @method POST + * @access private */ export const createOrganization = async (req, res, next) => { try { @@ -143,6 +121,12 @@ export const createOrganization = async (req, res, next) => { } }; +/** + * @desc Verify organization's contact email using OTP + * @route /api/organization/verifyOrg + * @method POST + * @access private + */ export const verifyOrganization = async (req, res, next) => { try { const { error } = verifyOrganizationValidation(req.body); @@ -187,6 +171,12 @@ export const verifyOrganization = async (req, res, next) => { } }; +/** + * @desc Get paginated list of organizations with filtering and sorting + * @route /api/organization/all + * @method GET + * @access private + */ export const getAllOrganizations = async (req, res, next) => { try { // Destructure and parse query params with defaults @@ -302,6 +292,12 @@ export const getAllOrganizations = async (req, res, next) => { } }; +/** + * @desc Get detailed information about a specific organization + * @route /api/organization/:organizationId + * @method GET + * @access private + */ export const getSpecificOrganization = async (req, res, next) => { try { const { organizationId } = req.params; @@ -461,6 +457,12 @@ export const getSpecificOrganization = async (req, res, next) => { } }; +/** + * @desc Update organization details + * @route /api/organization/:organizationId + * @method PUT + * @access private + */ export const updateOrganization = async (req, res, next) => { try { const { organizationId } = req.params; @@ -618,6 +620,12 @@ export const updateOrganization = async (req, res, next) => { } }; +/** + * @desc Soft delete an organization (marks as deleted but retains in database) + * @route /api/organization/:organizationId + * @method DELETE + * @access private + */ export const deleteOrganization = async (req, res, next) => { try { const { organizationId } = req.params; From ae5addaa27e4e0849f5e2506fdf1bc24895b2544 Mon Sep 17 00:00:00 2001 From: Mohamed Dawoud Date: Fri, 4 Apr 2025 18:08:02 +0200 Subject: [PATCH 4/5] refactor: organization routes docs --- src/routes/organization.routes.js | 607 ------------------------------ 1 file changed, 607 deletions(-) diff --git a/src/routes/organization.routes.js b/src/routes/organization.routes.js index 5d380bd..984d7c9 100644 --- a/src/routes/organization.routes.js +++ b/src/routes/organization.routes.js @@ -12,637 +12,30 @@ import { verifyAdminPermission } from '../middlewares/verifyAdminPermission.midd const router = Router(); -/** - * @swagger - * tags: - * name: Organization - * description: Organization management endpoints - */ - -/** - * @swagger - * components: - * securitySchemes: - * bearerAuth: - * type: http - * scheme: bearer - * bearerFormat: JWT - * schemas: - * CreateOrganizationRequest: - * type: object - * required: - * - name - * - contactEmail - * properties: - * name: - * type: string - * description: Name of the organization - * description: - * type: string - * description: Description of the organization - * industry: - * type: string - * description: Industry sector - * sizeRange: - * type: string - * description: Organization size (e.g., 1-10 employees) - * website: - * type: string - * format: uri - * description: Organization website URL - * logoUrl: - * type: string - * format: uri - * description: URL of the organization logo - * address: - * type: string - * description: Organization address - * contactEmail: - * type: string - * format: email - * description: Contact email for the organization - * contactPhone: - * type: string - * description: Contact phone number - * orgOwnerId: - * type: string - * description: ID of the organization owner (optional) - * CreateOrganizationResponse: - * type: object - * properties: - * success: - * type: boolean - * message: - * type: string - * data: - * type: object - * properties: - * organization: - * type: object - * properties: - * id: - * type: string - * name: - * type: string - * status: - * type: string - * isVerified: - * type: boolean - * organizationOwner: - * type: object - * properties: - * id: - * type: string - */ router.post('/api/organization', verifyAccessToken, createOrganization); - -/** - * @swagger - * /api/organization/verifyOrg: - * post: - * summary: Verify an organization's email using OTP - * tags: [Organization] - * security: - * - bearerAuth: [] - * requestBody: - * required: true - * content: - * application/json: - * schema: - * type: object - * required: - * - email - * - otp - * properties: - * email: - * type: string - * format: email - * description: Organization's registered contact email - * otp: - * type: string - * description: The OTP sent to the organization's email - * responses: - * 200: - * description: Organization verified successfully - * content: - * application/json: - * schema: - * type: object - * properties: - * message: - * type: string - * example: Organization verified successfully - * 400: - * description: Invalid or expired OTP - * 404: - * description: Organization not found - * 500: - * description: Server error - */ router.post( '/api/organization/verifyOrg', verifyAccessToken, verifyOrganization, ); - -/** - * @swagger - * /api/organization/all: - * get: - * summary: Retrieve all organizations with pagination, filtering, and sorting - * tags: [Organization] - * security: - * - bearerAuth: [] - * parameters: - * - in: query - * name: page - * schema: - * type: integer - * default: 1 - * description: Page number for pagination - * - in: query - * name: limit - * schema: - * type: integer - * default: 10 - * description: Number of organizations per page - * - in: query - * name: sortBy - * schema: - * type: string - * enum: [createdAt, name, industry, status] - * default: createdAt - * description: Field to sort by - * - in: query - * name: sortOrder - * schema: - * type: string - * enum: [asc, desc] - * default: desc - * description: Sorting order - * - in: query - * name: name - * schema: - * type: string - * description: Filter organizations by name (partial match) - * - in: query - * name: industry - * schema: - * type: string - * description: Filter organizations by industry - * - in: query - * name: sizeRange - * schema: - * type: string - * description: Filter organizations by size range - * - in: query - * name: status - * schema: - * type: string - * enum: [PENDING, APPROVED, REJECTED] - * description: Filter organizations by status - * - in: query - * name: isVerified - * schema: - * type: boolean - * description: Filter organizations by verification status - * responses: - * 200: - * description: Successfully retrieved organizations - * content: - * application/json: - * schema: - * type: object - * properties: - * success: - * type: boolean - * message: - * type: string - * data: - * type: object - * properties: - * organizations: - * type: array - * items: - * type: object - * properties: - * id: - * type: string - * name: - * type: string - * industry: - * type: string - * sizeRange: - * type: string - * status: - * type: string - * isVerified: - * type: boolean - * statistics: - * type: object - * properties: - * usersCount: - * type: integer - * departmentsCount: - * type: integer - * teamsCount: - * type: integer - * projectsCount: - * type: integer - * owners: - * type: array - * items: - * type: object - * properties: - * id: - * type: string - * name: - * type: string - * email: - * type: string - * pagination: - * type: object - * properties: - * total: - * type: integer - * page: - * type: integer - * limit: - * type: integer - * pages: - * type: integer - * 400: - * description: Invalid query parameters - * 401: - * description: Unauthorized - No token provided - * 403: - * description: Forbidden - Only admins can access this endpoint - * 500: - * description: Server error - */ router.get( '/api/organization/all', verifyAccessToken, verifyAdminPermission, getAllOrganizations, ); - -/** - * @swagger - * /api/organization/{organizationId}: - * get: - * summary: Retrieve details of a specific organization - * tags: [Organization] - * security: - * - bearerAuth: [] - * parameters: - * - in: path - * name: organizationId - * required: true - * schema: - * type: string - * description: The ID of the organization to retrieve - * responses: - * 200: - * description: Successfully retrieved organization details - * content: - * application/json: - * schema: - * type: object - * properties: - * success: - * type: boolean - * example: true - * message: - * type: string - * example: Organization retrieved successfully - * data: - * type: object - * properties: - * id: - * type: string - * name: - * type: string - * description: - * type: string - * industry: - * type: string - * sizeRange: - * type: string - * website: - * type: string - * logoUrl: - * type: string - * status: - * type: string - * enum: [PENDING, APPROVED, REJECTED] - * isVerified: - * type: boolean - * contactEmail: - * type: string - * contactPhone: - * type: string - * address: - * type: string - * createdAt: - * type: string - * format: date-time - * updatedAt: - * type: string - * format: date-time - * statistics: - * type: object - * properties: - * usersCount: - * type: integer - * departmentsCount: - * type: integer - * teamsCount: - * type: integer - * projectsCount: - * type: integer - * templatesCount: - * type: integer - * owners: - * type: array - * items: - * type: object - * properties: - * id: - * type: string - * name: - * type: string - * email: - * type: string - * profileImage: - * type: string - * departments: - * type: array - * items: - * type: object - * properties: - * id: - * type: string - * name: - * type: string - * description: - * type: string - * teamsCount: - * type: integer - * usersCount: - * type: integer - * teams: - * type: array - * items: - * type: object - * properties: - * id: - * type: string - * name: - * type: string - * description: - * type: string - * usersCount: - * type: integer - * projectsCount: - * type: integer - * projects: - * type: array - * items: - * type: object - * properties: - * id: - * type: string - * name: - * type: string - * description: - * type: string - * status: - * type: string - * enum: [ACTIVE, COMPLETED, ON_HOLD] - * startDate: - * type: string - * format: date-time - * endDate: - * type: string - * format: date-time - * hasMoreDepartments: - * type: boolean - * hasMoreTeams: - * type: boolean - * hasMoreProjects: - * type: boolean - * 400: - * description: Bad request - Missing or invalid organization ID - * 401: - * description: Unauthorized - No token provided - * 403: - * description: Forbidden - User does not have permission to view this organization - * 404: - * description: Not found - Organization not found - * 500: - * description: Server error - */ router.get( '/api/organization/:organizationId', verifyAccessToken, verifyAdminPermission, getSpecificOrganization, ); - -/** - * @swagger - * /api/organization/{organizationId}: - * put: - * summary: Update an organization's details - * tags: [Organization] - * security: - * - bearerAuth: [] - * parameters: - * - in: path - * name: organizationId - * required: true - * schema: - * type: string - * description: The ID of the organization to update - * requestBody: - * required: true - * content: - * application/json: - * schema: - * type: object - * properties: - * name: - * type: string - * example: "Tech Innovations Ltd." - * description: - * type: string - * example: "A leading software development company." - * industry: - * type: string - * example: "Technology" - * sizeRange: - * type: string - * example: "50-200" - * website: - * type: string - * example: "https://techinnovations.com" - * logoUrl: - * type: string - * example: "https://cdn.techinnovations.com/logo.png" - * status: - * type: string - * enum: [PENDING, APPROVED, REJECTED] - * example: "APPROVED" - * isVerified: - * type: boolean - * example: true - * contactEmail: - * type: string - * example: "contact@techinnovations.com" - * contactPhone: - * type: string - * example: "+1-234-567-890" - * address: - * type: string - * example: "123 Silicon Valley, CA, USA" - * responses: - * 200: - * description: Successfully updated the organization - * content: - * application/json: - * schema: - * type: object - * properties: - * success: - * type: boolean - * example: true - * message: - * type: string - * example: Organization updated successfully - * data: - * type: object - * properties: - * id: - * type: string - * name: - * type: string - * description: - * type: string - * industry: - * type: string - * sizeRange: - * type: string - * website: - * type: string - * logoUrl: - * type: string - * status: - * type: string - * isVerified: - * type: boolean - * contactEmail: - * type: string - * contactPhone: - * type: string - * address: - * type: string - * updatedAt: - * type: string - * format: date-time - * 400: - * description: Bad request - Validation error or missing required fields - * 401: - * description: Unauthorized - No token provided - * 403: - * description: Forbidden - User does not have permission to update the organization - * 404: - * description: Not found - Organization not found - * 409: - * description: Conflict - Organization with the same name already exists - * 500: - * description: Server error - */ router.put( '/api/organization/:organizationId', verifyAccessToken, verifyAdminPermission, updateOrganization, ); - -/** - * @swagger - * /api/organization/{organizationId}: - * delete: - * summary: Delete an organization - * description: Soft delete an organization by setting `deletedAt` and updating the status to `DELETED`. Only admins, owners, or the creator can perform this action. - * tags: - * - Organization - * security: - * - BearerAuth: [] - * parameters: - * - in: path - * name: organizationId - * required: true - * description: ID of the organization to delete - * schema: - * type: string - * responses: - * 200: - * description: Organization deleted successfully - * content: - * application/json: - * schema: - * type: object - * properties: - * success: - * type: boolean - * example: true - * message: - * type: string - * example: Organization deleted successfully - * 400: - * description: Missing or invalid organization ID - * content: - * application/json: - * schema: - * type: object - * properties: - * success: - * type: boolean - * example: false - * message: - * type: string - * example: Organization ID is required - * 403: - * description: Permission denied - * content: - * application/json: - * schema: - * type: object - * properties: - * success: - * type: boolean - * example: false - * message: - * type: string - * example: You do not have permission to delete this organization - * 404: - * description: Organization not found or already deleted - * content: - * application/json: - * schema: - * type: object - * properties: - * success: - * type: boolean - * example: false - * message: - * type: string - * example: Organization not found or already deleted - * 500: - * description: Internal server error - */ router.delete( '/api/organization/:organizationId', verifyAccessToken, From 9297c4c09bbfd4ec625785d73b530555e2b2d7f3 Mon Sep 17 00:00:00 2001 From: Mohamed Dawoud Date: Fri, 4 Apr 2025 18:09:40 +0200 Subject: [PATCH 5/5] fix: authorization header extracting --- src/middlewares/auth.middleware.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/middlewares/auth.middleware.js b/src/middlewares/auth.middleware.js index ffba2dd..ee46bb0 100644 --- a/src/middlewares/auth.middleware.js +++ b/src/middlewares/auth.middleware.js @@ -2,7 +2,7 @@ import jwt from 'jsonwebtoken'; export const verifyAccessToken = (req, res, next) => { // Extract token from "Bearer " format - const authHeader = req.headers.token; + const authHeader = req.headers.authorization; const token = authHeader && authHeader.split(' ')[1]; // ["Bearer", ""] if (!token) {