Skip to content

ChangePasswordController

Epic, User Stories, and Tasks

Epic: User Password Management

  • As a Salesforce user,
  • I want to securely change my password,
  • So that I can maintain the security of my account.

User Story 1: Changing the Password

  • As a Salesforce user,
  • I want to change my password using the web interface,
  • So that I can ensure my account remains secure.

Acceptance Criteria:

  • GIVEN I am logged into my account,
  • WHEN I enter my current password, a new password, and verify the new password,
  • THEN my password is successfully updated, and I receive a confirmation message.

User Story 2: Password Verification

  • As a Salesforce user,
  • I want the system to verify that my new password matches the confirmation,
  • So that I can avoid input errors and ensure my password is set correctly.

Acceptance Criteria:

  • GIVEN I have entered a new password and a verification password,
  • WHEN the two passwords do not match,
  • THEN an error message is displayed, and the password change does not occur.

User Story 3: Old Password Requirement

  • As a Salesforce user,
  • I want to provide my old password as a validation step,
  • So that unauthorized changes to my password are prevented.

Acceptance Criteria:

  • GIVEN I enter my old password,
  • WHEN it does not match the existing password,
  • THEN an error message is displayed, and the password change does not occur.

Technical Tasks

Task 1: Implement Password Change Logic
- Description: Update the ChangePasswordController to handle password changes securely, ensuring comparisons are case-sensitive and validating all provided inputs.
- Completion Criteria:
- User account password is changed successfully when valid input is provided.
- Proper input validation and error handling are integrated.

Task 2: Add Password Verification Logic
- Description: Implement logic that checks the new password against the verification password to ensure they match before finalizing the change.
- Completion Criteria:
- The user receives an error if the new password does not match with the verification password.

Task 3: Implement Old Password Verification
- Description: Enhance the password change method to validate that the provided old password matches the current password stored for the account.
- Completion Criteria:
- An error message is shown if the old password is incorrect, preventing any changes to be made.

Task 4: Create Unit Tests
- Description: Write test cases for ChangePasswordController to cover scenarios of successful password changes and error handling for mismatched passwords.
- Completion Criteria:
- Unit tests confirm that old password validation works correctly.
- Unit tests validate different scenarios when changing passwords, including success and failure cases.

Functional Map

User Management

Sub-function UM.1: User Authentication

Sub-function UM.2: Password Management

Password Resetting

Password Resetting

Sub-function PR.1: Change Password

Sub-function PR.2: Verify Password

User Management

Notification System

Sub-function NS.1: Send Email Notifications

Sub-function NS.2: Send SMS Notifications

User Management
Password Resetting

Database Management

Sub-function DB.1: User Data Storage

Sub-function DB.2: Password History Tracking

User Management
Password Resetting

Detailed Functional Specifications

Functional Scope

The ChangePasswordController Apex class supports the business process of user account management, specifically focusing on the password change functionality within the Salesforce application. This process is essential for maintaining user account security and ensuring proper access control.

Business Processes Supported

  • User Account Management
  • This includes changing user passwords to ensure account security and compliance.

Use Cases

Use Case 1: Change User Password

  • Main functional domain: User Account Management
  • Main Actor: User
  • Description: A user initiates a request to change their current password to a new password for security purposes.
  • Pre-conditions:
  • User is authenticated.
  • User knows their current password.
  • The new password meets system-defined criteria (length, complexity).
  • Post-conditions:
  • The user's password is updated successfully.
  • The user can log in with the new password.
  • Detailed steps:
  • User accesses the change password functionality in the application.
  • User inputs their current password into the oldPassword field.
  • User inputs the desired new password into the newPassword field.
  • User confirms the new password in the verifyNewPassword field.
  • User submits the password change request.
  • The system calls the changePassword method in the ChangePasswordController class.
  • The method validates the inputs and attempts to change the password.
  • If successful, the user receives a confirmation message; otherwise, an error message is displayed.

Functionalities Supported by the Class

  • Properties:
  • oldPassword: Holds the current password inputted by the user.
  • newPassword: Holds the proposed new password inputted by the user.
  • verifyNewPassword: Confirms the new password entered by the user for validation.

  • Methods:

  • changePassword():
    • This method calls the Site.changePassword method to change the user password.
    • It requires the old password, new password, and verified new password as parameters.
    • The function does not return any value as it directly performs the password change operation.

Business Rules

  • Password change requests must include verification of the current password.
  • New password must comply with security standards set by the organization (e.g., minimum length, character type requirements).
  • The old password input must match the currently stored password for the operation to proceed.
  • If the new and verified passwords do not match, the operation must not proceed.
  • The system must ensure that successful changes are logged for audit purposes.

Interaction with Automation Tools

  • The ChangePasswordController class does not explicitly interact with triggers, workflows, or dashboards in the provided code. However, changes made through the changePassword method may trigger system-level logging or notifications based on custom organizational policies or configurations.

Testing Functionality

  • The class includes a test method testChangePasswordController, which instantiates the ChangePasswordController, sets sample password values, and asserts that calling the changePassword() method functions as intended. This suggests a framework for validating that the password change logic behaves correctly under controlled conditions, although actual expected outcomes (like success or failure messaging) are not evaluated within the test.

Reporting or Dashboard Functionalities

  • The current implementation does not provide direct reporting or dashboard functionalities. However, it is implied that any password changes could be tracked in user logs or security management systems within Salesforce for monitoring user actions. Further integration might be considered to visualize password change metrics or audit logs via dashboards.

This documentation provides a comprehensive overview of the functionalities and conditions surrounding the ChangePasswordController Apex class, ensuring both technical and non-technical stakeholders have a clear understanding of its purpose and operations.

Detailed Technical Specifications

Main functionality analysis:

  • Purpose:
  • The ChangePasswordController class facilitates the process of changing user passwords within a Salesforce application. Its primary function is to handle user input for a password change request.

  • Trigger Events:

  • This class does not operate as a trigger but rather as a utility class that encapsulates logic for changing a user's password through a method invocation.

  • Business Context:

  • The class is relevant in scenarios where users need to update their passwords for security reasons or as part of a user account maintenance process. It ensures that the passwords adhere to minimal security guidelines while providing an interface for users to perform such changes.

Method descriptions:

  • changePassword()
  • Role: This method initiates the password change process by calling the Salesforce Site API to perform the actual change using the new password and its confirmation.

  • Parameters:

    • None (uses class properties).
  • Return Value:

    • Returns a PageReference object indicating the next page to navigate to after the password change action.
  • Exceptions:

    • The method may raise exceptions from the underlying Site.changePassword call, depending on the security constraints and validation failures related to the password change.
  • Constructor ChangePasswordController()

  • Role: This is a default constructor for instantiating ChangePasswordController. It does not perform any explicit initialization logic.

Interaction with other modules:

  • Dependencies:
  • The class interacts with the Salesforce Site class to execute the password change operation.
  • The Site.changePassword method is critical as it encapsulates the functionality needed for changing passwords securely.

  • Salesforce Objects:

  • This class primarily works with user-related data but does not directly manipulate standard or custom Salesforce objects. It interfaces with user authentication and session management indirectly through the password change mechanism.

Data flow analysis:

  • Data Types:
  • The class handles string types for the user’s password, including:

    • oldPassword - the user's current password (not utilized in the change call here, which could lead to possible future improvements).
    • newPassword - the new password to be set.
    • verifyNewPassword - a confirmation string for the new password.
  • Data Processing:

  • User input is captured through the class properties (oldPassword, newPassword, verifyNewPassword).
  • The flow involves performing validation checks (not explicitly coded in the snippet) before calling the password change function, ensuring that the new password matches its verification.

  • Data Storage:

  • Changes, when completed successfully through changePassword(), will be reflected in the user's account in Salesforce, updating the user's password securely.

Use cases covered:

  • Use Cases:
  • Allow users to change their passwords.
  • Ensure password confirmation to mitigate errors during the password change process.

  • Business Needs:

  • Addresses user security by allowing them to maintain account security and follow organizational password policies.
  • Enhances user experience by providing a straightforward mechanism for password updates, which is critical for application usability and security compliance.

Detailed review of Salesforce org and Apex code


Performance and Scalability

Performance Bottlenecks
  • Issue Identified: The changePassword method uses the Site.changePassword method, which may have performance implications depending on the implementation and user load.

  • Example: The code snippet uses Site.changePassword(newPassword, verifyNewPassword, oldpassword).

  • Recommendation: Optimize the changePassword process by ensuring that it doesn't perform unnecessary logic or queries. If encountering frequent calls, consider refactoring it to use asynchronous processing with future or queueable jobs if applicable, depending on the logic's complexity.


Security and Compliance

SOQL Injection Prevention
  • Issue Identified: The code does not perform any checks to validate the input for the password change process, which could be a security threat if this method is exposed through a public site.

  • Example: The changePassword method accepts input directly from users without validation.

  • Recommendation: Implement input validation logic to prevent such issues. Ensure that the newPassword and verifyNewPassword do not include special characters or spaces that could lead to injection vulnerabilities. Use string manipulation methods to sanitize inputs before processing. Also, log errors securely without exposing sensitive information.


Field-Level Security and CRUD Checks
  • Issue Identified: The code does not check if the current user has the appropriate permissions (CRUD/FLS checks) to change the password.

  • Example: Directly calling Site.changePassword without checking user permissions.

  • Recommendation: Before changing passwords, ensure to check the logged-in user's permissions using Schema.SObjectType.User.fields.getMap() for field-level security and implement CRUD checks for the password-related operations.


Code Quality and Maintainability

Readability and Adherence to Standards
  • Issue Identified: The method and variable names deviate from the Apex naming conventions. For example, oldpassword should be oldPassword.

  • Example: The method parameter uses oldpassword instead of oldPassword.

  • Recommendation: Rename variables and method parameters to comply with proper casing and naming conventions as per Salesforce standards to enhance readability.


Refactoring and Code Smells
  • Issue Identified: The testChangePasswordController directly instantiates the controller and sets hardcoded password values without proper testing strategy or mocking.

  • Example: controller.oldPassword = '123456';

  • Recommendation: Refactor test cases to utilize test utility classes for generating test data. Use relevant and varied test data to ensure robust testing, preventing hardcoding values directly in tests.


Automation and Testability

Test Coverage
  • Issue Identified: The test method does not adequately cover different scenarios, such as invalid inputs or security checks.

  • Example: Only a simple success case has been covered in the test.

  • Recommendation: Enhance the test method to include various scenarios:

  • Test when newPassword and verifyNewPassword do not match.
  • Test invalid password criteria (e.g., lacks special characters).
  • Test for different user permission levels to ensure robust security checks are in place.

Logging and Monitoring

Logging Mechanisms
  • Issue Identified: There is currently no logging for exceptions or errors during the password change operation.

  • Example: The code lacks any log statement or exception handling.

  • Recommendation: Implement a logging mechanism (e.g., using a custom Log object) to track errors or anomalies during execution, especially in cases where the password change fails. This can help troubleshoot and monitor the change process effectively.


Deployment and Version Control

CI/CD Pipeline Review
  • Issue Identified: The method implementation lacks visibility on whether it follows CI/CD deployment standards.

  • Example: The provided code does not reference deployment practices or pipelines.

  • Recommendation: Document how this changeset integrates into your CI/CD process. Ensure that all new changes are versioned correctly. Utilize the Salesforce CLI for deployments and manage the metadata appropriately through version control systems (e.g., Git).


Security Best Practices

Error Handling
  • Issue Identified: The method lacks structured error handling, which could expose errors to end users.

  • Example: If an exception occurs, it’s unclear how the system will respond or log the failure.

  • Recommendation: Wrap the logic in a try-catch block and use a custom exception class for better error handling and debugging. This will improve the resilience of the changePassword function.


High-Priority Recommendations 1. Performance Improvements: Ensure the changePassword logic is optimized for asynchronous processing if high-frequency calls are expected. 2. Security Enhancements: Implement proper input validation, FLS checks, and secure error logging mechanisms. 3. Code Quality: Refactor variable names to follow Apex naming conventions, and enhance test coverage for robustness against different scenarios.

Improvements

Section: Performance Optimization
Issue: The changePassword method uses hard-coded password values in the test method.
Recommendation: Instead of using hard-coded values, consider using test data factories or a custom setting to retrieve test passwords. This allows for easier updates and more robust testing.

Section: Governor Limit Management
Issue: The method changePassword directly calls the Site.changePassword without handling potential errors.
Recommendation: Implement proper error handling around the password change operation to ensure that any issues are caught and managed without causing unhandled exceptions or exceeding governor limits.

Section: Best Practices
Issue: The oldPassword variable is consistently referenced with the incorrect casing (oldpassword instead of oldPassword).
Recommendation: Change usage from oldpassword to oldPassword to maintain consistency with the property declaration and prevent potential runtime errors.

Section: Code Readability and Maintainability
Issue: The class lacks methods that are modular and reusable.
Recommendation: Consider breaking up the changePassword method into smaller helper methods that handle specific tasks (e.g., validate passwords, perform the change). This modular approach enhances readability and maintainability.

Section: Security Considerations
Issue: The changePassword method lacks field-level security (FLS) checks and validation for sensitive input.
Recommendation: Ensure that FLS checks are implemented before accessing sensitive fields and encrypt or sanitize inputs to prevent security vulnerabilities such as unauthorized access to password data.

Section: Documentation and Comments
Issue: The class and methods lack comments describing their purpose and functionality.
Recommendation: Add comments at the start of the class and each method explaining their purpose, parameters, and return values. This will improve code understanding and facilitate easier onboarding for new developers.

Original Code

public class ChangePasswordController {
    public String oldPassword {get; set;}
    public String newPassword {get; set;}
    public String verifyNewPassword {get; set;}        

    public PageReference changePassword() {
        return Site.changePassword(newPassword, verifyNewPassword, oldpassword);    
    }     

    public ChangePasswordController() {}

    public static testMethod void testChangePasswordController() {

        ChangePasswordController controller = new ChangePasswordController();
        controller.oldPassword = '123456';
        controller.newPassword = 'qwerty1'; 
        controller.verifyNewPassword = 'qwerty1';                

        System.assertEquals(controller.changePassword(),null);                           
    }    
}

Refactored Code

public class ChangePasswordController {
    // Properties for holding password data
    public String oldPassword { get; set; }
    public String newPassword { get; set; }
    public String verifyNewPassword { get; set; }

    // Method to change user password
    public PageReference changePassword() {
        // Use ensure that the variable is correctly spelled
        return Site.changePassword(newPassword, verifyNewPassword, oldPassword);    
    }     

    // Constructor
    public ChangePasswordController() {}

    // Test method for ChangePasswordController
    @isTest
    static void testChangePasswordController() {
        ChangePasswordController controller = new ChangePasswordController();
        controller.oldPassword = '123456';
        controller.newPassword = 'qwerty1'; 
        controller.verifyNewPassword = 'qwerty1';                

        // Assert that the changePassword method behaves as expected
        System.assertEquals(null, controller.changePassword());                           
    }    
}

Key Changes Summary

  • Formatting and Indentation: Improved the formatting and indentation for better readability.

  • Spelling Correction: Corrected the variable oldpassword to oldPassword in the changePassword method to match the property naming convention.

  • Method Annotation: Added @isTest annotation to the test method to clarify its purpose and ensure it is recognized as a test method.

  • Inline Comments: Included inline comments to explain the purpose of methods and properties, enhancing code understandability.

  • Consistent Property Access: Ensured all properties utilized a consistent camelCase naming convention.

  • Code Cleanup: Removed unnecessary line breaks to enhance readability.

These changes enhance the clarity of the code while maintaining its original functionality.

Tests

Positive Testing

Test Case TC001

Description: Verify that changing the password with valid input values is executed successfully without errors.
Preconditions:
- User is logged in to Salesforce with permissions to change passwords.
- Ensure that the current password (oldPassword) is correct.

Test Steps:
1. Instantiate ChangePasswordController.
2. Set oldPassword to '123456'.
3. Set newPassword to 'qwerty1'.
4. Set verifyNewPassword to 'qwerty1'.
5. Call the changePassword() method.

Expected Results:
- The method should execute without throwing any exceptions.
- The return value of changePassword() should be null.

Test Data:
- oldPassword: '123456'
- newPassword: 'qwerty1'
- verifyNewPassword: 'qwerty1'


Negative Testing

Test Case TC002

Description: Verify that changing the password with mismatched new password and verification password fails.
Preconditions:
- User is logged in to Salesforce with permissions to change passwords.
- Ensure that the current password (oldPassword) is correct.

Test Steps:
1. Instantiate ChangePasswordController.
2. Set oldPassword to '123456'.
3. Set newPassword to 'qwerty1'.
4. Set verifyNewPassword to 'wrongpassword'.
5. Call the changePassword() method.

Expected Results:
- The method should execute and potentially throw an exception or return an error indicating the passwords do not match.

Test Data:
- oldPassword: '123456'
- newPassword: 'qwerty1'
- verifyNewPassword: 'wrongpassword'


Boundary Testing

Test Case TC003

Description: Validate the behavior when the new password and verify password exceed the character limit.
Preconditions:
- User is logged in to Salesforce with permissions to change passwords.
- Ensure that the current password (oldPassword) is correct.

Test Steps:
1. Instantiate ChangePasswordController.
2. Set oldPassword to '123456'.
3. Set newPassword to a string with 256 characters (assuming this is the limit).
4. Set verifyNewPassword to the same 256-character string.
5. Call the changePassword() method.

Expected Results:
- The method should execute and potentially throw an exception or return an error indicating the password exceeds allowable length.

Test Data:
- oldPassword: '123456'
- newPassword: A string of 256 'A' characters.
- verifyNewPassword: The same 256 'A' characters.


Edge Cases

Test Case TC004

Description: Ensure that the password change is handled appropriately when the oldPassword is incorrectly provided.
Preconditions:
- User is logged in to Salesforce with permissions to change passwords.

Test Steps:
1. Instantiate ChangePasswordController.
2. Set oldPassword to an incorrect password ('wrongpass').
3. Set newPassword to 'qwerty1'.
4. Set verifyNewPassword to 'qwerty1'.
5. Call the changePassword() method.

Expected Results:
- The method should execute and throw an exception or return an error indicating the old password does not match.

Test Data:
- oldPassword: 'wrongpass'
- newPassword: 'qwerty1'
- verifyNewPassword: 'qwerty1'


Data-driven Testing

Test Case TC005

Description: Validate password change functionality with various valid and invalid password combinations for newPassword and verifyNewPassword.
Preconditions:
- User is logged in to Salesforce with permissions to change passwords.
- Ensure that the current password (oldPassword) is correct.

Test Steps:
1. Instantiate ChangePasswordController.
2. Set oldPassword to '123456'.
3. Loop through the following sets of newPassword and verifyNewPassword:
- Set 1: newPassword: '12345678', verifyNewPassword: '12345678' (valid)
- Set 2: newPassword: 'abc12345', verifyNewPassword: 'abc123456' (invalid)
- Set 3: newPassword: 'admin@123', verifyNewPassword: 'admin@123' (valid)
4. For each case, call the changePassword() method and capture the result.

Expected Results:
- For valid cases: method executes successfully without error.
- For invalid cases: method throws an exception or returns an error indicating the mismatch.

Test Data:
- Set 1: '12345678', '12345678'
- Set 2: 'abc12345', 'abc123456'
- Set 3: 'admin@123', 'admin@123'

Potential AgentForce use cases or similar functionalities

  1. Primary Use Case:
  2. Secure and streamlined self-service password management for agents and customers.

  3. Key Business Outcomes:

  4. Minimizes time and effort spent on password reset requests, reducing pressure on support teams.
  5. Enhances security by empowering users to update credentials independently, decreasing risk of stagnant or compromised accounts.
  6. Supports compliance initiatives through enforced password update policies.

  7. Relevant Customer Scenarios:

  8. Agents are required to reset passwords at regular intervals according to organizational policy.
  9. Customers regain access after a forgotten password via a secure interface, without waiting for manual intervention.
  10. Field agents working in different time zones reset their credentials on their own, maintaining seamless operations.

  11. Business Value Delivered:

  12. Reduces password-related incident tickets by up to 60%.
  13. Shortens average password reset process from hours to under a minute, improving operational efficiency.
  14. Enhances user satisfaction and trust due to reduced downtime and secure handling.

  15. Recommended Next Steps:

  16. Integrate multi-factor authentication (MFA) for stronger security during sensitive operations such as password changes.
  17. Automate password expiration notifications and enforce complexity rules.
  18. Enable agent supervisors and admins to monitor password health across the agent pool.
  19. Expand self-service options to include account unlock and recovery workflows, further lowering support burden.

Extended and Inspired Use Cases

  1. Primary Use Case:
  2. Dynamic access and credential management as part of agent onboarding/offboarding workflows.

  3. Key Business Outcomes:

  4. Accelerates provisioning for new hires and revocation for exits or role changes.
  5. Reduces security risks associated with inappropriate or lingering access.
  6. Eases compliance with regulations (e.g., GDPR, HIPAA) requiring auditable access controls.

  7. Relevant Customer Scenarios:

  8. Mass onboarding of temporary agents during busy seasons with automated credential assignment.
  9. Rapid credential revocation for contractors or gig workers upon project completion.
  10. Role-based access adjustments when agents transition between departments (e.g., from support to sales).

  11. Business Value Delivered:

  12. Slashes onboarding and offboarding time by 30-50%.
  13. Improves security posture and audit readiness.
  14. Increases flexibility in managing distributed, hybrid, or gig-based agent teams.

  15. Recommended Next Steps:

  16. Integrate with HR and identity management systems to synchronize credential lifecycle events.
  17. Automate notifications and approvals for changes in agent access or roles.
  18. Track credential changes and provide real-time reporting for compliance audits.

Additional Opportunities Inspired by Broader Industry Practices

  1. Primary Use Case:
  2. Unified agent self-service portal, integrating password management, schedule viewing, workload balancing, and well-being features.

  3. Key Business Outcomes:

  4. Empowers agents to manage core administrative tasks, promoting autonomy and satisfaction.
  5. Decreases need for manual HR or IT intervention.
  6. Supports agent well-being and prevents burnout through automated break tracking and workload transparency.

  7. Relevant Customer Scenarios:

  8. Agents initiate password resets, view schedules, request time off, and monitor workload, all in one place.
  9. System proactively prompts agents to take breaks or flags when workloads exceed best-practice thresholds.
  10. Distributed and hybrid teams remain connected to central resources via secured, mobile-friendly interfaces.

  11. Business Value Delivered:

  12. Increases agent productivity and retention by up to 15-20%.
  13. Decreases administrative overhead for HR and IT by up to 35%.
  14. Enhances compliance with labor and well-being standards.

  15. Recommended Next Steps:

  16. Expand the ChangePasswordController pattern to a modular self-service controller for multiple administrative tasks.
  17. Integrate usage analytics to continuously refine and prioritize most-used self-service features.
  18. Partner with workforce management vendors for deeper schedule/workload integration.

Sensitive information:
- No secret tokens or password fields are directly exposed in the code sample. However, always review for potential hardcoded secrets and ensure secure handling of credentials in production environments.

Diagram

stateDiagram-v2 direction LR %% Initial transition [*] --> ChangeController %% "ChangeController" comme regroupement logique state ChangeController { Constructor --> OldPassword: "Initialize properties" OldPassword --> NewPassword NewPassword --> VerifyNewPassword VerifyNewPassword --> ChangePwd: "Assign password values" ChangePwd --> TestMethod: "Invoke changePassword method" } %% Transitions externes (test) ChangeController --> ExternalCall: "Call Site.changePassword()" ExternalCall --> AssertResult: "Assert result equals null" AssertResult --> [*] %% Liste des états (à plat) state Constructor state OldPassword state NewPassword state VerifyNewPassword state ChangePwd state TestMethod state ExternalCall state AssertResult %% Styles class OldPassword,NewPassword,VerifyNewPassword purpleProps class Constructor,ChangePwd,TestMethod,ExternalCall,AssertResult orangeMethods classDef purpleProps fill:#800080,stroke:#000,stroke-width:2px,color:#FFF; classDef orangeMethods fill:#FFA500,stroke:#000,stroke-width:2px,color:#000;