| 338 | } |
| 339 | |
| 340 | function SetupAuthenticatorApp(props: SetupAuthenticatorProps) { |
| 341 | const { onSubmitCode } = props; |
| 342 | const [authenticatorDetails, setAuthenticatorDetails] = useState({ |
| 343 | sharedKey: null, |
| 344 | authenticatorUri: null |
| 345 | }); |
| 346 | const [copied, setCopied] = useState(false); |
| 347 | |
| 348 | useEffect(() => { |
| 349 | (async function () { |
| 350 | setAuthenticatorDetails(await db.mfa.setup("app")); |
| 351 | })(); |
| 352 | }, []); |
| 353 | |
| 354 | return ( |
| 355 | <VerifyAuthenticatorForm |
| 356 | codeHelpText={strings.mfaScanQrCodeHelpText()} |
| 357 | onSubmitCode={onSubmitCode} |
| 358 | > |
| 359 | <Text variant={"body"}>{strings.mfaScanQrCode()}</Text> |
| 360 | <Box sx={{ alignSelf: "center" }}> |
| 361 | {authenticatorDetails.authenticatorUri ? ( |
| 362 | <Suspense fallback={<Loading />}> |
| 363 | <QRCode |
| 364 | value={authenticatorDetails.authenticatorUri} |
| 365 | ecLevel={"M"} |
| 366 | size={150} |
| 367 | /> |
| 368 | </Suspense> |
| 369 | ) : ( |
| 370 | <Loading /> |
| 371 | )} |
| 372 | </Box> |
| 373 | <Text variant={"subBody"}>{`${strings.scanQrError()}:`}</Text> |
| 374 | <Flex |
| 375 | bg="var(--background-secondary)" |
| 376 | mt={2} |
| 377 | sx={{ borderRadius: "default", alignItems: "center" }} |
| 378 | p={1} |
| 379 | > |
| 380 | <Text |
| 381 | className="selectable" |
| 382 | ml={1} |
| 383 | sx={{ |
| 384 | flex: 1, |
| 385 | overflowWrap: "anywhere", |
| 386 | color: "paragraph", |
| 387 | fontSize: "body", |
| 388 | fontFamily: "monospace" |
| 389 | }} |
| 390 | > |
| 391 | {authenticatorDetails.sharedKey ? ( |
| 392 | authenticatorDetails.sharedKey |
| 393 | ) : ( |
| 394 | <Loading /> |
| 395 | )} |
| 396 | </Text> |
| 397 | <Button |