Skip to content

feat(admin): add assignRole method for validating user and role IDs#857

Merged
nevil-mathew merged 2 commits intodevelopfrom
add-tenant-admin-role
Oct 27, 2025
Merged

feat(admin): add assignRole method for validating user and role IDs#857
nevil-mathew merged 2 commits intodevelopfrom
add-tenant-admin-role

Conversation

@nevil-mathew
Copy link
Collaborator

@nevil-mathew nevil-mathew commented Oct 27, 2025

Summary by CodeRabbit

  • New Features
    • Added validation for role-assignment inputs, ensuring user and role identifiers are present and numeric before processing. This reduces invalid submissions and prevents downstream errors during role assignment operations.

@coderabbitai
Copy link

coderabbitai bot commented Oct 27, 2025

Walkthrough

Added a new public validator method assignRole(req) in src/validators/v1/admin.js that filters the request body and validates that user_id and role_id are present and numeric.

Changes

Cohort / File(s) Summary
New Admin Role Validator
src/validators/v1/admin.js
Added assignRole(req) method to validate role-assignment requests by filtering the request body and ensuring user_id and role_id are present and numeric.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

  • Single-file change with isolated validation logic.
  • Review attention: confirm validation uses existing filtering/utilities consistently and error messages match project conventions.

Poem

🐰 I hopped through code with careful pace,
To check each id in its place,
user_id, role_id — both must be true,
A tiny guard for what admins do. ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "feat(admin): add assignRole method for validating user and role IDs" directly corresponds to the main change in the pull request: adding a new public validator method assignRole(req) in the admin validators module. The title uses clear, specific language following conventional commit format (feat scope), accurately describes what was added, and the purpose is immediately apparent. It avoids vague terminology and noise, making it easy for reviewers scanning history to understand that a new role assignment validation method was introduced.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch add-tenant-admin-role

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4bcd72a and 681e22c.

📒 Files selected for processing (1)
  • src/validators/v1/admin.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/validators/**

⚙️ CodeRabbit configuration file

Validate all incoming data thoroughly. Check for missing or incomplete validation rules.

Files:

  • src/validators/v1/admin.js
🧬 Code graph analysis (1)
src/validators/v1/admin.js (2)
src/validators/v1/user-role.js (1)
  • filterRequestBody (1-1)
src/constants/blacklistConfig.js (1)
  • admin (136-208)
🔇 Additional comments (1)
src/validators/v1/admin.js (1)

188-198: Remove tenant-id header validation suggestion; improve ID validation instead.

The original review incorrectly suggests adding tenant-id header validation. The controller implementation shows that assignRole extracts tenant_code from req.decodedToken (JWT), not from headers—unlike other methods like addOrgAdmin and deactivateOrg.

However, the suggestion to use stricter ID validation is valid. Replace isNumeric() with isInt({ min: 1 }) to reject decimals and negative numbers:

		req.checkBody('user_id')
			.notEmpty()
			.withMessage('user_id field is empty')
-			.isNumeric()
-			.withMessage('user_id must be a number')
+			.isInt({ min: 1 })
+			.withMessage('user_id must be a positive integer')

		req.checkBody('role_id')
			.notEmpty()
			.withMessage('role_id field is empty')
-			.isNumeric()
-			.withMessage('role_id must be a number')
+			.isInt({ min: 1 })
+			.withMessage('role_id must be a positive integer')

Likely an incorrect or invalid review comment.

@nevil-mathew nevil-mathew merged commit c05e2df into develop Oct 27, 2025
0 of 2 checks passed
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/validators/v1/admin.js (1)

185-189: Consider adding .trim() for consistency.

For consistency with other validators in this file (e.g., lines 17, 25, 56, 84, 110), consider adding .trim() before validation. While numeric validation handles whitespace, explicit trimming makes the intent clearer and follows the established pattern.

 	assignRole: (req) => {
 		req.checkBody('user_id')
+			.trim()
 			.notEmpty()
 			.withMessage('user_id field is empty')
 			.isInt({ min: 1 })
 			.withMessage('user_id must be a positive integer')
 
 		req.checkBody('role_id')
+			.trim()
 			.notEmpty()
 			.withMessage('role_id field is empty')
 			.isInt({ min: 1 })
 			.withMessage('role_id must be a positive integer')
 	},

Also applies to: 191-195

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 681e22c and 03bc059.

📒 Files selected for processing (1)
  • src/validators/v1/admin.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/validators/**

⚙️ CodeRabbit configuration file

Validate all incoming data thoroughly. Check for missing or incomplete validation rules.

Files:

  • src/validators/v1/admin.js
🧠 Learnings (1)
📚 Learning: 2025-09-12T10:35:28.285Z
Learnt from: praveenKDass
PR: ELEVATE-Project/user#816
File: src/services/admin.js:704-704
Timestamp: 2025-09-12T10:35:28.285Z
Learning: In ELEVATE-Project/user admin.js, there's an inconsistency in organizationQueries.update usage: addOrgAdmin calls it without options (returns number), while deactivateOrg calls it with { returning: true, raw: true } (returns object). The validation logic 'if (orgRowsAffected === 0)' only works for the first case - the second case needs 'if (orgRowsAffected.rowsAffected === 0)' to properly validate updates.

Applied to files:

  • src/validators/v1/admin.js
🔇 Additional comments (1)
src/validators/v1/admin.js (1)

184-196: ****

The assignRole validator correctly omits tenant-id validation because the endpoint uses a different architectural pattern than addOrgAdmin. While addOrgAdmin explicitly accepts and passes the tenant-id header to the service (requiring validation), assignRole extracts tenant-id solely from the authenticated JWT token via req.decodedToken.tenant_code and never reads request headers for this value. Since tenant-id is not incoming data for assignRole, there is no validation needed in the validator—the tenant scope is already enforced through JWT verification at the middleware level.

Likely an incorrect or invalid review comment.

Comment on lines +184 to +196
assignRole: (req) => {
req.checkBody('user_id')
.notEmpty()
.withMessage('user_id field is empty')
.isNumeric()
.withMessage('user_id must be a number')

req.checkBody('role_id')
.notEmpty()
.withMessage('role_id field is empty')
.isNumeric()
.withMessage('role_id must be a number')
},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify that missing filterRequestBody doesn't introduce security risks.

Unlike other methods in this file (create, login, addOrgAdmin, deactivateUser), assignRole doesn't call filterRequestBody to sanitize the request body. While you mentioned that only IDs are used, it's important to verify that the controller and service layers don't inadvertently process additional fields, which could introduce security vulnerabilities.

Run the following script to verify that the controller only uses user_id and role_id from the request body:


🏁 Script executed:

#!/bin/bash
# Find the assignRole implementation and check what fields it accesses from req.body
rg -n -A20 "assignRole.*req.*res" --type=js -g '**/controllers/**/admin.js'

# Also check the service layer
rg -n -A20 "assignRole" --type=js -g '**/services/**/admin.js'

Length of output: 2492


Validate organization_id and add filterRequestBody call—critical validator completeness issue.

The service layer at line 112 extracts THREE fields from the request body: user_id, role_id, and organization_id. However, the validator only validates two. The organization_id is used directly in the service at line 125 to locate the organization within the user's organizations array and must be validated. Additionally, filterRequestBody is missing, which allows extra fields to pass through.

Add validation for organization_id (should be numeric and required) and call filterRequestBody after all validation checks, consistent with other methods in this file:

assignRole: (req) => {
	req.checkBody('user_id')
		.notEmpty()
		.withMessage('user_id field is empty')
		.isNumeric()
		.withMessage('user_id must be a number')

	req.checkBody('role_id')
		.notEmpty()
		.withMessage('role_id field is empty')
		.isNumeric()
		.withMessage('role_id must be a number')

	req.checkBody('organization_id')
		.notEmpty()
		.withMessage('organization_id field is empty')
		.isNumeric()
		.withMessage('organization_id must be a number')

	filterRequestBody(req, ['user_id', 'role_id', 'organization_id'])
},
🤖 Prompt for AI Agents
In src/validators/v1/admin.js around lines 184 to 196, the assignRole validator
only checks user_id and role_id but omits organization_id and does not call
filterRequestBody; add a req.checkBody('organization_id') block mirroring the
others (.notEmpty().withMessage('organization_id field is
empty').isNumeric().withMessage('organization_id must be a number')) and then
call filterRequestBody(req, ['user_id','role_id','organization_id']) after all
checks to ensure the body is validated and filtered.

Comment on lines +185 to +189
req.checkBody('user_id')
.notEmpty()
.withMessage('user_id field is empty')
.isNumeric()
.withMessage('user_id must be a number')
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Use .isInt() instead of .isNumeric() for ID validation.

Database IDs should be integers. The .isNumeric() validator accepts decimal strings like "1.5", which are invalid for ID fields. Use .isInt({ min: 1 }) to ensure both fields are positive integers.

Apply this diff to fix the validation:

 	assignRole: (req) => {
 		req.checkBody('user_id')
 			.notEmpty()
 			.withMessage('user_id field is empty')
-			.isNumeric()
-			.withMessage('user_id must be a number')
+			.isInt({ min: 1 })
+			.withMessage('user_id must be a positive integer')
 
 		req.checkBody('role_id')
 			.notEmpty()
 			.withMessage('role_id field is empty')
-			.isNumeric()
-			.withMessage('role_id must be a number')
+			.isInt({ min: 1 })
+			.withMessage('role_id must be a positive integer')
 	},

Also applies to: 191-195

🤖 Prompt for AI Agents
In src/validators/v1/admin.js around lines 185-189 (and similarly update lines
191-195), the validator uses .isNumeric() which allows decimals; change it to
.isInt({ min: 1 }) to ensure the user_id (and the other ID field at 191-195) are
positive integers, keeping the preceding .notEmpty() and updating the error
message to reflect "must be a positive integer" or similar.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant