From 3ebb1d18154375471e329f2bad40534d858cbe1e Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 9 Jun 2022 16:11:49 -0300 Subject: [PATCH] better select secret screen --- packages/anastasis-webui/clean_and_build.sh | 9 +- packages/anastasis-webui/html/ui-dev.html | 25 +++- .../src/components/FlieButton.tsx | 1 - .../src/components/fields/FileInput.tsx | 1 - packages/anastasis-webui/src/hooks/async.ts | 2 - .../src/hooks/use-anastasis-reducer.ts | 8 -- .../src/pages/home/AddingProviderScreen.tsx | 116 +++++++++++++++--- .../src/pages/home/SecretSelectionScreen.tsx | 70 +++++++++-- .../home/authMethod/AuthMethodTotpSolve.tsx | 1 - .../anastasis-webui/src/pages/home/index.tsx | 3 +- packages/anastasis-webui/src/stories.tsx | 3 + packages/anastasis-webui/watch/reply.sh | 3 +- packages/anastasis-webui/watch/send.sh | 12 ++ packages/anastasis-webui/watch/send2.sh | 14 +++ packages/anastasis-webui/watch/send_reload.sh | 7 -- packages/anastasis-webui/watch/serve.sh | 2 +- 16 files changed, 218 insertions(+), 59 deletions(-) create mode 100755 packages/anastasis-webui/watch/send.sh create mode 100755 packages/anastasis-webui/watch/send2.sh delete mode 100755 packages/anastasis-webui/watch/send_reload.sh diff --git a/packages/anastasis-webui/clean_and_build.sh b/packages/anastasis-webui/clean_and_build.sh index 2fa3ec777..21107a905 100755 --- a/packages/anastasis-webui/clean_and_build.sh +++ b/packages/anastasis-webui/clean_and_build.sh @@ -50,11 +50,14 @@ bundle ui-dev if [ "WATCH" == "$1" ]; then echo watch mode + echo Writting any file in the src directory will trigger a browser reload. + echo Be sure that the watcher server is running. inotifywait -e close_write -r src -q -m | while read line; do - DATE=$(date) - echo $DATE $line + echo $(date) $line build_js src/main.ts bundle ui-dev - ./watch/send_reload.sh + #CONTENT=$(echo 'alert("hola")' | base64) + ./watch/send.sh '{"type":"RELOAD"}' + #./watch/send.sh '{"type":"UPDATE","content":"'$CONTENT'"}' done; fi diff --git a/packages/anastasis-webui/html/ui-dev.html b/packages/anastasis-webui/html/ui-dev.html index 4cc36268e..5b1dd31cf 100644 --- a/packages/anastasis-webui/html/ui-dev.html +++ b/packages/anastasis-webui/html/ui-dev.html @@ -23,13 +23,13 @@
- diff --git a/packages/anastasis-webui/src/components/FlieButton.tsx b/packages/anastasis-webui/src/components/FlieButton.tsx index 4358d7d4d..1d19ae630 100644 --- a/packages/anastasis-webui/src/components/FlieButton.tsx +++ b/packages/anastasis-webui/src/components/FlieButton.tsx @@ -45,7 +45,6 @@ export function FileButton(props: Props): VNode { if (!f || f.length != 1) { return props.onChange(undefined); } - console.log(f); if (f[0].size > MAX_IMAGE_UPLOAD_SIZE) { setSizeError(true); return props.onChange(undefined); diff --git a/packages/anastasis-webui/src/components/fields/FileInput.tsx b/packages/anastasis-webui/src/components/fields/FileInput.tsx index b67ae870b..f20b07c7a 100644 --- a/packages/anastasis-webui/src/components/fields/FileInput.tsx +++ b/packages/anastasis-webui/src/components/fields/FileInput.tsx @@ -75,7 +75,6 @@ export function FileInput(props: FileInputProps): VNode { if (!f || f.length != 1) { return props.onChange(undefined); } - console.log(f); if (f[0].size > MAX_IMAGE_UPLOAD_SIZE) { setSizeError(true); return props.onChange(undefined); diff --git a/packages/anastasis-webui/src/hooks/async.ts b/packages/anastasis-webui/src/hooks/async.ts index cb1bb45f2..fc757ea81 100644 --- a/packages/anastasis-webui/src/hooks/async.ts +++ b/packages/anastasis-webui/src/hooks/async.ts @@ -66,9 +66,7 @@ export function useAsync( }, tooLong); try { - console.log("calling async", args); const result = await fn(...args); - console.log("async back", result); if (!isMounted()) { // Possibly calling fn(...) resulted in the component being unmounted. return; diff --git a/packages/anastasis-webui/src/hooks/use-anastasis-reducer.ts b/packages/anastasis-webui/src/hooks/use-anastasis-reducer.ts index cd00950e4..f78576118 100644 --- a/packages/anastasis-webui/src/hooks/use-anastasis-reducer.ts +++ b/packages/anastasis-webui/src/hooks/use-anastasis-reducer.ts @@ -177,7 +177,6 @@ function getStateFromStorage(): any { if (s === "undefined") { state = undefined; } else if (s) { - console.log("restoring state from", s); state = JSON.parse(s); } } catch (e) { @@ -225,7 +224,6 @@ export function useAnastasisReducer(): AnastasisReducerApi { if (Object.keys(updates).length === 0) { return; } - console.log("got provider updates", updates); const rs2 = reducerState; if (rs2.reducer_type !== "backup" && rs2.reducer_type !== "recovery") { return; @@ -248,19 +246,15 @@ export function useAnastasisReducer(): AnastasisReducerApi { }; async function doTransition(action: string, args: any): Promise { - console.log("reducing with", action, args); let s: ReducerState; if (remoteReducer) { s = await reduceStateRemote(anastasisState.reducerState, action, args); } else { s = await reduceAction(anastasisState.reducerState!, action, args); } - console.log("got response from reducer", s); if (s.reducer_type === "error") { - console.log("response is an error"); setAnastasisState({ ...anastasisState, currentError: s }); } else { - console.log("response is a new state"); setAnastasisState({ ...anastasisState, currentError: undefined, @@ -387,7 +381,6 @@ export function useAnastasisReducer(): AnastasisReducerApi { console.log("exception during reducer transaction", e); } const s = txHandle.transactionState; - console.log("transaction finished, new state", s); if (s.reducer_type === "error") { setAnastasisState({ ...anastasisState, @@ -413,7 +406,6 @@ class ReducerTxImpl implements ReducerTransactionHandle { } else { s = await reduceAction(this.transactionState, action, args); } - console.log("making transition in transaction", action); this.transactionState = s; // Abort transaction as soon as we transition into an error state. if (this.transactionState.reducer_type === "error") { 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 */ -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(); 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 && - p.methods.findIndex((m) => m.type === providerType) !== -1 - ); - } - }); + 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(undefined); useEffect(() => { @@ -211,6 +229,17 @@ export function AddingProviderScreen({ providerType, onCancel }: Props): VNode { ); })} + {authProvidersByStatus["error"]?.map((k) => { + const p = k as AuthenticationProviderStatusError; + return ( + + ); + })} ); @@ -277,3 +306,62 @@ function TableRow({ ); } + +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 ( +
+
+
{url}
+
+
+ Error +
+
{info.hint}
+
+ Code +
+
{info.code}
+
+ Status +
+
{status}
+
+
+
+ +
+
+ ); +} 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" > -

Found versions:

- {policies.map((version, i) => ( -
- {version.policy_hash} / {version.secret_name} - +
+
+

Found versions:

+ {policies.map((version, i) => ( +
+
+
+
+ Name: {version.secret_name} +
+
+ Id:  + + + + {version.policy_hash.substring(0, 22)}... +
+
+ +
+ + reducer.transition("select_version", version) + } + > + Recover + +
+
+
+ ))}
- ))} - +
+

+ Secret found, you can select another version or continue to the + challenges solving +

+

+ setManageProvider(true)}> + Manage recovery providers + +

+
+
); } 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 { - 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, ): 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 ; } - console.log("state", reducer.currentReducerState); if ( (state.reducer_type === "backup" && diff --git a/packages/anastasis-webui/src/stories.tsx b/packages/anastasis-webui/src/stories.tsx index 351d6f37b..6ee016089 100644 --- a/packages/anastasis-webui/src/stories.tsx +++ b/packages/anastasis-webui/src/stories.tsx @@ -381,4 +381,7 @@ function setupLiveReload(port: number, onReload: () => void): void { ws.onerror = (error) => { console.error(error); }; + ws.onclose = (e) => { + console.log("disconnected", e); + }; } diff --git a/packages/anastasis-webui/watch/reply.sh b/packages/anastasis-webui/watch/reply.sh index 1b42aa4e3..20cbff37e 100755 --- a/packages/anastasis-webui/watch/reply.sh +++ b/packages/anastasis-webui/watch/reply.sh @@ -14,4 +14,5 @@ done cat watch/web_socket_server.reply | sed 's/$'"/`echo \\\r`/" | envsubst '$WS_ACCEPT' -socat UNIX-RECV:./send_signal STDOUT +tail -n 0 -F /tmp/send_signal 2> /dev/null + diff --git a/packages/anastasis-webui/watch/send.sh b/packages/anastasis-webui/watch/send.sh new file mode 100755 index 000000000..184cd2491 --- /dev/null +++ b/packages/anastasis-webui/watch/send.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +#https://datatracker.ietf.org/doc/html/rfc6455#page-65 + +COMMAND=$1 +LEN=$(printf '%x\n' ${#COMMAND}) + +#text command +OPCODE=81 + +cat <(echo -n $OPCODE$LEN | xxd -r -p) <(echo -n $COMMAND) >> /tmp/send_signal + diff --git a/packages/anastasis-webui/watch/send2.sh b/packages/anastasis-webui/watch/send2.sh new file mode 100755 index 000000000..6a2881c19 --- /dev/null +++ b/packages/anastasis-webui/watch/send2.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +#https://datatracker.ietf.org/doc/html/rfc6455#page-65 + +CONTENT=$( cat $1 | base64 -w 0 ) +COMMAND='{"type":"UPDATE","'$CONTENT'"}' +LEN=$(printf '%0*x\n' 4 ${#COMMAND}) +echo $LEN +LEN=00000138 +#text command +OPCODE=81 + +cat <(echo -n $OPCODE$LEN | xxd -r -p) <(echo -n $COMMAND) >> /tmp/send_signal + diff --git a/packages/anastasis-webui/watch/send_reload.sh b/packages/anastasis-webui/watch/send_reload.sh deleted file mode 100755 index 87eef7d54..000000000 --- a/packages/anastasis-webui/watch/send_reload.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -COMMAND='{"type":"RELOAD"}' -LEN=$(printf '%x\n' ${#COMMAND}) -OPCODE=81 -cat <(echo -n $OPCODE$LEN | xxd -r -p) <(echo -n $COMMAND) | socat - UNIX-SEND:./send_signal - diff --git a/packages/anastasis-webui/watch/serve.sh b/packages/anastasis-webui/watch/serve.sh index cf2737416..c395c6a64 100755 --- a/packages/anastasis-webui/watch/serve.sh +++ b/packages/anastasis-webui/watch/serve.sh @@ -1,4 +1,4 @@ #!/bin/bash -socat TCP-LISTEN:8003,fork EXEC:"./watch/reply.sh" +socat TCP-LISTEN:8003,fork,reuseaddr,keepalive EXEC:"./watch/reply.sh"