diff options
author | Sebastian <sebasjm@gmail.com> | 2022-06-09 16:11:49 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2022-06-09 16:12:18 -0300 |
commit | 3ebb1d18154375471e329f2bad40534d858cbe1e (patch) | |
tree | 5a7e5d14eb03c88eddbe0d61afa4ee1335768d65 /packages/anastasis-webui/src/pages/home | |
parent | 78b056a0b1613ef19d1d72c17fd256c2e86e6774 (diff) |
better select secret screen
Diffstat (limited to 'packages/anastasis-webui/src/pages/home')
4 files changed, 159 insertions, 29 deletions
diff --git a/packages/anastasis-webui/src/pages/home/AddingProviderScreen.tsx b/packages/anastasis-webui/src/pages/home/AddingProviderScreen.tsx index d4675f9da..6aeee9e7a 100644 --- a/packages/anastasis-webui/src/pages/home/AddingProviderScreen.tsx +++ b/packages/anastasis-webui/src/pages/home/AddingProviderScreen.tsx @@ -13,7 +13,11 @@ You should have received a copy of the GNU Affero General Public License along with GNU Anastasis; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { AuthenticationProviderStatusOk } from "@gnu-taler/anastasis-core"; +import { + AuthenticationProviderStatus, + AuthenticationProviderStatusError, + AuthenticationProviderStatusOk, +} from "@gnu-taler/anastasis-core"; import { h, VNode } from "preact"; import { useEffect, useRef, useState } from "preact/hooks"; import { TextInput } from "../../components/fields/TextInput.js"; @@ -38,7 +42,6 @@ async function testProvider( "This provider doesn't have authentication method. Check the provider URL", ); } - console.log("expected", expectedMethodType); if (!expectedMethodType) { return; } @@ -68,8 +71,10 @@ export function AddingProviderScreen({ providerType, onCancel }: Props): VNode { const reducer = useAnastasisContext(); const [providerURL, setProviderURL] = useState(""); + const [error, setError] = useState<string | undefined>(); const [testing, setTesting] = useState(false); + const providerLabel = providerType ? authMethods[providerType].label : undefined; @@ -81,19 +86,32 @@ export function AddingProviderScreen({ providerType, onCancel }: Props): VNode { !reducer.currentReducerState.authentication_providers ? {} : reducer.currentReducerState.authentication_providers; - const authProviders = Object.keys(allAuthProviders).filter((provUrl) => { - const p = allAuthProviders[provUrl]; - if (!providerLabel) { - return p && "currency" in p; - } else { - return ( - p && - "currency" in p && + + const authProvidersByStatus = Object.keys(allAuthProviders).reduce( + (prev, url) => { + const p = allAuthProviders[url]; + if ( + providerLabel && + p.status === "ok" && p.methods.findIndex((m) => m.type === providerType) !== -1 - ); - } - }); + ) { + return prev; + } + const others = prev[p.status] ? prev[p.status] : []; + others.push({ ...p, url }); + return { + ...prev, + [p.status]: others, + }; + }, + {} as Record< + AuthenticationProviderStatus["status"], + (AuthenticationProviderStatus & { url: string })[] + >, + ); + const authProviders = authProvidersByStatus["ok"].map((p) => p.url); + console.log("rodos", allAuthProviders); //FIXME: move this timeout logic into a hook const timeout = useRef<number | undefined>(undefined); useEffect(() => { @@ -211,6 +229,17 @@ export function AddingProviderScreen({ providerType, onCancel }: Props): VNode { <TableRow key={k} url={k} info={p} onDelete={deleteProvider} /> ); })} + {authProvidersByStatus["error"]?.map((k) => { + const p = k as AuthenticationProviderStatusError; + return ( + <TableRowError + key={k} + url={k.url} + info={p} + onDelete={deleteProvider} + /> + ); + })} </div> </AnastasisClientFrame> ); @@ -277,3 +306,62 @@ function TableRow({ </div> ); } + +function TableRowError({ + url, + info, + onDelete, +}: { + onDelete: (s: string) => void; + url: string; + info: AuthenticationProviderStatusError; +}): VNode { + const [status, setStatus] = useState("checking"); + useEffect(function () { + testProvider(url.endsWith("/") ? url.substring(0, url.length - 1) : url) + .then(function () { + setStatus("responding"); + }) + .catch(function () { + setStatus("failed to contact"); + }); + }); + return ( + <div + class="box" + style={{ display: "flex", justifyContent: "space-between" }} + > + <div> + <div class="subtitle">{url}</div> + <dl> + <dt> + <b>Error</b> + </dt> + <dd>{info.hint}</dd> + <dt> + <b>Code</b> + </dt> + <dd>{info.code}</dd> + <dt> + <b>Status</b> + </dt> + <dd>{status}</dd> + </dl> + </div> + <div + class="block" + style={{ + marginTop: "auto", + marginBottom: "auto", + display: "flex", + justifyContent: "space-between", + flexDirection: "column", + }} + > + <button class="button is-danger" onClick={() => onDelete(url)}> + Remove + </button> + </div> + </div> + ); +} diff --git a/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.tsx b/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.tsx index ebfe2821a..7d92bcd2c 100644 --- a/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.tsx +++ b/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.tsx @@ -91,20 +91,64 @@ export function SecretSelectionScreen(): VNode { title="Recovery: Select secret" hideNext="Please select version to recover" > - <p>Found versions:</p> - {policies.map((version, i) => ( - <div key={i}> - {version.policy_hash} / {version.secret_name} - <button - onClick={async () => { - await reducer.transition("select_version", version); - }} - > - Recover - </button> + <div class="columns"> + <div class="column"> + <p class="block">Found versions:</p> + {policies.map((version, i) => ( + <div key={i} class="box"> + <div + class="block" + style={{ display: "flex", justifyContent: "space-between" }} + > + <div + style={{ + display: "flex", + flexDirection: "column", + }} + > + <div style={{ display: "flex", alignItems: "center" }}> + <b>Name:</b> <span>{version.secret_name}</span> + </div> + <div style={{ display: "flex", alignItems: "center" }}> + <b>Id:</b> + <span + class="icon has-tooltip-top" + data-tooltip={version.policy_hash + .match(/(.{22})/g) + ?.join("\n")} + > + <i class="mdi mdi-information" /> + </span> + <span>{version.policy_hash.substring(0, 22)}...</span> + </div> + </div> + + <div> + <AsyncButton + class="button" + onClick={() => + reducer.transition("select_version", version) + } + > + Recover + </AsyncButton> + </div> + </div> + </div> + ))} </div> - ))} - <button>Load older versions</button> + <div class="column"> + <p> + Secret found, you can select another version or continue to the + challenges solving + </p> + <p class="block"> + <a onClick={() => setManageProvider(true)}> + Manage recovery providers + </a> + </p> + </div> + </div> </AnastasisClientFrame> ); } diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.tsx index 609cb6264..0ce0e1016 100644 --- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.tsx +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.tsx @@ -85,7 +85,6 @@ export function AuthMethodTotpSolve(props: AuthMethodSolveProps): VNode { const feedback = challengeFeedback[selectedUuid]; async function onNext(): Promise<void> { - console.log(`sending TOTP code '${answerCode}'`); return reducer?.transition("solve_challenge", { answer: answerCode, }); diff --git a/packages/anastasis-webui/src/pages/home/index.tsx b/packages/anastasis-webui/src/pages/home/index.tsx index 48bb99c9b..57f935bd6 100644 --- a/packages/anastasis-webui/src/pages/home/index.tsx +++ b/packages/anastasis-webui/src/pages/home/index.tsx @@ -146,7 +146,7 @@ export function AnastasisClientFrame(props: AnastasisClientFrameProps): VNode { const handleKeyPress = ( e: h.JSX.TargetedKeyboardEvent<HTMLDivElement>, ): void => { - console.log("Got key press", e.key); + // console.log("Got key press", e.key); // FIXME: By default, "next" action should be executed here }; @@ -227,7 +227,6 @@ function AnastasisClientImpl(): VNode { if (!state) { return <StartScreen />; } - console.log("state", reducer.currentReducerState); if ( (state.reducer_type === "backup" && |