aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.42k stars 2.12k forks source link

confirmSignIn() Documention #13598

Open vincedbowen opened 2 months ago

vincedbowen commented 2 months ago

Is this related to a new or existing framework?

React Native

Is this related to a new or existing API?

Authentication

Is this related to another service?

Cognito

Describe the feature you'd like to request

Hi team!

I think a documentation update for the confirmSignIn() method of the Amplify SDK would be great for users. Currently when signing in unconfirmed users, the documentation says confirmSignIn() should be called. Per the docs, "CONFIRM_SIGN_IN_WITH_NEW_PASSWORD_REQUIRED - The user was created with a temporary password and must set a new one. Complete the process with confirmSignIn", however, there is no further mention of how to call this function. I know I need to pass in a challengeResponse, but I am not sure of how to go about this.

Describe the solution you'd like

I would like updated documentation of how to call confirmSignIn() to reset a user's temporary password and set required attributes in the Cognito pool.

Describe alternatives you've considered

I have tried to update user attributes and reset the user's password individually, using those methods respectively. However, this doesn't work, as the user is not authenticated.

Additional context

Is this something that you'd be interested in working on?

cwomack commented 2 months ago

Hey, @vincedbowen 👋. Sorry to hear you're running into this, and we appreciate you creating this issue in the event we have a gap in our documentation. Just to be clear, was the user in this scenario made within the Cognito console manually? And is the request here to provide better documentation on how to handle this scenario when you need to call confirmSignIn() when you have the CONFIRM_SIGN_IN_WITH_NEW_PASSWORD_REQUIRED as the API response?

To be clear, signIn() must always be called before confirmSignIn(), but I think we could potentially improve this section of our docs to make this more clear. The user should have a temporary password that was given (if made within the Cognito console), but we want to better understand how to get into this scenario. Can you help me understand why there is no expected code/email sent?

cwomack commented 2 months ago

@vincedbowen, just to follow up on this... you'll still need to have signIn() called with the temporary password (the above comment is trying to better understand why we're missing that), but then we'd called confirmSignIn() subsequently to then pass in a new password for the user as seen here.

Either way, I agree that the docs could use the example linked above for better clarity on this flow.

vincedbowen commented 2 months ago

Hey, @vincedbowen 👋. Sorry to hear you're running into this, and we appreciate you creating this issue in the event we have a gap in our documentation. Just to be clear, was the user in this scenario made within the Cognito console manually? And is the request here to provide better documentation on how to handle this scenario when you need to call confirmSignIn() when you have the CONFIRM_SIGN_IN_WITH_NEW_PASSWORD_REQUIRED as the API response?

To be clear, signIn() must always be called before confirmSignIn(), but I think we could potentially improve this section of our docs to make this more clear. The user should have a temporary password that was given (if made within the Cognito console), but we want to better understand how to get into this scenario. Can you help me understand why there is no expected code/email sent?

Hi @cwomack! Thanks so much for the quick reply 😊.

Yes, the user was made in the Console manually, to simulate users being imported from another database (app migration in an organization).

For your second question, yes my request is the documentation have a clearer example of calling confirmSingIn() when CONFIRM_SIGN_IN_WITH_NEW_PASSWORD_REQUIRED is the nextStep in the API response!

Finally, no verification code should be sent out because their email is verified when manually entered in the Cognito pool, in which they are sent an invite with there username and temporary password (which does occur as expected).

vincedbowen commented 2 months ago

@vincedbowen, just to follow up on this... you'll still need to have signIn() called with the temporary password (the above comment is trying to better understand why we're missing that), but then we'd called confirmSignIn() subsequently to then pass in a new password for the user as seen here.

Either way, I agree that the docs could use the example linked above for better clarity on this flow.

Yes, I am calling signIn() regardless of if the user is confirmed or not.

I hope this clarifies the flow, but if not, please let me know!

The only way I have found to be able to pass in these arguments to confirmSignIn() semi-successfully is like such:

const challengeResponse = newPassword;
await confirmSignIn({ challengeResponse });

When I inspect the network logs for this call to Cognito, I see something like this:

{ChallengeName: NEW_PASSWORD_REQUIRED,
    ChallengeResponse: {
        USERNAME: <username>,
        NEW_PASSWORD: <newPassword>},
    SessionId: <sessionId>,
    ClientId: <clientId>}

However, even when passing in userAttributes in a manner similar to the provided example, they never end up in the request to Cognito, and expectedly, I get a missing parameter error.

ashika112 commented 2 months ago

@vincedbowen on this last bit,

However, even when passing in userAttributes in a manner similar to the provided example, they never end up in the request to Cognito, and expectedly, I get a missing parameter error.

are you asking how to pass in userAttributes during confirmSignIn?

vincedbowen commented 2 months ago

@vincedbowen on this last bit,

However, even when passing in userAttributes in a manner similar to the provided example, they never end up in the request to Cognito, and expectedly, I get a missing parameter error.

are you asking how to pass in userAttributes during confirmSignIn?

Yes, I am. I think the documentation is a bit unclear here.

ZaneAridi1022 commented 2 weeks ago

@vincedbowen Did you ever figure this out? I have reached the same place in my authentication flow and I don't quite understand what parameters we need to pass here. Do we just pass in the temporary password as the challenge response and then call the resetPassword function? If not, where do we pass the new password into the confirmSignIn function? Any updates on this @ashika112 @cwomack.

vincedbowen commented 2 weeks ago

@vincedbowen Did you ever figure this out? I have reached the same place in my authentication flow and I don't quite understand what parameters we need to pass here. Do we just pass in the temporary password as the challenge response and then call the resetPassword function? If not, where do we pass the new password into the confirmSignIn function? Any updates on this @ashika112 @cwomack.

No, I ended up creating a new Cognito pool with the attributes I wanted as optional (since I was controlling the applications login flow). Then I just only passed in the new password, and once logged in, I just updated the attributes from the form immediately. Not an ideal solution, but it worked for the MVP I was developing, and I was tired of debugging lol 😅.

matepapp commented 2 weeks ago

@vincedbowen Did you ever figure this out? I have reached the same place in my authentication flow and I don't quite understand what parameters we need to pass here. Do we just pass in the temporary password as the challenge response and then call the resetPassword function? If not, where do we pass the new password into the confirmSignIn function? Any updates on this @ashika112 @cwomack.

I did exactly that, and it worked. The only issue I encountered was that I initially wanted to call the signIn and confirmSignIn methods on the server side (within a Server Action in Next.js), but it couldn't find the auth pool. Falling back to the client side solved the problem.

vincedbowen commented 1 week ago

@vincedbowen Did you ever figure this out? I have reached the same place in my authentication flow and I don't quite understand what parameters we need to pass here. Do we just pass in the temporary password as the challenge response and then call the resetPassword function? If not, where do we pass the new password into the confirmSignIn function? Any updates on this @ashika112 @cwomack.

I did exactly that, and it worked. The only issue I encountered was that I initially wanted to call the signIn and confirmSignIn methods on the server side (within a Server Action in Next.js), but it couldn't find the auth pool. Falling back to the client side solved the problem.

Glad you figured it out! So did you end up using USER_SRP_AUTH? I am pretty sure that is the recommended security practice as the password never leaves the client.