Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Correctly Update User Details and Handle Profile Picture Length #4489

Merged
merged 2 commits into from
Feb 25, 2025

Conversation

Baalmart
Copy link
Contributor

@Baalmart Baalmart commented Feb 25, 2025

Description

This PR resolves issues with user account updates during Google authentication, including thelastLogin,isActive, andloginCountfields, and handles profile picture URLs that exceed the maximum allowed length, and now newly registered users and previously registered users have their fields updated correctly.

Changes Made

  • Passport Middleware (passport.js):
    • Removed the next() call from the useGoogleStrategy callback to ensure the controller runs after the Google Strategy's cb() function has completed.
    • Modify the new user creation part to include the lastLogin, isActive, loginCount updates.
    • Added next parameter to the UserModel.register() method.
    • Passed the next parameter to the UserModel.register() method.
  • User Model (User.js):
    • Modified the UserSchema.pre() to truncate profile picture URLs longer than 1024 characters.
    • Added validation for the profile picture after truncation.
    • Updated the UserSchema.statics.register() method to take a next parameter.
    • Updated the toAuthJson method to have a return value for the jwt.sign() method.
  • User Controller (user.controller.js):
    • The database update logic has been moved to google callback and is being run after the req.user is set by passport.
    • The tenant from the request is being used for the database updates.

Testing

  • Tested locally
  • Tested against staging environment
  • Relevant tests passed: [List test names]

Affected Services

  • Which services were modified:
    • Auth Service

Endpoints Ready for Testing

  • New endpoints ready for testing:
    • Google Signin

API Documentation Updated?

  • Yes, API documentation was updated
  • No, API documentation does not need updating

Summary by CodeRabbit

  • New Features

    • Enhanced the Google sign-in experience by tracking user login activity and status, ensuring improved session management and a more stable authentication process.
  • Bug Fixes

    • Improved error handling during new user registration, providing a smoother and more reliable onboarding experience.
    • Optimized profile picture input validation by automatically truncating excessively long entries, reducing potential input errors.

Copy link
Contributor

coderabbitai bot commented Feb 25, 2025

📝 Walkthrough

Walkthrough

The changes update several components of the authentication flow. In the user controller’s googleCallback method, after logging the Google token, the code now updates the user’s last login time, active status, and login count with a try-catch block. In the Passport middleware’s useGoogleStrategy function, the user registration process now passes the next function into the registration call and includes improved error handling during record updates. Additionally, the user model’s pre-validation middleware for profilePicture has been modified to truncate overly long URLs before final validation.

Changes

File(s) Change Summary
src/auth-service/controllers/user.controller.js In googleCallback, after logging the token, the method updates lastLogin, isActive, and loginCount via findOneAndUpdate wrapped in a try-catch block.
src/auth-service/middleware/passport.js The useGoogleStrategy function now passes next to UserModel.register and wraps subsequent user update operations in a try-catch block for error logging.
src/auth-service/models/User.js The pre-validation middleware for profilePicture now truncates the field to 1024 characters before re-validation, returning an error if the truncated value is invalid.

Possibly related PRs

  • handling cases where this.getQuery might not be available #3941: The changes in the main PR, which involve updating user login details in the googleCallback method, are related to the modifications in the retrieved PR that enhance error handling and user data updates in the User.js model.
  • Optimize User Authentication #4225: The changes in the main PR are related to the updates made to the user's last login time and active status in the user.controller.js, which also occurs in the retrieved PR's loginWithDetails method.
  • addressing loginCount and lastActive logical errors #4283: The changes in the main PR enhance the user update logic in the googleCallback method, while the retrieved PR removes similar user update logic from the login method in the same file, indicating a direct relationship in terms of modifying user activity tracking.

Suggested reviewers

  • Benjamin Ssempala

Poem

In lines of code and logical streams,
Google tokens spark our authentication dreams.
User updates now secure and bright,
With try-catch guarding both day and night.
A cascade of changes, flawless and keen,
Our code now dances in a well-made scene.
🚀✨ Happy coding, serene and clean!

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • JIRA integration encountered authorization issues. Please disconnect and reconnect the integration in the CodeRabbit UI.

📜 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 81a1603 and 3d873c3.

📒 Files selected for processing (1)
  • src/auth-service/models/User.js (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: build-push-deploy-auth-service
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (5)
src/auth-service/models/User.js (5)

21-22: Good approach using a named constant for the profile picture URL length.

Creating a constant for this value improves maintainability and ensures consistency across the codebase.


40-44: Consistent application of the new maximum length constant.

You've properly updated the validation function to use the new constant. This ensures that error messages are consistent with the actual validation logic being applied.


224-224: Updated schema validation constraint appropriately.

The maxLength property in the schema definition now references the constant, maintaining consistency throughout the codebase.


231-231: Error message updated for consistency.

The error message now dynamically references the maximum length constant, which will ensure it stays in sync if the value changes in the future.


420-435:

✅ Verification successful

Good implementation of URL truncation with proper validation.

Rather than simply rejecting profile pictures with URLs that exceed the maximum length, the code now attempts to truncate them and re-validate. This is a more user-friendly approach.

A few observations:

  1. The truncation logic correctly handles URLs that exceed the maximum length
  2. Re-validation after truncation ensures the URL remains valid
  3. Proper error handling if the truncated URL is still invalid

One consideration: Truncating URLs can sometimes break functionality if important query parameters are cut off. While 1024 characters should be sufficient for most URLs, you may want to monitor if any users report issues with their profile pictures not loading correctly after truncation.


🏁 Script executed:

#!/bin/bash
# Check if there are any other places in the codebase where URL truncation might be needed
rg -A 2 -B 2 "profilePicture.*length" --type js

Length of output: 737


Truncation & Re-validation Logic Verified and Approved

  • The truncation logic in src/auth-service/models/User.js (lines 420-435) effectively truncates overly long profile picture URLs and then re-validates them.
  • A repository-wide search confirms that similar URL length checks appear only in this context, showing consistency throughout the file.
  • One minor caution remains: truncating URLs might inadvertently remove critical query parameters. While 1024 characters should cover most cases, it’s advisable to monitor for any user reports of broken profile pictures.

Overall, this is a solid, user-friendly implementation.

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

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. (Beta)
  • @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

codecov bot commented Feb 25, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 11.23%. Comparing base (26cb93a) to head (3d873c3).
Report is 224 commits behind head on staging.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff            @@
##           staging    #4489   +/-   ##
========================================
  Coverage    11.23%   11.23%           
========================================
  Files          156      156           
  Lines        18020    18020           
  Branches       388      388           
========================================
  Hits          2025     2025           
  Misses       15993    15993           
  Partials         2        2           

Copy link
Contributor

Auth-service changes in this PR available for preview here

Copy link
Contributor

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

🧹 Nitpick comments (4)
src/auth-service/models/User.js (1)

419-430: Good implementation of profile picture URL truncation.

This change correctly handles the case where a profile picture URL exceeds the maximum allowed length by truncating it to 200 characters before re-validating. This is a more user-friendly approach than simply rejecting the URL.

Consider adding a log message or notification to indicate that truncation occurred, which could help with debugging user issues. For example:

 // Truncate if too long
 if (this.profilePicture.length > 200) {
+  logger.info(`Profile picture URL truncated from ${this.profilePicture.length} to 200 characters for user ${this._id || 'new user'}`);
   this.profilePicture = this.profilePicture.substring(0, 200);
 }
src/auth-service/controllers/user.controller.js (2)

373-374: Consider using a tenant validation check.

The code uses the tenant directly from the request, but it would be safer to validate it or provide a fallback.

- await UserModel(request.query.tenant) // Use the tenant from the request.
+ const tenant = request.query.tenant || constants.DEFAULT_TENANT || "airqo";
+ await UserModel(tenant)

377-384: Clean implementation for updating user activity metrics.

The update logic handles the lastLogin, isActive, and loginCount fields correctly.

There's a commented example of a conditional update for the verified field. Either implement this feature if needed or remove the comment to keep the code clean:

- // Add any other updates as needed (e.g., verified)
- // ...(req.user.analyticsVersion !== 3 && req.user.verified === false ? { $set: { verified: true } } : {}), // Example (if you have these fields)
+ // Add any other updates as needed
src/auth-service/middleware/passport.js (1)

492-518: Consistent user activity tracking implementation.

This code correctly updates the user's lastLogin, isActive, and loginCount after successful Google registration, consistent with the implementation in the controller.

Consider extracting this user activity update logic into a utility function since it's duplicated in multiple places (controller and middleware). This would make maintenance easier and reduce code duplication:

// In a utils file (e.g., user.utils.js)
async function updateUserActivityMetrics(tenant, userId, options = {}) {
  const currentDate = new Date();
  try {
    await UserModel(tenant.toLowerCase())
      .findOneAndUpdate(
        { _id: userId },
        {
          $set: { lastLogin: currentDate, isActive: true },
          $inc: { loginCount: 1 },
          ...(options.updateVerification ? { $set: { verified: true } } : {})
        },
        {
          new: true,
          upsert: false,
          runValidators: true
        }
      )
      .then(() => {})
      .catch((error) => {
        logger.error(`🐛🐛 Internal Server Error -- ${stringify(error)}`);
      });
  } catch (error) {
    logger.error(`🐛🐛 Internal Server Error -- ${stringify(error)}`);
  }
}

// Then in your code:
// updateUserActivityMetrics(tenant, user._id, { updateVerification: user.analyticsVersion !== 3 && user.verified === false });
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 23ef076 and 81a1603.

📒 Files selected for processing (3)
  • src/auth-service/controllers/user.controller.js (1 hunks)
  • src/auth-service/middleware/passport.js (2 hunks)
  • src/auth-service/models/User.js (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: build-push-deploy-auth-service
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (4)
src/auth-service/controllers/user.controller.js (1)

370-390:

❓ Verification inconclusive

Properly updates user activity metrics after Google login.

The added code correctly updates the user's lastLogin time, active status, and login count after successful Google authentication. This ensures consistent tracking of user activity.

There appears to be a potential issue with the error logging. The stringify function is used in the error logging but its import isn't visible in the provided code segment. Let's verify this:


🏁 Script executed:

#!/bin/bash
# Check if stringify is properly imported
rg "stringify.*=.*require|import.*stringify" src/auth-service/controllers/user.controller.js

Length of output: 94


Verify stringify Import in User Controller

The revised code correctly updates the user's last login, active status, and login count. However, please note that the error logging still calls the stringify function without any visible import or definition in this file. We need to confirm if stringify is provided globally or imported elsewhere. If not, please add the appropriate import statement or function definition to prevent potential runtime errors.

  • Verified code snippet for user activity update remains intact.
  • Action Required: Manually verify that stringify is imported or defined in your codebase; if it isn’t, add the necessary import.
src/auth-service/middleware/passport.js (3)

456-456: Good removal of premature next() call.

Removing this next() call is important to ensure the authentication flow completes properly before proceeding to the next middleware.


458-472: Proper error handling with next parameter.

Adding the next parameter to the register method allows for better error propagation and handling throughout the authentication flow.


521-521: Appropriate removal of next() call.

Similar to line 456, removing this next() call ensures the authentication flow completes before proceeding to the next middleware.

Copy link
Contributor

Auth-service changes in this PR available for preview here

@Baalmart Baalmart merged commit 80976a3 into staging Feb 25, 2025
52 checks passed
@Baalmart Baalmart deleted the fix-google-auth-user branch February 25, 2025 13:56
@Baalmart Baalmart mentioned this pull request Feb 25, 2025
3 tasks
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.

1 participant