diff options
author | Sebastian <sebasjm@gmail.com> | 2021-11-02 10:12:52 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2021-11-02 10:13:08 -0300 |
commit | a4cdc02e5017ba587c169cb28a7e7927fc64c7cf (patch) | |
tree | ad9815e595a62524f7c29ce477877ea415125997 /packages/anastasis-webui/src/pages/home/authMethodSetup/AuthMethodTotpSetup.tsx | |
parent | 88d142d2098ad87613222e9a0c6df478a78f6528 (diff) | |
download | wallet-core-a4cdc02e5017ba587c169cb28a7e7927fc64c7cf.tar.xz |
totp qr code
Diffstat (limited to 'packages/anastasis-webui/src/pages/home/authMethodSetup/AuthMethodTotpSetup.tsx')
-rw-r--r-- | packages/anastasis-webui/src/pages/home/authMethodSetup/AuthMethodTotpSetup.tsx | 54 |
1 files changed, 44 insertions, 10 deletions
diff --git a/packages/anastasis-webui/src/pages/home/authMethodSetup/AuthMethodTotpSetup.tsx b/packages/anastasis-webui/src/pages/home/authMethodSetup/AuthMethodTotpSetup.tsx index bbffedad6..db656e630 100644 --- a/packages/anastasis-webui/src/pages/home/authMethodSetup/AuthMethodTotpSetup.tsx +++ b/packages/anastasis-webui/src/pages/home/authMethodSetup/AuthMethodTotpSetup.tsx @@ -4,36 +4,70 @@ import { stringToBytes } from "@gnu-taler/taler-util"; import { h, VNode } from "preact"; -import { useState } from "preact/hooks"; +import { useMemo, useState } from "preact/hooks"; import { AuthMethodSetupProps } from "../AuthenticationEditorScreen"; import { AnastasisClientFrame } from "../index"; import { TextInput } from "../../../components/fields/TextInput"; import { QR } from "../../../components/QR"; +import { base32enc, computeTOTPandCheck } from "./totp"; + +export function AuthMethodTotpSetup({ addAuthMethod, cancel, configured }: AuthMethodSetupProps): VNode { + const [name, setName] = useState("anastasis"); + const [test, setTest] = useState(""); + const digits = 8 + const secretKey = useMemo(() => { + const array = new Uint8Array(32) + return window.crypto.getRandomValues(array) + }, []) + const secret32 = base32enc(secretKey); + const totpURL = `otpauth://totp/${name}?digits=${digits}&secret=${secret32}` -export function AuthMethodTotpSetup({addAuthMethod, cancel, configured}: AuthMethodSetupProps): VNode { - const [name, setName] = useState(""); const addTotpAuth = (): void => addAuthMethod({ authentication_method: { type: "totp", - instructions: `Enter code for ${name}`, - challenge: encodeCrock(stringToBytes(name)), + instructions: `Enter ${digits} digits code for ${name}`, + challenge: encodeCrock(stringToBytes(totpURL)), }, }); - const errors = !name ? 'The TOTP name is missing' : undefined; + + const testCodeMatches = computeTOTPandCheck(secretKey, 8, parseInt(test, 10)); + + const errors = !name ? 'The TOTP name is missing' : ( + !testCodeMatches ? 'The test code doesnt match' : undefined + ); return ( <AnastasisClientFrame hideNav title="Add TOTP authentication"> <p> - For Time-based One-Time Password (TOTP) authentication, you need to set - a name for the TOTP secret. Then, you must scan the generated QR code + For Time-based One-Time Password (TOTP) authentication, you need to set + a name for the TOTP secret. Then, you must scan the generated QR code with your TOTP App to import the TOTP secret into your TOTP App. </p> - <div> + <div class="block"> <TextInput label="TOTP Name" grabFocus bind={[name, setName]} /> </div> - <QR text={`sometext ${name}`} /> + <div style={{ height: 300 }}> + <QR text={totpURL} /> + </div> + <p> + After scanning the code with your TOTP App, test it in the input below. + </p> + <TextInput + label="Test code" + bind={[test, setTest]} /> + {configured.length > 0 && <section class="section"> + <div class="block"> + Your TOTP numbers: + </div><div class="block"> + {configured.map((c, i) => { + return <div key={i} class="box" style={{ display: 'flex', justifyContent: 'space-between' }}> + <p style={{ marginTop: 'auto', marginBottom: 'auto' }}>{c.instructions}</p> + <div><button class="button is-danger" onClick={c.remove}>Delete</button></div> + </div> + })} + </div></section>} <div> <div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}> <button class="button" onClick={cancel}>Cancel</button> |