aws-samples / amazon-cognito-passwordless-auth

Passwordless authentication with Amazon Cognito: FIDO2 (WebAuthn, support for Passkeys), Magic Link, SMS OTP Step Up
Apache License 2.0
367 stars 63 forks source link

requestSignInLink does not work with phone number. #144

Closed fahadsadiq closed 6 months ago

fahadsadiq commented 7 months ago

I create a user with verified email and phone number. When call requestSignInLink({username: email}) using email, it works fine but when i requestSignInLink({username: phone}) using the verified phone number for the user i get "User does not exist."

I checked the comments for the functions it says that alias should work fine. Is this not supposed to work with phone number.

ottokruse commented 7 months ago

Should work with any alias, so phone nr too. Can you try a non-custom auth flow with that User Pool and Client ID and phone number? Does that work?

fahadsadiq commented 7 months ago

@ottokruse seems it was because user pool was configured wrong. It was fixed once enabled username, phone and email. Another question that i have is when i am using signup, the presignup lambda is triggered which auto confirms the user. But i want the to send a validation email to user once they signup. Will this be possible with the default setup for signup function or will i need to update the lambda.

ottokruse commented 7 months ago

Creation of preSignUp lambda can be turned off by setting autoConfirmUsers to false, as part of the magicLink properties you pass when using the CDK construct: https://github.com/aws-samples/amazon-cognito-passwordless-auth/blob/d7dda2898e5bfe227a4c5e5c4a46b1a07a4d83aa/cdk/lib/cognito-passwordless.ts#L228

ottokruse commented 7 months ago

Does that make sense? Turn preSignUp trigger off to have Cognito send the emails again.

That is because we set autoConfirmUsers to true in that trigger. You could of course also update the code and add logic to only auto confirm in specific cases. If you want that, swap in your own code by using the functionProps override for the preSignUp function, when instantiating the CDK construct.

fahadsadiq commented 7 months ago

Thank you @ottokruse. I went with overriding the preSignUp lambda. Here i am validating the email to check if the email already exists. I am facing a role issue where the lambda is not allowed to list users from cognito. Can i add the ability to list users access from

functionProps: { preSignUp: { entry: path.join(__dirname, "lambdas/pre-sign-up/index.ts"), bundling: { banner: "import {createRequire} from 'module'; const require = createRequire(import.meta.url);", }, }, },

ottokruse commented 7 months ago

Easiest is to do something like this:

const passwordless = new Passwordless(this, "Passwordless", {
   ... // your props
};

// Access the preSignUp function to add permissions to it:
passwordless.preSignUpFn.addToRolePolicy(yourStatement);

// Can also use it as grant target:
passwordless.userPool.Grant(passwordless.preSignUpFn, yourAction);
fahadsadiq commented 7 months ago

@ottokruse Thank you for your assistance so far. However, I've encountered another issue with the passwordless CDK implementation.

I've configured auto confirmation for users to be false in the CDK setup. Consequently, when a user signs up using a username and password, an email containing a verification code is sent to the provided email address. The signup function looks like this:

await signUp({ username: 'testusername', password: 'testpass', userAttributes: [ { name: 'email', value: email } ] });

Now, the provided functions such as verifyUserAttribute({ attributeName: 'email', code: '123' }) ; seem to require a user token for verification. However, during the signup process, only the UserSub is provided, like so:

{ UserSub: "56999c33-6df3-487a-9011-22eba4e614d6" }

Does this mean that I need to develop my own logic for verifying the token sent via email during the signup process? If so, could you provide guidance or best practices for implementing this logic effectively?

And thank you for your patience in answering my queries.

ottokruse commented 7 months ago

For the initial confirmation you will have to call this API: https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_ConfirmSignUp.html

I don't think that API has already been included in https://github.com/aws-samples/amazon-cognito-passwordless-auth/blob/main/client/cognito-api.ts so you'll have to code it. Should be easy enough to copy from the other API calls in there. Send us a PR if you want to add it to cognito-api.ts

fahadsadiq commented 7 months ago

@ottokruse Thank you for the guidance. I will create a PR for this soon. I've got another question. After a user confirms their email, I'm wondering if there's a way to snag the token that was sent in the email.

I want to redirect users off to another process once they've confirmed their email, without making them jump through hoops again with another verification link. Can we grab that token from the email somehow?

ottokruse commented 7 months ago

I've got another question. After a user confirms their email, I'm wondering if there's a way to snag the token that was sent in the email.

I want to redirect users off to another process once they've confirmed their email, without making them jump through hoops again with another verification link. Can we grab that token from the email somehow?

If you send the verification code from Cognito in your web application, from JavaScript, you are in full control. If you want to influence the email that is sent with the code, I believe you can change the template in the User Pool settings. And you can also configure the custom message trigger and add code that you want there: https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-custom-message.html