skip to Main Content

I have Parse server with MongoDB and KMP app where login method.

@POST("login")
@Headers(
    value = [
        "${ParseHeaders.CONTENT_TYPE}: application/json",
        "${ParseHeaders.APPLICATION_ID}: ${ParseConstants.APPLICATION_ID}",
        "${ParseHeaders.REST_API_KEY}: ${ParseConstants.REST_API_KEY}",
    ],
)
suspend fun logIn(@Body credentials: ParseLoginCredentials): ParseUserResponse

I need to make the username case-insensitive. Currently, usernames are stored in MongoDB in a disorganized way. We need to structure this on the server side, so the login username in the Parse server must be case-insensitive. I don’t see any login functions in the Parse backend code, yet the login works for some reason. Perhaps it’s handled internally by Parse. I’ve written an interceptor in the Parse server code, but it’s not working.

Parse.Cloud.define("login", async (req) => {
   try {
        const user = await Parse.User.logIn(req.params.username.toLowerCase(), req.params.password);
        return user;
    } catch (error) {
        const errorMessages = {
            101: "Login error.",
        };

        const errorCode = error.code || 0;
        const translatedError = errorMessages[errorCode] || "Login error.";

        throw new Parse.Error(errorCode, translatedError);
    }
});

Is there any option to handle this on the MongoDB side? Or how can it be done with Parse Server? Do I need to write additional code, such as a case-insensitive login hook, or is there another solution?

I also tried modifying and hiding some indexes in the `_User` entity on MongoDB, but it had no effect.
enter image description here

2

Answers


  1. If you can modify query of MongoDB in Parse.User.logIn use regex with /i option. Try use VSCode or Intellij open your project, setup open all hidden directory, use Ctrl + Click shortcut into logIn and you can find location code.

    With Mongodb you can config strength: 2 in collation for case-insentitive, see doc here. Just create index for username field.

    db.Users.createIndex(
      { username: 1 },
      { 
        collation: {
          locale: 'en',
          strength: 2
        }
      }
    );
    
    Login or Signup to reply.
  2. Parse Server does not have a built-in case-insensitive login feature. However, a straightforward way to handle case-insensitivity at the server level, specifically for usernames, is through normalization.

    Here’s a workaround solution:

    1. Store both the original username and a lowercase version of the username in separate fields in the MongoDB _User collection. You might name these fields username and usernameLowerCase.

    2. When a new user signs up, convert their username to lowercase and store it in the usernameLowerCase field, while also storing the original username in the username field.

    3. Update the login function to convert the username to lowercase before attempting to log in.

    Here’s a code snippet:

    Parse.Cloud.define('signup', async (req) => {
      const user = new Parse.User();
      user.set('username', req.params.username);
      user.set('usernameLowerCase', req.params.username.toLowerCase());
      user.set('password', req.params.password);
    
      try {
        const result = await user.signUp();
        return result;
      } catch (error) {
        throw new Parse.Error(Parse.Error.SIGN_UP_ERROR, error.message);
      }
    });
    
    Parse.Cloud.define('login', async (req) => {
      try {
        const query = new Parse.Query(Parse.User);
        query.equalTo('usernameLowerCase', req.params.username.toLowerCase());
        const userObject = await query.first();
        const user = await Parse.User.logIn(userObject.get('username'), req.params.password);
        return user;
      } catch (error) {
        throw new Parse.Error(Parse.Error.LOGIN_ERROR, error.message);
      }
    });
    

    In your Android/iOS application too, you would then authenticate with the original username and password via the Client SDK:

    ParseUser.logInInBackground(username, password, new LogInCallback() {
      public void done(ParseUser user, ParseException e) {
        if (user != null) {
          // Hooray! The user is logged in.
        } else {
          // Signup failed
        }
      }
    });
    

    One thing you should take care of is the uniqueness of the usernameLowerCase. You can create a unique index for the usernameLowerCase field to enforce this at the MongoDB level. Ensure to handle exceptions that may arise due to duplicate usernames in your signup function.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search