Skip to content

Conversation

@5Amogh
Copy link
Member

@5Amogh 5Amogh commented Jun 4, 2025

πŸ“‹ Description

JIRA ID: AMM-1247

This feature is part of VAPT and includes captcha implementation, includes validators for login form.

βœ… Type of Change

  • 🐞 Bug fix (non-breaking change which resolves an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • πŸ”₯ Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • πŸ›  Refactor (change that is neither a fix nor a new feature)
  • βš™οΈ Config change (configuration file or build script updates)
  • πŸ“š Documentation (updates to docs or readme)
  • πŸ§ͺ Tests (adding new or updating existing tests)
  • 🎨 UI/UX (changes that affect the user interface)
  • πŸš€ Performance (improves performance)
  • 🧹 Chore (miscellaneous changes that don't modify src or test files)

Summary by CodeRabbit

  • New Features

    • Introduced CAPTCHA verification to the login process for enhanced security.
    • Added a CAPTCHA widget to the login form, requiring users to complete the challenge before logging in.
  • Enhancements

    • Login button is now disabled until both form fields are completed and CAPTCHA is solved.
    • Improved accessibility for login form elements.
  • Bug Fixes

    • Ensured the CAPTCHA widget resets after each login attempt or error.
  • Chores

    • Updated environment configuration to support CAPTCHA integration.

5Amogh added 2 commits May 30, 2025 12:44
…lity added, env injection for captcha script and sitekey; login form validation
@coderabbitai
Copy link

coderabbitai bot commented Jun 4, 2025

Walkthrough

A CAPTCHA challenge has been integrated into the login flow. This includes a new CAPTCHA component and service, updates to the login component and service to handle the CAPTCHA token, environment variable additions for CAPTCHA configuration, and template and style changes to support and enforce CAPTCHA validation during authentication.

Changes

File(s) Change Summary
scripts/ci-prebuild.js Added SITE_KEY, CAPTCHA_CHALLENGE_URL, and ENABLE_CAPTCHA to default environment values.
src/environments/environment.ci.ts.template, src/environments/environment.local.ts Added siteKey, captchaChallengeURL, and enableCaptcha properties to environment configuration.
src/app/app.module.ts Imported and declared CaptchaComponent, provided CaptchaService.
src/app/captcha/captcha.component.ts, src/app/captcha/captcha.component.html Added new CaptchaComponent with template container for CAPTCHA widget.
src/app/services/captcha-service/captcha.service.ts Introduced CaptchaService to dynamically load CAPTCHA script.
src/app/login/login.component.ts Integrated CAPTCHA into login logic: added token handling, reset method, and component reference.
src/app/login/login.html Updated login form: added required fields, conditional CAPTCHA component, and button disable logic.
src/app/login/login.component.css Added .sr-only for accessibility and .disabledLoginButton for disabled button styling.
src/app/services/loginService/login.service.ts Modified authenticateUser to accept and send optional captchaToken in authentication payload.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant LoginComponent
    participant CaptchaComponent
    participant CaptchaService
    participant LoginService
    participant Backend

    User->>LoginComponent: Enter username & password
    LoginComponent->>CaptchaComponent: Render CAPTCHA
    CaptchaComponent->>CaptchaService: Load CAPTCHA script
    CaptchaService-->>CaptchaComponent: Script loaded
    User->>CaptchaComponent: Solve CAPTCHA
    CaptchaComponent->>LoginComponent: Emit tokenResolved(token)
    LoginComponent->>LoginService: authenticateUser(username, password, doLogout, captchaToken)
    LoginService->>Backend: POST /user/userAuthenticate {username, password, doLogout, captchaToken}
    Backend-->>LoginService: Authentication response
    LoginService-->>LoginComponent: Response
    LoginComponent->>CaptchaComponent: reset() (on success or error)
Loading

Possibly related PRs

  • Ci setupΒ #30: Extended environment configuration files and CI prebuild script by adding CAPTCHA-related environment variables, related to environment setup and CI file generation for CAPTCHA integration.

Poem

πŸ‡βœ¨
A bunny hopped onto the login page,
With a CAPTCHA to foil the bot’s rampage.
A token is earned with a click and a hop,
Now only real users can make it to the top!
With scripts and styles, the code’s secureβ€”
The login flow is safer, that’s for sure!
πŸ”’πŸ°


πŸ“œ Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between fd04054 and 6a422ac.

πŸ“’ Files selected for processing (1)
  • src/app/login/login.component.ts (9 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/app/login/login.component.ts
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: package
  • GitHub Check: Analyze (javascript)
  • GitHub Check: Build
✨ Finishing Touches
  • πŸ“ Generate Docstrings

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
πŸͺ§ 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @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.

@coderabbitai
Copy link

coderabbitai bot commented Jun 4, 2025

Caution

No docstrings were generated.

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

πŸ”­ Outside diff range comments (1)
src/app/login/login.component.ts (1)

207-223: πŸ› οΈ Refactor suggestion

Add CAPTCHA token validation before authentication.

The login method should validate that a CAPTCHA token exists before attempting authentication for security compliance.

  login(doLogOut) {
+   if (!this.captchaToken) {
+     this.alertMessage.alert('Please complete the CAPTCHA verification', 'error');
+     return;
+   }
    
    this.encryptpassword = this.encrypt(this.Key_IV, this.password);
    this.loginservice
      .authenticateUser(this.userID, this.encryptpassword, doLogOut, this.captchaToken)
      .subscribe(
        (response: any) => {
          console.error("response",response);
          if (
            response !== undefined &&
            response !== null &&
            response.previlegeObj !== undefined &&
            response.previlegeObj !== null
          ) {
            this.successCallback(response);
          }
        },
        (error: any) => this.errorCallback(error)
      );
-     this.resetCaptcha();
  }
🧹 Nitpick comments (8)
src/environments/environment.ci.ts.template (1)

47-48: Fix spacing consistency in environment object.

There's a missing space after the colon in the siteKey property assignment, which is inconsistent with the formatting style used elsewhere in the file.

Apply this diff to maintain consistent formatting:

-  siteKey:siteKey,
+  siteKey: siteKey,
src/environments/environment.local.ts (1)

52-53: Fix spacing consistency and consider local development implications.

There's a spacing inconsistency in the property definitions. Also, consider that empty CAPTCHA configuration values may cause the CAPTCHA feature to not function in local development.

Apply this diff to maintain consistent formatting:

-  siteKey:siteKey,
-  captchaChallengeURL:captchaChallengeURL
+  siteKey: siteKey,
+  captchaChallengeURL: captchaChallengeURL

Consider documenting in comments or README how to configure CAPTCHA for local development testing.

scripts/ci-prebuild.js (1)

50-51:

Details

❓ Verification inconclusive

Fix formatting and verify secure CAPTCHA configuration in deployment.

The CAPTCHA environment variables are correctly added to support the template rendering process. However, there's a spacing inconsistency, and it's important to ensure proper CAPTCHA configuration in production deployments.

Apply this diff for consistent formatting:

-  SITE_KEY:'',
-  CAPTCHA_CHALLENGE_URL:''
+  SITE_KEY: '',
+  CAPTCHA_CHALLENGE_URL: ''

Please verify that:

  1. The CAPTCHA service (likely Cloudflare Turnstile) is properly configured in production
  2. The SITE_KEY and CAPTCHA_CHALLENGE_URL are securely managed and not exposed in logs
  3. Fallback behavior is implemented when CAPTCHA service is unavailable

🏁 Script executed:

#!/bin/bash
# Description: Check for CAPTCHA-related security considerations in the codebase

# Search for any hardcoded CAPTCHA keys or URLs that might be a security risk
echo "Searching for potential hardcoded CAPTCHA credentials..."
rg -i "turnstile|captcha" --type ts --type js -A 3 -B 3

# Check for proper error handling in CAPTCHA implementation
echo "Checking for CAPTCHA error handling..."
ast-grep --pattern 'catch ($err) { $$$ }' | head -10

Length of output: 13940


Apply consistent formatting and confirm secure CAPTCHA deployment

Formatting of the new environment variables should be updated for consistency, and please verify that CAPTCHA keys are securely managed in your CI/CD and production environments.

β€’ scripts/ci-prebuild.js

-  SITE_KEY:'',
-  CAPTCHA_CHALLENGE_URL:''
+  SITE_KEY: '',
+  CAPTCHA_CHALLENGE_URL: ''

β€’ Verify that:

  1. No CAPTCHA keys or URLs are hardcoded (CI prebuild defaults to empty strings).
  2. SITE_KEY and CAPTCHA_CHALLENGE_URL are injected from a secure secrets store in CI/CD and never logged.
  3. The application gracefully handles CAPTCHA service failures (fallback path or user messaging).
src/app/services/loginService/login.service.ts (1)

60-60: Add spacing around the captchaToken parameter.

While the CAPTCHA token integration is correct, improve readability by adding proper spacing.

Apply this formatting improvement:

-  public authenticateUser(uname, pwd, doLogout,captchaToken) {
+  public authenticateUser(uname, pwd, doLogout, captchaToken) {
src/app/captcha/captcha.component.ts (1)

49-53: Add defensive check for turnstile.remove method.

The cleanup logic assumes turnstile.remove exists but checks for it. Consider more robust error handling.

  ngOnDestroy() {
-   if (this.widgetId && typeof turnstile !== 'undefined' && turnstile.remove) {
-     turnstile.remove(this.widgetId);
+   if (this.widgetId && typeof turnstile !== 'undefined') {
+     try {
+       if (typeof turnstile.remove === 'function') {
+         turnstile.remove(this.widgetId);
+       }
+     } catch (error) {
+       console.warn('Failed to remove CAPTCHA widget:', error);
+     }
    }
+   this.widgetId = null;
  }
src/app/services/captcha-service/captcha.service.ts (1)

4-4: Consider using providedIn for better tree-shaking.

The service should use providedIn: 'root' for better Angular dependency injection and tree-shaking optimization.

-@Injectable()
+@Injectable({
+  providedIn: 'root'
+})
src/app/login/login.component.ts (2)

57-57: Initialize captchaToken property.

The property should be initialized to prevent undefined access and improve type safety.

-captchaToken: string;
+captchaToken: string = '';

383-385: Add input validation for CAPTCHA token.

The token handler should validate the token format for additional security.

  onCaptchaResolved(token: string) {
+   if (!token || typeof token !== 'string' || token.trim().length === 0) {
+     console.warn('Invalid CAPTCHA token received');
+     return;
+   }
    this.captchaToken = token;
  }
πŸ“œ Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 3b4491d and 263b7aa.

πŸ“’ Files selected for processing (11)
  • scripts/ci-prebuild.js (1 hunks)
  • src/app/app.module.ts (3 hunks)
  • src/app/captcha/captcha.component.html (1 hunks)
  • src/app/captcha/captcha.component.ts (1 hunks)
  • src/app/login/login.component.css (1 hunks)
  • src/app/login/login.component.ts (9 hunks)
  • src/app/login/login.html (2 hunks)
  • src/app/services/captcha-service/captcha.service.ts (1 hunks)
  • src/app/services/loginService/login.service.ts (1 hunks)
  • src/environments/environment.ci.ts.template (2 hunks)
  • src/environments/environment.local.ts (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/app/captcha/captcha.component.ts (2)
src/app/login/login.component.ts (1)
  • Component (36-416)
src/environments/environment.local.ts (1)
  • environment (41-54)
src/app/services/captcha-service/captcha.service.ts (1)
src/environments/environment.local.ts (1)
  • environment (41-54)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: Build
  • GitHub Check: package
πŸ”‡ Additional comments (13)
src/environments/environment.ci.ts.template (1)

33-34: LGTM! Proper template variable setup.

The CAPTCHA configuration constants are correctly implemented using EJS template placeholders, following the established pattern in this environment template file.

src/app/captcha/captcha.component.html (1)

1-1: LGTM! Clean CAPTCHA container implementation.

The template correctly provides a container for the Cloudflare Turnstile CAPTCHA widget with appropriate ID and template reference. The implementation is minimal and focused, which is ideal for a CAPTCHA component.

src/environments/environment.local.ts (1)

38-39: LGTM! Appropriate local development configuration.

The CAPTCHA configuration constants are properly initialized with empty strings for local development, which is a reasonable default for development environments where CAPTCHA might not be required.

src/app/login/login.html (4)

16-16: Good addition of form validation.

The required attribute enforces mandatory username input, improving form validation.


26-26: Good addition of form validation.

The required attribute enforces mandatory password input, completing the basic form validation requirements.


31-34: Excellent accessibility implementation for CAPTCHA.

The CAPTCHA integration includes proper accessibility features:

  • ARIA role="group" and aria-labelledby for semantic grouping
  • Screen reader-only label with sr-only class
  • Centered styling for visual alignment

This implementation follows WCAG guidelines for accessibility compliance.


37-37: Secure implementation of conditional login button.

The login button is properly disabled until both CAPTCHA token is present and form is valid, preventing submission without completing security verification. The disabledLoginButton class provides visual feedback for the disabled state.

src/app/app.module.ts (3)

285-286: Properly organized imports for CAPTCHA functionality.

The CAPTCHA service and component imports are correctly placed and follow the existing import organization pattern in the module.


323-323: Correct component declaration.

The CaptchaComponent is properly added to the declarations array, enabling its use throughout the application.


494-494: Proper service registration.

The CaptchaService is correctly added to the providers array, making it available for dependency injection throughout the application.

src/app/login/login.component.css (2)

95-106: Excellent accessibility implementation with sr-only class.

The .sr-only class follows the standard pattern for screen reader-only content, using proper CSS properties to hide content visually while maintaining accessibility. This is essential for the CAPTCHA label accessibility.


109-114: Good visual feedback for disabled login button.

The .disabledLoginButton class provides clear visual indication of the disabled state with:

  • Muted gray background and text colors
  • not-allowed cursor for user feedback
  • Removed box shadow for flat appearance
  • !important declarations ensure style precedence

This enhances user experience by clearly indicating when the button cannot be clicked.

src/app/services/loginService/login.service.ts (1)

67-67: Secure integration of CAPTCHA token in authentication payload.

The CAPTCHA token is properly included in the authentication request payload, enabling server-side verification of the CAPTCHA challenge. This strengthens the security of the login process as required for VAPT compliance.

import { CaptchaService } from '../services/captcha-service/captcha.service';
import { environment } from 'environments/environment';

declare const turnstile: any;
Copy link

Choose a reason for hiding this comment

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

πŸ› οΈ Refactor suggestion

Add proper type definitions for turnstile.

The global turnstile declaration lacks type safety. Consider creating proper TypeScript interfaces or installing official types if available.

-declare const turnstile: any;
+interface TurnstileWidget {
+  render(element: HTMLElement, options: {
+    sitekey: string;
+    theme?: string;
+    callback?: (token: string) => void;
+  }): string;
+  reset(widgetId: string): void;
+  remove?(widgetId: string): void;
+}
+
+declare const turnstile: TurnstileWidget;
πŸ€– Prompt for AI Agents
In src/app/captcha/captcha.component.ts at line 5, replace the generic 'any'
type declaration for the global 'turnstile' variable with a proper TypeScript
interface or type definition. If official type definitions for 'turnstile'
exist, install and use them; otherwise, define an interface that accurately
describes the properties and methods used from 'turnstile' to ensure type safety
and improve code maintainability.

Comment on lines +8 to +30
loadScript(): Promise<void> {
return new Promise((resolve, reject) => {
if (this.scriptLoaded) return resolve();

const script = document.createElement('script');
script.src = environment.captchaChallengeURL;
script.async = true;
script.defer = true;
script.onload = () => {
this.scriptLoaded = true;
resolve();
};
script.onerror = (event) => {
this.scriptLoaded = false;
reject(
new Error(
`Failed to load CAPTCHA script from ${environment.captchaChallengeURL}: ${event}`,
),
);
};
document.head.appendChild(script);
});
}
Copy link

Choose a reason for hiding this comment

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

πŸ› οΈ Refactor suggestion

Add race condition protection and environment validation.

The current implementation has potential race conditions and missing validation that could cause issues in production.

+private loadingPromise: Promise<void> | null = null;

  loadScript(): Promise<void> {
+   // Return existing promise if script is already being loaded
+   if (this.loadingPromise) {
+     return this.loadingPromise;
+   }
+
+   if (this.scriptLoaded) return Promise.resolve();
+
+   if (!environment.captchaChallengeURL) {
+     return Promise.reject(new Error('CAPTCHA challenge URL is not configured'));
+   }
+
+   this.loadingPromise = new Promise((resolve, reject) => {
-    return new Promise((resolve, reject) => {
-      if (this.scriptLoaded) return resolve();

      const script = document.createElement('script');
      script.src = environment.captchaChallengeURL;
      script.async = true;
      script.defer = true;
      script.onload = () => {
        this.scriptLoaded = true;
+       this.loadingPromise = null;
        resolve();
      };
      script.onerror = (event) => {
        this.scriptLoaded = false;
+       this.loadingPromise = null;
        reject(
          new Error(
            `Failed to load CAPTCHA script from ${environment.captchaChallengeURL}: ${event}`,
          ),
        );
      };
      document.head.appendChild(script);
    });
+
+   return this.loadingPromise;
  }
πŸ€– Prompt for AI Agents
In src/app/services/captcha-service/captcha.service.ts around lines 8 to 30, the
loadScript method lacks protection against race conditions and does not validate
the environment variable. To fix this, add a mechanism to queue or block
multiple simultaneous calls to loadScript until the script is fully loaded,
preventing concurrent script insertions. Also, validate that
environment.captchaChallengeURL is defined and a valid URL before attempting to
load the script, and handle the case where it is missing or invalid by rejecting
the promise early with a clear error.

Comment on lines 387 to 392
resetCaptcha() {
if (this.captchaCmp && typeof this.captchaCmp.reset === 'function') {
this.captchaCmp.reset();
this.captchaToken = '';
}
}
Copy link

Choose a reason for hiding this comment

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

πŸ› οΈ Refactor suggestion

Improve CAPTCHA reset method with proper error handling.

The reset method should include better error handling and null checking.

  resetCaptcha() {
-   if (this.captchaCmp && typeof this.captchaCmp.reset === 'function') {
+   try {
+     if (this.captchaCmp && typeof this.captchaCmp.reset === 'function') {
        this.captchaCmp.reset();
-       this.captchaToken = '';
+     }
+   } catch (error) {
+     console.warn('Failed to reset CAPTCHA:', error);
+   } finally {
+     this.captchaToken = '';
    }
  }
πŸ“ 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
resetCaptcha() {
if (this.captchaCmp && typeof this.captchaCmp.reset === 'function') {
this.captchaCmp.reset();
this.captchaToken = '';
}
}
resetCaptcha() {
try {
if (this.captchaCmp && typeof this.captchaCmp.reset === 'function') {
this.captchaCmp.reset();
}
} catch (error) {
console.warn('Failed to reset CAPTCHA:', error);
} finally {
this.captchaToken = '';
}
}
πŸ€– Prompt for AI Agents
In src/app/login/login.component.ts around lines 387 to 392, the resetCaptcha
method lacks robust error handling and null checks. Enhance the method by adding
explicit null or undefined checks for this.captchaCmp before calling reset, and
wrap the reset call in a try-catch block to handle any potential errors
gracefully. Also ensure that this.captchaToken is reset only if the reset call
succeeds without exceptions.

@5Amogh 5Amogh requested a review from snehar-nd June 10, 2025 11:47
@5Amogh 5Amogh merged commit 10354c2 into develop Jun 10, 2025
2 of 4 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Jun 15, 2025
1 task
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.

3 participants