Skip to content

Add validation for phone number and PAN card on contribution form#447

Merged
pokhiii merged 5 commits intodevelopfrom
add-validation-on-contribution
Dec 11, 2024
Merged

Add validation for phone number and PAN card on contribution form#447
pokhiii merged 5 commits intodevelopfrom
add-validation-on-contribution

Conversation

@tarunnjoshi
Copy link
Copy Markdown
Member

@tarunnjoshi tarunnjoshi commented Nov 13, 2024

Add validation for phone number and PAN card on contribution form

Summary by CodeRabbit

  • New Features

    • Introduced user input validation for mobile numbers and PAN card numbers on the contribution form.
    • Added error messages for invalid input formats to enhance user experience during form submission.
    • Implemented a reset button functionality with a delay to prevent immediate action.
  • Bug Fixes

    • Ensured existing message display functionality remains unaffected by the new validation logic.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Nov 13, 2024

Walkthrough

The changes introduce a consolidated event listener for the DOMContentLoaded event in the JavaScript file. This listener now triggers three functions: handleUrlMessages(), handleFormReset(), and setupFormValidation(). The handleUrlMessages() function processes URL parameters for message display, while handleFormReset() manages form reset functionality with a delay. The setupFormValidation() function implements validation for mobile numbers and PAN card numbers, utilizing regular expressions to ensure proper input formats before form submission.

Changes

Files Change Summary
wp-content/themes/goonj-crm/main.js Consolidated event listener for DOMContentLoaded; added functions for URL message handling, form reset, and input validation for mobile and PAN card numbers.

Possibly related PRs

Suggested reviewers

  • nishant22029

🎉 In the realm of forms, validation takes flight,
Mobile and PAN, ensuring inputs are right.
With regex in hand, errors are caught,
Submissions are safe, no worries, no fraught!
So here’s to the code, a neat little dance,
Making forms better, giving users a chance! 🎉


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between e77f846 and 74a9fed.

📒 Files selected for processing (1)
  • wp-content/themes/goonj-crm/main.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • wp-content/themes/goonj-crm/main.js

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Experiment)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown

@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: 4

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between c3f4623 and aae43f4.

📒 Files selected for processing (1)
  • wp-content/themes/goonj-crm/main.js (1 hunks)

Comment on lines +71 to +82
const fields = [
{
labelText: "Mobile Number",
regex: /^\d{10}$/,
errorMessage: "Please enter a valid 10-digit mobile number.",
},
{
labelText: "Enter PAN Card Number",
regex: /^[A-Z]{5}[0-9]{4}[A-Z]$/,
errorMessage: "Please enter a valid PAN card number in the format ABCDE1234F.",
}
];
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider improving validation configuration maintainability and security

The current implementation has several areas for improvement:

  1. The regex patterns lack documentation explaining their rules
  2. Validation rules are hardcoded in JS, making them difficult to maintain
  3. Missing input sanitization before validation

Consider this improved structure:

 const fields = [
   {
     labelText: "Mobile Number",
+    // Matches exactly 10 digits, no spaces or special characters
     regex: /^\d{10}$/,
     errorMessage: "Please enter a valid 10-digit mobile number.",
+    sanitize: (value) => value.replace(/\D/g, ''), // Remove non-digits
   },
   {
     labelText: "Enter PAN Card Number",
+    // Format: 5 uppercase letters + 4 digits + 1 uppercase letter
     regex: /^[A-Z]{5}[0-9]{4}[A-Z]$/,
     errorMessage: "Please enter a valid PAN card number in the format ABCDE1234F.",
+    sanitize: (value) => value.toUpperCase().replace(/[^A-Z0-9]/g, ''), // Convert to uppercase and remove special chars
   }
 ];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const fields = [
{
labelText: "Mobile Number",
regex: /^\d{10}$/,
errorMessage: "Please enter a valid 10-digit mobile number.",
},
{
labelText: "Enter PAN Card Number",
regex: /^[A-Z]{5}[0-9]{4}[A-Z]$/,
errorMessage: "Please enter a valid PAN card number in the format ABCDE1234F.",
}
];
const fields = [
{
labelText: "Mobile Number",
// Matches exactly 10 digits, no spaces or special characters
regex: /^\d{10}$/,
errorMessage: "Please enter a valid 10-digit mobile number.",
sanitize: (value) => value.replace(/\D/g, ''), // Remove non-digits
},
{
labelText: "Enter PAN Card Number",
// Format: 5 uppercase letters + 4 digits + 1 uppercase letter
regex: /^[A-Z]{5}[0-9]{4}[A-Z]$/,
errorMessage: "Please enter a valid PAN card number in the format ABCDE1234F.",
sanitize: (value) => value.toUpperCase().replace(/[^A-Z0-9]/g, ''), // Convert to uppercase and remove special chars
}
];

Comment thread wp-content/themes/goonj-crm/main.js Outdated
Comment on lines +93 to +106
// Attach validation on form submission
if (form) {
form.addEventListener("submit", function (event) {
const value = input.value;
if (!field.regex.test(value)) {
event.preventDefault();
alert(field.errorMessage);
input.focus();
}
});
}
}
}
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Enhance validation UX and event handling

The current validation implementation has several UX and technical issues:

  1. Using alert() for error messages provides poor user experience
  2. No real-time validation feedback
  3. Multiple event listeners could be attached to the same form
  4. No cleanup of event listeners

Consider this improved implementation:

-if (form) {
-  form.addEventListener("submit", function (event) {
-    const value = input.value;
-    if (!field.regex.test(value)) {
-      event.preventDefault();
-      alert(field.errorMessage);
-      input.focus();
-    }
-  });
-}

+// Create error message element
+const errorSpan = document.createElement('span');
+errorSpan.className = 'error-message';
+errorSpan.style.color = 'red';
+errorSpan.style.display = 'none';
+input.parentNode.insertBefore(errorSpan, input.nextSibling);
+
+// Real-time validation
+input.addEventListener('input', validateField);
+
+// Form submission validation
+if (!form.hasAttribute('data-validation-attached')) {
+  form.setAttribute('data-validation-attached', 'true');
+  form.addEventListener('submit', function(event) {
+    const isValid = Array.from(form.querySelectorAll('input'))
+      .every(input => !input.getAttribute('aria-invalid'));
+    
+    if (!isValid) {
+      event.preventDefault();
+      form.querySelector('[aria-invalid="true"]')?.focus();
+    }
+  });
+}
+
+function validateField() {
+  const value = field.sanitize ? field.sanitize(input.value) : input.value;
+  const isValid = field.regex.test(value);
+  
+  input.setAttribute('aria-invalid', !isValid);
+  errorSpan.textContent = isValid ? '' : field.errorMessage;
+  errorSpan.style.display = isValid ? 'none' : 'block';
+}

This implementation provides:

  • Immediate visual feedback
  • Accessible error messages
  • Input sanitization
  • Prevention of duplicate event listeners

Consider moving the validation logic to a separate module for better maintainability.

Committable suggestion skipped: line range outside the PR's diff.

Comment thread wp-content/themes/goonj-crm/main.js Outdated
Comment on lines +84 to +92
fields.forEach(field => {
// Select the label by labelText and find the associated input
const label = Array.from(document.querySelectorAll("label")).find(el => el.textContent.includes(field.labelText));
if (label) {
const input = document.querySelector(`input[name="${label.getAttribute("for")}"]`);

if (input) {
const form = input.closest("form");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve field selection robustness and performance

The current field selection approach has potential issues:

  1. Inefficient DOM traversal using Array.from and find
  2. No error handling for missing form elements
  3. Possible race conditions with dynamically loaded forms

Consider this more robust approach:

-fields.forEach(field => {
-  const label = Array.from(document.querySelectorAll("label")).find(el => el.textContent.includes(field.labelText));
-  if (label) {
-    const input = document.querySelector(`input[name="${label.getAttribute("for")}"]`);
-
-    if (input) {
-      const form = input.closest("form");

+fields.forEach(field => {
+  // More efficient selector
+  const label = document.querySelector(`label:contains("${field.labelText}")`);
+  if (!label) {
+    console.warn(`Validation field "${field.labelText}" not found in the form`);
+    return;
+  }
+
+  const input = document.getElementById(label.getAttribute("for"));
+  if (!input) {
+    console.warn(`Input for "${field.labelText}" not found`);
+    return;
+  }
+
+  const form = input.closest("form");
+  if (!form) {
+    console.warn(`Form not found for "${field.labelText}"`);
+    return;
+  }

Committable suggestion skipped: line range outside the PR's diff.

Comment thread wp-content/themes/goonj-crm/main.js Outdated
Comment on lines +67 to +107
// Add validation for the phone number and PAN card on contribution form.

document.addEventListener("DOMContentLoaded", function () {
// Define validation configurations for each field
const fields = [
{
labelText: "Mobile Number",
regex: /^\d{10}$/,
errorMessage: "Please enter a valid 10-digit mobile number.",
},
{
labelText: "Enter PAN Card Number",
regex: /^[A-Z]{5}[0-9]{4}[A-Z]$/,
errorMessage: "Please enter a valid PAN card number in the format ABCDE1234F.",
}
];

fields.forEach(field => {
// Select the label by labelText and find the associated input
const label = Array.from(document.querySelectorAll("label")).find(el => el.textContent.includes(field.labelText));
if (label) {
const input = document.querySelector(`input[name="${label.getAttribute("for")}"]`);

if (input) {
const form = input.closest("form");

// Attach validation on form submission
if (form) {
form.addEventListener("submit", function (event) {
const value = input.value;
if (!field.regex.test(value)) {
event.preventDefault();
alert(field.errorMessage);
input.focus();
}
});
}
}
}
});
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codebase verification

Server-side validation is missing for sensitive data

The current implementation only includes client-side validation for PAN card and mobile numbers. While the client-side validation is well-structured, it's insufficient for sensitive data like PAN numbers. Here's what needs attention:

  • No server-side validation found in the codebase for PAN card numbers
  • Form submission endpoints are not implementing any validation checks
  • Relying solely on client-side JavaScript validation which can be bypassed

The code should be enhanced with proper server-side validation before accepting these sensitive fields.

🔗 Analysis chain

Verify server-side validation implementation

While client-side validation is implemented, it's crucial to ensure proper server-side validation exists for these sensitive fields.


Let me search for the server-side form handling code to verify if proper validation exists.


Let me check for any server-side form processing code that might handle these validations.


Let me check the validation.js file and any related server-side processing code.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for server-side validation of mobile and PAN card numbers

# Look for validation in PHP files
echo "Searching for server-side validation..."
rg -t php "(mobile|phone|pan|PAN).*valid" ./wp-content

# Look for form processing endpoints
echo "Searching for form processing endpoints..."
rg -t php "contribution.*form" ./wp-content

Length of output: 31124


Script:

#!/bin/bash
# Search for form handling code in PHP files
echo "Searching for form handling code..."
rg -t php "material.*contribution.*form" ./wp-content/themes/goonj-crm --context 10

# Search for validation related code
echo "Searching for validation related code..."
rg -t php "(mobile|phone|pan).*valid" ./wp-content/themes/goonj-crm

Length of output: 2386


Script:

#!/bin/bash
# Search for form processing endpoints and validation logic
echo "Searching for form processing endpoints..."
rg -t php "add_action.*wp_ajax" ./wp-content/themes/goonj-crm/functions.php -A 10

# Look for any validation functions
echo "Searching for validation functions..."
rg -t php "function.*valid" ./wp-content/themes/goonj-crm

# Check if there's a dedicated validation file
echo "Checking for validation files..."
fd validation ./wp-content/themes/goonj-crm

Length of output: 589


Script:

#!/bin/bash
# Check the validation.js file content
echo "Checking validation.js content..."
cat ./wp-content/themes/goonj-crm/validation.js

# Look for form submission handling
echo "Searching for form submission handling..."
rg -t php "handle.*form.*submit" ./wp-content/themes/goonj-crm

# Check for any AJAX endpoints that might handle the form
echo "Searching for AJAX handlers..."
rg -t php "wp_ajax_(nopriv_)?(material|contribution)" ./wp-content/themes/goonj-crm

Length of output: 2052

Copy link
Copy Markdown

@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: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between aae43f4 and e77f846.

📒 Files selected for processing (1)
  • wp-content/themes/goonj-crm/main.js (1 hunks)
🔇 Additional comments (2)
wp-content/themes/goonj-crm/main.js (2)

69-82: Enhance validation configuration with sanitization and documentation

The validation configuration needs improvement in several areas:

  1. Add documentation for regex patterns
  2. Implement input sanitization
  3. Consider moving validation rules to a configuration file

This issue was previously identified. Please refer to the earlier review comment for the detailed implementation suggestion that includes input sanitization and improved documentation.


84-106: ⚠️ Potential issue

Improve field selection and validation implementation

Previous review comments have already addressed the technical improvements needed for:

  1. More efficient field selection
  2. Better error handling
  3. Prevention of duplicate event listeners
  4. Real-time validation

Please refer to the earlier review comments for detailed implementation suggestions.

Additionally, there's a security concern:

  • The current client-side-only validation can be easily bypassed
  • Sensitive data like PAN numbers require server-side validation

Let's verify if there's any server-side validation:

#!/bin/bash
# Search for server-side validation in PHP files
echo "Checking for PAN and mobile validation in server-side code..."
rg -t php "(pan|mobile|phone).*valid" ./wp-content

# Look for form submission handlers
echo "Checking form submission handlers..."
rg -t php "add_action.*wp_ajax.*contribution" ./wp-content

Comment thread wp-content/themes/goonj-crm/main.js Outdated
Comment on lines +66 to +107

// Add validation for the phone number and PAN card on contribution form.

document.addEventListener("DOMContentLoaded", function () {
// Define validation configurations for each field
const fields = [
{
labelText: "Mobile Number",
regex: /^\d{10}$/,
errorMessage: "Please enter a valid 10-digit mobile number.",
},
{
labelText: "PAN Card Number",
regex: /^[A-Z]{5}[0-9]{4}[A-Z]$/,
errorMessage: "Please enter a valid PAN card number in the format ABCDE1234F.",
}
];

fields.forEach(field => {
// Select the label by labelText and find the associated input
const label = Array.from(document.querySelectorAll("label")).find(el => el.textContent.includes(field.labelText));
if (label) {
const input = document.querySelector(`input[name="${label.getAttribute("for")}"]`);

if (input) {
const form = input.closest("form");

// Attach validation on form submission
if (form) {
form.addEventListener("submit", function (event) {
const value = input.value;
if (!field.regex.test(value)) {
event.preventDefault();
alert(field.errorMessage);
input.focus();
}
});
}
}
}
});
});
Copy link
Copy Markdown

@coderabbitai coderabbitai bot Dec 10, 2024

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consolidate event listeners and track temporary solutions

The file structure needs improvement:

  1. Multiple DOMContentLoaded event listeners should be consolidated into a single listener
  2. The temporary form reset solution needs proper tracking

Consider this structure:

 document.addEventListener('DOMContentLoaded', function() {
+  // Message handling
   handleUrlMessages();
+  
+  // Form reset handling
   handleFormReset();
+  
+  // Form validation
   setupFormValidation();
 });
 
+// TODO: Replace with proper form reset solution
+// Issue: #<create-tracking-issue>
 function handleFormReset() {
   // ... reset logic ...
 }

Would you like me to create a tracking issue for replacing the temporary form reset solution?

Committable suggestion skipped: line range outside the PR's diff.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@tarunnjoshi this is a good suggestion which i think we should implement before it's too late

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Copy link
Copy Markdown
Member

@pokhiii pokhiii left a comment

Choose a reason for hiding this comment

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

I am just echoing one of the suggestions given by coderabbit regarding refactoring

@pokhiii pokhiii merged commit a506eaa into develop Dec 11, 2024
@pokhiii pokhiii deleted the add-validation-on-contribution branch December 11, 2024 05:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants