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.41k stars 2.11k forks source link

Amplify V6 -- signin and confirmsignin cannot work separatly? #13175

Open zcemycl opened 4 months ago

zcemycl commented 4 months ago

Before opening, please confirm:

JavaScript Framework

Next.js

Amplify APIs

Authentication

Amplify Version

v6

Amplify Categories

auth

Backend

Other

Environment information

``` # Put output below this line System: OS: macOS 14.4 CPU: (8) arm64 Apple M1 Memory: 70.72 MB / 8.00 GB Shell: 5.9 - /bin/zsh Binaries: Node: 20.10.0 - ~/.nvm/versions/node/v20.10.0/bin/node npm: 10.2.3 - ~/.nvm/versions/node/v20.10.0/bin/npm Browsers: Chrome: 123.0.6312.59 Safari: 17.4 npmPackages: @ampproject/toolbox-optimizer: undefined () @aws-amplify/adapter-nextjs: ^1.0.21 => 1.0.21 @aws-amplify/adapter-nextjs/api: undefined () @aws-amplify/adapter-nextjs/data: undefined () @aws-sdk/client-cognito-identity: ^3.540.0 => 3.540.0 @aws-sdk/client-cognito-identity-provider: ^3.540.0 => 3.540.0 @babel/core: undefined () @babel/runtime: 7.22.5 @edge-runtime/cookies: 4.1.0 @edge-runtime/ponyfill: 2.4.2 @edge-runtime/primitives: 4.1.0 @hapi/accept: undefined () @mswjs/interceptors: undefined () @napi-rs/triples: undefined () @next/font: undefined () @next/react-dev-overlay: undefined () @opentelemetry/api: undefined () @types/node: ^20 => 20.11.30 @types/react: ^18 => 18.2.67 @types/react-dom: ^18 => 18.2.22 @vercel/nft: undefined () @vercel/og: 0.6.2 acorn: undefined () amphtml-validator: undefined () anser: undefined () arg: undefined () assert: undefined () async-retry: undefined () async-sema: undefined () autoprefixer: ^10.0.1 => 10.4.19 aws-amplify: ^6.0.21 => 6.0.21 aws-amplify/adapter-core: undefined () aws-amplify/analytics: undefined () aws-amplify/analytics/kinesis: undefined () aws-amplify/analytics/kinesis-firehose: undefined () aws-amplify/analytics/personalize: undefined () aws-amplify/analytics/pinpoint: undefined () aws-amplify/api: undefined () aws-amplify/api/server: undefined () aws-amplify/auth: undefined () aws-amplify/auth/cognito: undefined () aws-amplify/auth/cognito/server: undefined () aws-amplify/auth/enable-oauth-listener: undefined () aws-amplify/auth/server: undefined () aws-amplify/data: undefined () aws-amplify/data/server: undefined () aws-amplify/datastore: undefined () aws-amplify/in-app-messaging: undefined () aws-amplify/in-app-messaging/pinpoint: undefined () aws-amplify/push-notifications: undefined () aws-amplify/push-notifications/pinpoint: undefined () aws-amplify/storage: undefined () aws-amplify/storage/s3: undefined () aws-amplify/storage/s3/server: undefined () aws-amplify/storage/server: undefined () aws-amplify/utils: undefined () babel-packages: undefined () browserify-zlib: undefined () browserslist: undefined () buffer: undefined () bytes: undefined () ci-info: undefined () cli-select: undefined () client-only: 0.0.1 comment-json: undefined () compression: undefined () conf: undefined () constants-browserify: undefined () content-disposition: undefined () content-type: undefined () cookie: undefined () cross-spawn: undefined () crypto-browserify: undefined () css.escape: undefined () data-uri-to-buffer: undefined () debug: undefined () devalue: undefined () domain-browser: undefined () dotenv: ^16.4.5 => 16.4.5 edge-runtime: undefined () eslint: ^8.57.0 => 8.57.0 eslint-config-next: 14.1.4 => 14.1.4 eslint-config-prettier: ^9.1.0 => 9.1.0 events: undefined () find-cache-dir: undefined () find-up: undefined () fresh: undefined () get-orientation: undefined () glob: undefined () gzip-size: undefined () http-proxy: undefined () http-proxy-agent: undefined () https-browserify: undefined () https-proxy-agent: undefined () icss-utils: undefined () ignore-loader: undefined () image-size: undefined () is-animated: undefined () is-docker: undefined () is-wsl: undefined () jest-worker: undefined () json5: undefined () jsonwebtoken: undefined () loader-runner: undefined () loader-utils: undefined () lodash.curry: undefined () lru-cache: undefined () micromatch: undefined () mini-css-extract-plugin: undefined () nanoid: undefined () native-url: undefined () neo-async: undefined () next: 14.1.4 => 14.1.4 next-auth: ^4.24.7 => 4.24.7 next-themes: ^0.3.0 => 0.3.0 node-fetch: undefined () node-html-parser: undefined () ora: undefined () os-browserify: undefined () p-limit: undefined () path-browserify: undefined () platform: undefined () postcss: ^8 => 8.4.38 (8.4.31) postcss-flexbugs-fixes: undefined () postcss-modules-extract-imports: undefined () postcss-modules-local-by-default: undefined () postcss-modules-scope: undefined () postcss-modules-values: undefined () postcss-preset-env: undefined () postcss-safe-parser: undefined () postcss-scss: undefined () postcss-value-parser: undefined () prettier: ^3.2.5 => 3.2.5 process: undefined () punycode: undefined () querystring-es3: undefined () raw-body: undefined () react: ^18 => 18.2.0 react-builtin: undefined () react-dom: ^18 => 18.2.0 react-dom-builtin: undefined () react-dom-experimental-builtin: undefined () react-experimental-builtin: undefined () react-is: 18.2.0 react-refresh: 0.12.0 react-server-dom-turbopack-builtin: undefined () react-server-dom-turbopack-experimental-builtin: undefined () react-server-dom-webpack-builtin: undefined () react-server-dom-webpack-experimental-builtin: undefined () regenerator-runtime: 0.13.4 sass-loader: undefined () scheduler-builtin: undefined () scheduler-experimental-builtin: undefined () schema-utils: undefined () semver: undefined () send: undefined () server-only: 0.0.1 setimmediate: undefined () sharp: ^0.33.2 => 0.33.2 shell-quote: undefined () source-map: undefined () stacktrace-parser: undefined () stream-browserify: undefined () stream-http: undefined () string-hash: undefined () string_decoder: undefined () strip-ansi: undefined () superstruct: undefined () tailwindcss: ^3.3.0 => 3.4.1 tar: undefined () terser: undefined () text-table: undefined () timers-browserify: undefined () ts-node: ^10.9.2 => 10.9.2 tty-browserify: undefined () typescript: ^5 => 5.4.3 ua-parser-js: undefined () unistore: undefined () util: undefined () vm-browserify: undefined () watchpack: undefined () web-vitals: undefined () webpack: undefined () webpack-sources: undefined () ws: undefined () zod: undefined () npmGlobalPackages: @aws-amplify/cli: 12.10.1 corepack: 0.22.0 npm: 10.2.3 ```

Describe the bug

I have the following workflow,

  1. Sign in with custom challenge. The cognito will reply with a magic link.
  2. Click on the magic link will open up a new tab to send confirmsignin.

That will not work because amplify v6 needs signin and confirmsignin command from 'aws-amplify/auth' to be placed in the same function so that the next step in signin can continue.

However, from "@aws-sdk/client-cognito-identity" package, InitiateAuthCommand and RespondToAuthChallengeCommand can be separated in callbacks by session id.

Expected behavior

Allow signIn and confirmSignIn to be separated.

Reproduction steps

  1. Install aws-amplify v6
  2. Create two scripts. One script just to use signIn, another just to use confirmSignIn.

Code Snippet

// Put your code below this line.
  async function amplifySignIn(email: string) {
    const resp = await login({
      username: email,
      options: { authFlowType: "CUSTOM_WITHOUT_SRP" },
    });
    return resp;
  }

  async function amplifyConfirmSignIn(email: string, code: string) {
    const resp = await confirmSignIn({
      challengeResponse: code,
    });
  }

Log output

``` // Put your logs below this line confirmSignIn.mjs:58 Uncaught (in promise) SignInException: An error occurred during the sign in process. This most likely occurred due to: 1. signIn was not called before confirmSignIn. 2. signIn threw an exception. 3. page was refreshed during the sign in flow. ```

aws-exports.js

No response

Manual configuration

No response

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

No response

cwomack commented 4 months ago

Hello, @zcemycl and thanks for opening this issue. You are correct that confirmSignIn() currently needs to be called alongside signIn() due to the session information and challengeResponse being required as part of the confirmation flow.

Are you able to provide more context around what the use case is here or why you're needing to call these separately in the authentication flow? Thanks!

zcemycl commented 4 months ago

@cwomack for example, this one from aws tutorial https://aws.amazon.com/blogs/mobile/implementing-passwordless-email-authentication-with-amazon-cognito/ .

I can replicate that tutorial with "@aws-sdk/client-cognito-identity-provider" but "aws-amplify" is not working.

cwomack commented 4 months ago

Related to #10469.

@zcemycl can you review that issue I linked above to see if it would encompass what you're asking for in this issue?

zcemycl commented 4 months ago

@cwomack I can confirm it is similar, except that issue is from v5 amplify.sendCustomChallengeAnswer . But v5 can integrate nicer with amazon-cognito-identity-js (v2) to solve that issue.

My current issue is based on v6 and i can't see any examples of using amplify v6 and @aws-sdk/client-cognito-identity-provider v3 together.

cwomack commented 4 months ago

@zcemycl, thanks for the quick response! I've got this marked as a feature request and will review this internally with the work that is currently underway with the other issue. This may be considered a duplicate if that's the case, but we'll capture the scope (and of course v6 aspect) of what's in this issue if we consider them duplicates.

cwomack commented 4 months ago

Following up to say we'll keep both issues open and separate for now, because of the extra context here regarding the new/cross tab functionality described.

mmeylan commented 2 months ago

We have the exact same use case, where we send a magic link to our users to login without a password. With v5, we're able to serialise the user/session into local storage, and hydrate it once the user clicks on the link in the email, thanks to interop with amazon-cognito-identity-js.

Having this part of amplify auth would be extremely awesome, or else have a way we can implement it on our side.

mattiLeBlanc commented 3 weeks ago

@zcemycl @mmeylan I have magic link login working in Amplify v6, using the CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE flow and then call confirmSignIn({ challengeResponse: challenge } which will log me in.

For this to work, I have had to setup multiple hooks in Cognito to log you in when you do the custom challenge. Is this what you are looking for?

mmeylan commented 2 weeks ago

@mattiLeBlanc Does your implementation work when the magic link is opened in a new tab or after a page reload ? Here's my exact flow:

  1. User opens sign-in page, enters email (amplify signIn called)
  2. Email is sent to user with sign-in challenge in the link
  3. User clicks on link in email, new page is opened with challenge in the query params (amplify confirmSignIn({challengeResponse: challenge}) called) <-- does not work because session created by 1. does not exist.

As far as I could tell from by tests on v6, the session is stored in memory by amplify, but maybe I am missing something.

@zcemycl @mmeylan I have magic link login working in Amplify v6, using the CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE flow and then call confirmSignIn({ challengeResponse: challenge } which will log me in.

For this to work, I have had to setup multiple hooks in Cognito to log you in when you do the custom challenge. Is this what you are looking for?