Alternative email as authentication

I have this scenario where users are expected to fill up an alternative email address and use that to authenticate user but I don’t know how or if there is an existing API that can be used to do that. I would like to know it.

You probably need to design a custom auth:
Notice that here i’m using GraphQL API for internal calls, i’m also using Typescript

// Custom Email Auth module
export const CustomEmailAuth = {
	async validateAuthData(authData: CustomAuthEmailInput) {

        //authData.id is email, need to keep this name for Parse Server auth engine
		if (authData.id && authData.password) {
            // Auth data should be already set on the user
			const { users } = await client.findUsersByCustomAuth({ email: authData.id })

			if (users.edges?.length === 1 && users.edges[0] && users.edges[0].node) {
				const user = users.edges[0].node
				// Additional safety check
				if (
					user.authData?.customEmail?.id === authData.id &&
					user.authData?.customEmail?.password &&
					user.authData.customEmail.password ===
						SHA512(authData.password).toString()
				) {
					return
				}
			}
		}
                // Always throw by default for security purpose
		throw new Error('Invalid authData')
	},

	async validateAppId() {
		return true
	},
}
// On the Parse Server Config
auth: {
    customEmail: {
        module: CustomEmailAuth,
    },
},
# The query used to find the user
query findUsersByCustomAuth($email: Any!) {
    users(where: { authData: { equalTo: { key: "customEmail.id", value: $email } } }, first: 2) {
      edges {
        node {
          id
          username
          authData {
            customEmail {
              id
              password
            }
          }
        }
      }
    }
  }

Sorry I should have stated my tools first and made clear of the statement of what I’m trying to do. I’m not familiar with GraphQL, I only used, NodeJS Server and JS-SDK.

Let’s say, A user signed up with email and password. The username is what the user inputted as their email. Aside from it was personal info, and then alternativeEmail field as part of _User class name.

The next time, that user logged in, he decided to use his alternative email address to authenticate.

How will I be able to do that?

Based on your solution, I need to setup a custom authentication (though I need to study custom auth first), and in the client, I need to provide an AuthProvider and use linkWith?

Yes custom auth + linkWith, parse server donnot support alternative emails for auth

Upon looking at UsersRoute of PS, I just saw how they handle querying for email, username, and password comparison using crypto. I’ll try to mimic haw they did it.

You can use this simple cloud code:

Parse.Cloud.define("loginWithAlternativeEmail", async (request) => {

  var alternativeEmail = request.params.email;

  var pass = request.params.pass;
  
  if(!alternativeEmail||!pass){
    throw "error";
  }

  var userQuery = new Parse.Query(Parse.User);
  userQuery.equalTo("alternativeEmail",alternativeEmail);
  userQuery.limit(1);
  var result = await userQuery.find();
  if(result.length<1){
    throw "loginError";
  }

  var tempUser = result[0];
  var user = await Parse.User.logIn(tempUser.get("username"),pass);
  return user.getSessionToken();
  

});

Then use become method in javascript using sessionToken that cloud code returned.

Parse.User.become(token);

1 Like

Yes more affordable solution ! Thanks @uzaysan

1 Like

Thanks to both of you. @uzaysan I was wondering, is there any security risk like checking the number of attempts and so on?

I don’t think failed attemps would be security risk. Parse server itself comes with unlimited login try by default. But if you wanna restrict login after x times fail You can use accountLockout policy. More information of parse parameters can be found here

Is there a way to pull that from parse server so that I will be able to re-use that kind of logic?

I didn’t understand what you said. English is not my native language. Can you explain a little simple?

So do I :laughing:

I want to know if there is a way to re-use the logic of account policy from parse server instead of creating your own account policy?

So I guess you are talking about the code I posted above. It doesn’t change parse server account policy. It uses it. So normal account login/register should be work fine. Its just cloud code. It doesn’t change parse server behaviour.

Oh I see. Thanks a lot.