question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

AmplifyTotpSetup component renders broken image for QR code

See original GitHub issue

Describe the bug The QR Code image for TOTP Setup fails to render if AmplifyTotpSetup is used in AmplifyAuthenticator

To Reproduce Steps to reproduce the behavior:

  1. Create auth flow with <AmplifyAuthenticator >...</AmplifyAuthenticator>
  2. Add <AmplifyTotpSetup slot="totp-setup" /> child
  3. Register a new user or sign in with one that still needs TOTP Setup
  4. View broken qr code…

Expected behavior QR Code renders correctly with no overrides, with issuer override, with header text override, etc

Code Snippet

import React from "react";
import "./App.css";
import Amplify from "aws-amplify";
import {
  AmplifyAuthenticator,
  AmplifySignOut,
  AmplifyTotpSetup,
} from "@aws-amplify/ui-react";
import { AuthState, onAuthUIStateChange } from "@aws-amplify/ui-components";
import awsconfig from "./aws-exports";

Amplify.configure(awsconfig);

const AuthStateApp: React.FunctionComponent = () => {
  const [authState, setAuthState] = React.useState<AuthState>();
  const [user, setUser] = React.useState<object | undefined>();

  React.useEffect(() => {
    return onAuthUIStateChange((nextAuthState, authData) => {
      setAuthState(nextAuthState);
      setUser(authData);
    });
  }, []);

  return authState === AuthState.SignedIn && user ? (
    <div className="App">
      <div>Hello, {(user as any).username}</div>
      <AmplifySignOut />
    </div>
  ) : (
    <AmplifyAuthenticator >
      <AmplifyTotpSetup headerText="My Custom TOTP Setup Text" slot="totp-setup" />
    </AmplifyAuthenticator>
  );
};

export default AuthStateApp;

Screenshots

Working if you don’t use the AmplifyTotpSetup component: image

Broken with no overrides <AmplifyTotpSetup slot="totp-setup" /> image

Broken with overrides <AmplifyTotpSetup headerText="My Custom TOTP Setup Text" slot="totp-setup" /> image

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:4
  • Comments:14 (5 by maintainers)

github_iconTop GitHub Comments

3reactions
wlee221commented, Jan 24, 2021

That being said, I see that having to pass user manually is cumbersome. I’ll bring this up to the team and discuss if we can reduce this complexity.

2reactions
bwindsorcommented, Jan 16, 2021

In case it is useful to anybody, here is what I did as a temporary workaround for a custom issuer in TOTP setup until #7522 is merged:

const MyAuthenticatorWithCustomTotpIssuer: React.FC = () => {
    <AmplifyAuthenticator>
        <CustomTotpSetup />
    </AmplifyAuthenticator>
}

const CustomTotpSetup: React.FC = () => {
    // This component is a bit of a hack because slots are currently not working properly in the Amplify UI,
    // until this gets merged: https://github.com/aws-amplify/amplify-js/pull/7522
    // Because the TOTP component makes a request to AssociateSoftwareToken on mount, the default component makes
    // this request and is then immediately replaced by this component. This leads to two requests. So we delay this
    // second request by one second so that it doesn't clash with the first one and always happens afterwards, which
    // should lead to the correct QR code being displayed.
    const [user, setUser] = React.useState<CognitoUserInterface | undefined>();
    const [displayComponent, setDisplayComponent] = React.useState<boolean>(false);

    React.useEffect(() => {
        return onAuthUIStateChange((nextAuthState, authData) => {
            if (authData && nextAuthState === AuthState.TOTPSetup) {
                setUser(authData as CognitoUserInterface);
            } else {
                setUser(undefined);
            }
        });
    }, []);

    React.useEffect(() => {
        if (user) {
            const timeout = setTimeout(() => setDisplayComponent(true), 1000);
            return () => clearTimeout(timeout);
        } else {
            setDisplayComponent(false);
        }
    }, [user])

    return (
        <span slot="totp-setup">
            {displayComponent ? (
                <AmplifyTotpSetup issuer={'My Custom Issuer'} user={user} />
            ) : <div>Loading...</div>}
        </span>
    );
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

React app loads images locally, but AWS Amplify does not ...
In my case, AWS Amplify was not playing nice with SVG images. Changed them to PNG and the issue was resolved.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found