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

Auth.resendSignUp does not work with email #9872

Closed KristianLake closed 9 months ago

KristianLake commented 2 years ago

Before opening, please confirm:

JavaScript Framework

React

Amplify APIs

Authentication

Amplify Categories

auth

Environment information

``` # Put output below this line System: OS: Linux 5.10 Ubuntu 20.04.2 LTS (Focal Fossa) CPU: (20) x64 Intel(R) Core(TM) i9-10850K CPU @ 3.60GHz Memory: 90.50 GB / 100.52 GB Container: Yes Shell: 5.0.17 - /bin/bash Binaries: Node: 14.17.0 - ~/.nvm/versions/node/v14.17.0/bin/node Yarn: 1.22.17 - /usr/bin/yarn npm: 8.5.0 - ~/.nvm/versions/node/v14.17.0/bin/npm npmPackages: @chainlink/contracts: ^0.4.0 => 0.4.0 @craco/craco: ^6.4.3 => 6.4.3 @openzeppelin/contracts: ^4.5.0 => 4.5.0 @radix-ui/react-dropdown-menu: ^0.1.6 => 0.1.6 @radix-ui/react-popover: ^0.1.6 => 0.1.6 @sentry/browser: ^6.17.3 => 6.18.1 @sentry/react: ^6.17.3 => 6.18.1 @sentry/tracing: ^6.17.3 => 6.18.1 @sentry/types: ^6.17.3 => 6.18.1 @serverless-stack/static-site-env: ^0.60.11 => 0.60.11 @serverless-stack/static-site-env-test-base: 0.60.11 @serverless-stack/static-site-env-test-sst-app-not-exist: 0.60.11 @serverless-stack/static-site-env-test-sst-env-outputs-file-not-exist: 0.60.11 @serverless-stack/static-site-env-test-sst-env-outputs-not-found: 0.60.11 @testing-library/cypress: ^8.0.2 => 8.0.2 @testing-library/jest-dom: ^5.16.1 => 5.16.2 @testing-library/react: ^12.1.2 => 12.1.3 @testing-library/user-event: ^13.5.0 => 13.5.0 @truffle/hdwallet-provider: ^2.0.3 => 2.0.3 @types/jest: ^27.4.0 => 27.4.1 (26.0.24) @types/node: ^16.11.22 => 16.11.26 (10.17.60, 14.18.12) @types/react: ^17.0.38 => 17.0.39 @types/react-dom: ^17.0.11 => 17.0.13 @types/react-router-dom: ^5.3.3 => 5.3.3 @types/styled-components: ^5.1.24 => 5.1.24 @types/uuid: ^8.3.4 => 8.3.4 @typescript-eslint/eslint-plugin: ^5.10.2 => 5.13.0 @typescript-eslint/parser: ^5.10.2 => 5.13.0 aws-amplify: ^4.3.14 => 4.3.15 babel-polyfill: 6.26.0 => 6.26.0 babel-preset-env: 1.7.0 => 1.7.0 babel-preset-es2015: 6.24.1 => 6.24.1 babel-preset-stage-2: 6.24.1 => 6.24.1 babel-preset-stage-3: 6.24.1 => 6.24.1 babel-register: 6.26.0 => 6.26.0 bootstrap: ^5.1.3 => 5.1.3 chai: ^4.3.6 => 4.3.6 chai-as-promised: ^7.1.1 => 7.1.1 cypress: ^9.5.2 => 9.5.2 eslint: ^8.8.0 => 8.10.0 eslint-config-airbnb: ^19.0.4 => 19.0.4 eslint-config-airbnb-typescript-prettier: ^5.0.0 => 5.0.0 eslint-plugin-cypress: ^2.12.1 => 2.12.1 eslint-plugin-import: ^2.25.4 => 2.25.4 eslint-plugin-jsx-a11y: ^6.5.1 => 6.5.1 eslint-plugin-react: ^7.28.0 => 7.29.3 eslint-plugin-react-hooks: ^4.3.0 => 4.3.0 framer-motion: ^6.2.8 => 6.2.8 prettier: ^2.5.1 => 2.5.1 react: ^17.0.2 => 17.0.2 react-bootstrap: ^2.1.2 => 2.2.0 react-bootstrap/AbstractModalHeader: undefined () react-bootstrap/Accordion: undefined () react-bootstrap/AccordionBody: undefined () react-bootstrap/AccordionButton: undefined () react-bootstrap/AccordionCollapse: undefined () react-bootstrap/AccordionContext: undefined () react-bootstrap/AccordionHeader: undefined () react-bootstrap/AccordionItem: undefined () react-bootstrap/AccordionItemContext: undefined () react-bootstrap/Alert: undefined () react-bootstrap/Anchor: undefined () react-bootstrap/Badge: undefined () react-bootstrap/BootstrapModalManager: undefined () react-bootstrap/Breadcrumb: undefined () react-bootstrap/BreadcrumbItem: undefined () react-bootstrap/Button: undefined () react-bootstrap/ButtonGroup: undefined () react-bootstrap/ButtonToolbar: undefined () react-bootstrap/Card: undefined () react-bootstrap/CardGroup: undefined () react-bootstrap/CardHeader: undefined () react-bootstrap/CardHeaderContext: undefined () react-bootstrap/CardImg: undefined () react-bootstrap/Carousel: undefined () react-bootstrap/CarouselCaption: undefined () react-bootstrap/CarouselItem: undefined () react-bootstrap/CloseButton: undefined () react-bootstrap/Col: undefined () react-bootstrap/Collapse: undefined () react-bootstrap/Container: undefined () react-bootstrap/Dropdown: undefined () react-bootstrap/DropdownButton: undefined () react-bootstrap/DropdownContext: undefined () react-bootstrap/DropdownItem: undefined () react-bootstrap/DropdownMenu: undefined () react-bootstrap/DropdownToggle: undefined () react-bootstrap/ElementChildren: undefined () react-bootstrap/Fade: undefined () react-bootstrap/Feedback: undefined () react-bootstrap/Figure: undefined () react-bootstrap/FigureCaption: undefined () react-bootstrap/FigureImage: undefined () react-bootstrap/FloatingLabel: undefined () react-bootstrap/Form: undefined () react-bootstrap/FormCheck: undefined () react-bootstrap/FormCheckInput: undefined () react-bootstrap/FormCheckLabel: undefined () react-bootstrap/FormContext: undefined () react-bootstrap/FormControl: undefined () react-bootstrap/FormFloating: undefined () react-bootstrap/FormGroup: undefined () react-bootstrap/FormLabel: undefined () react-bootstrap/FormRange: undefined () react-bootstrap/FormSelect: undefined () react-bootstrap/FormText: undefined () react-bootstrap/Image: undefined () react-bootstrap/InputGroup: undefined () react-bootstrap/InputGroupContext: undefined () react-bootstrap/ListGroup: undefined () react-bootstrap/ListGroupItem: undefined () react-bootstrap/Modal: undefined () react-bootstrap/ModalBody: undefined () react-bootstrap/ModalContext: undefined () react-bootstrap/ModalDialog: undefined () react-bootstrap/ModalFooter: undefined () react-bootstrap/ModalHeader: undefined () react-bootstrap/ModalTitle: undefined () react-bootstrap/Nav: undefined () react-bootstrap/NavContext: undefined () react-bootstrap/NavDropdown: undefined () react-bootstrap/NavItem: undefined () react-bootstrap/NavLink: undefined () react-bootstrap/Navbar: undefined () react-bootstrap/NavbarBrand: undefined () react-bootstrap/NavbarCollapse: undefined () react-bootstrap/NavbarContext: undefined () react-bootstrap/NavbarOffcanvas: undefined () react-bootstrap/NavbarToggle: undefined () react-bootstrap/Offcanvas: undefined () react-bootstrap/OffcanvasBody: undefined () react-bootstrap/OffcanvasHeader: undefined () react-bootstrap/OffcanvasTitle: undefined () react-bootstrap/OffcanvasToggling: undefined () react-bootstrap/Overlay: undefined () react-bootstrap/OverlayTrigger: undefined () react-bootstrap/PageItem: undefined () react-bootstrap/Pagination: undefined () react-bootstrap/Placeholder: undefined () react-bootstrap/PlaceholderButton: undefined () react-bootstrap/Popover: undefined () react-bootstrap/PopoverBody: undefined () react-bootstrap/PopoverHeader: undefined () react-bootstrap/ProgressBar: undefined () react-bootstrap/Ratio: undefined () react-bootstrap/Row: undefined () react-bootstrap/SSRProvider: undefined () react-bootstrap/Spinner: undefined () react-bootstrap/SplitButton: undefined () react-bootstrap/Stack: undefined () react-bootstrap/Switch: undefined () react-bootstrap/Tab: undefined () react-bootstrap/TabContainer: undefined () react-bootstrap/TabContent: undefined () react-bootstrap/TabPane: undefined () react-bootstrap/Table: undefined () react-bootstrap/Tabs: undefined () react-bootstrap/ThemeProvider: undefined () react-bootstrap/Toast: undefined () react-bootstrap/ToastBody: undefined () react-bootstrap/ToastContainer: undefined () react-bootstrap/ToastContext: undefined () react-bootstrap/ToastFade: undefined () react-bootstrap/ToastHeader: undefined () react-bootstrap/ToggleButton: undefined () react-bootstrap/ToggleButtonGroup: undefined () react-bootstrap/Tooltip: undefined () react-bootstrap/TransitionWrapper: undefined () react-bootstrap/createChainedFunction: undefined () react-bootstrap/createUtilityClasses: undefined () react-bootstrap/createWithBsPrefix: undefined () react-bootstrap/divWithClassName: undefined () react-bootstrap/getTabTransitionComponent: undefined () react-bootstrap/helpers: undefined () react-bootstrap/safeFindDOMNode: undefined () react-bootstrap/transitionEndListener: undefined () react-bootstrap/triggerBrowserReflow: undefined () react-bootstrap/types: undefined () react-bootstrap/useOverlayOffset: undefined () react-bootstrap/usePlaceholder: undefined () react-bootstrap/useWrappedRefWithWarning: undefined () react-dom: ^17.0.2 => 17.0.2 react-hook-form: ^7.27.0 => 7.27.1 react-icons: ^4.3.1 => 4.3.1 react-router-bootstrap: ^0.25.0 => 0.25.0 react-router-dom: ^5.2.0 => 5.3.0 react-scripts: 5.0.0 => 5.0.0 styled-components: ^5.3.3 => 5.3.3 styled-components/macro: undefined () styled-components/native: undefined () styled-components/primitives: undefined () typescript: ^4.6.2 => 4.6.2 uuid: ^8.3.2 => 8.3.2 (3.4.0, 3.3.2) web-vitals: ^2.1.4 => 2.1.4 npmGlobalPackages: fkill-cli: 6.1.0 ganache-cli: 6.12.2 ipfs: 0.55.4 npm-check: 5.9.2 npm-upgrade: 3.1.0 npm: 8.5.0 truffle: 5.4.2 ```

Describe the bug

This is while the user status is unconfirmed.

             Auth.resendSignUp("test.example.com").then(data => {
                console.log(data)
              })

returns UserNotFoundException: Username/client id combination not found.

Expected behavior

It should know that email can be used to resend code.

Reproduction steps

  1. register a new user in cognito using
        await Auth.signUp({
        username: data.name,
        password: data.password,
        attributes: {
          email: data.email,
        },
        validationData: [] 
        })
  2. do not input the verification code
  3. attempt to resend the verification code
              Auth.resendSignUp("test.example.com").then(data => {
                console.log(data)
              })
nadetastic commented 2 years ago

Hi @KristianLake,

Upon reviewing this, I have a few question for you - can you please confirm the following:

  1. Can you confirm the SignUp experience you have configured? i.e. Do users sign up with a username or email? You can confirm this by going into your UserPool in the Cognito console, and under Sign-in experience look at Cognito user pool sign-in options

  2. In the reproduction steps above, I see the username passed to Auth.resendSignUp() is not an email - is this a typo? If not, note that this would need to be an email if your signup experience is set to email.

  3. Also you can you share the users info that you are attempting to resend the code to as seen in Cognito?

The resendSignUp() takes a username as a parameter. So if you have your signup experience set to User name, that will be the username they entered on signUp, however if it is setup to be email, it will be the email a user entered. Also, note that the username can be different from the email configured under the users attributes.

KristianLake commented 2 years ago

Sure, so im using sst and my configuration is completely done IAAC.

 const auth = new Auth(stack, "Auth", {
    triggers: {
      customMessage: {
        handler: "services/cognito/customMessage.main",
        environment: { TABLE_NAME: table.tableName },
        permissions: [table],
      },
      preSignUp: {
        handler: "services/cognito/preSignUp.main",
      },
      postConfirmation: {
        handler: "services/cognito/postConfirmation.main",
        environment: { TABLE_NAME: table.tableName },
        permissions: [table],
      },
    },
    cdk: {
      userPool: {
        email: cognito.UserPoolEmail.withSES({
          sesRegion: 'us-east-2',
          fromEmail: 'noreply@example.com',
          fromName: `${stack.stage.toLowerCase() === "prod" ? "" : stack.stage.toLowerCase()} Support`,
          replyTo: 'support@example.com',
          sesVerifiedDomain: 'example.com',
        }),
        deviceTracking: {
          challengeRequiredOnNewDevice: true,
          deviceOnlyRememberedOnUserPrompt: true,
        },
        // Users can login with their email and password
        signInAliases: { 
          username: true,
          email: true,
        },
      },      
    },
})

  auth.attachPermissionsForTrigger("preSignUp", ["cognito-idp:ListUsers"]);
  auth.attachPermissionsForTrigger("postConfirmation", ["ses:SendEmail"]);

So as you can see users can login with their email AND username.

So if a user elects to login with their username but they have not yet confirmed via email (during register they provided username and email) there is no easy way to wire up the Auth.resendSignUp( as during login they provided the username only and you can't get the email (as they did not submit it) So short of taking the username and running though a custom gateway api call to "get me the email for this username" to then pass into resendSignUp - which adds a delay, a possible security vector and additional network calls though AWS.

Alexei-Lashakov commented 2 years ago

@nadetastic @nickarocho Guys, do you have any updates?

nadetastic commented 9 months ago

Hi @KristianLake following up here - based on the error message UserNotFoundException: Username/client id there's either a mismatch with the userpool client that the client app is using verses where the user is actually sign up in. On way to check this is to verify the values being passed into Amplify.configure(). If the userpool, or userpoolClient do not match this will cause this issue.

Are you still experiencing this problem?

cc @Alexei-Lashakov

cwomack commented 9 months ago

Closing this issue as we have not heard back from you. If you are still experiencing this, please feel free to reply back and provide any information previously requested and we'd be happy to re-open the issue.

Thank you!