fix #7065
This commit is contained in:
parent
eef2d47020
commit
cf894f1dd3
@ -40,17 +40,20 @@ set -e
|
||||
echo compile
|
||||
build_css &
|
||||
build_js src/main.ts &
|
||||
build_js src/stories.tsx &
|
||||
build_js src/main.test.ts &
|
||||
for file in $(find src/ -name test.ts); do build_js $file; done &
|
||||
wait -n
|
||||
wait -n
|
||||
wait -n
|
||||
wait -n
|
||||
wait -n
|
||||
pnpm run --silent test -- -R dot
|
||||
|
||||
echo html
|
||||
build_html ui
|
||||
build_html ui-dev
|
||||
build_html stories
|
||||
|
||||
if [ "WATCH" == "$1" ]; then
|
||||
|
||||
@ -62,6 +65,8 @@ if [ "WATCH" == "$1" ]; then
|
||||
echo $(date) $line
|
||||
build_js src/main.ts
|
||||
build_html ui-dev
|
||||
build_js src/stories.tsx
|
||||
build_html stories
|
||||
./watch/send.sh '{"type":"RELOAD"}'
|
||||
done;
|
||||
fi
|
||||
|
@ -28,11 +28,8 @@ interface Props {
|
||||
mobile?: boolean;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
const maybeEnv = process?.env || {};
|
||||
|
||||
const VERSION: string = maybeEnv.__VERSION__ || "dev";
|
||||
const GIT_HASH: string | undefined = maybeEnv.__GIT_HASH__;
|
||||
const VERSION = typeof __VERSION__ !== "undefined" ? __VERSION__ : "dev";
|
||||
const GIT_HASH = typeof __GIT_HASH__ !== "undefined" ? __GIT_HASH__ : undefined;
|
||||
const VERSION_WITH_HASH = GIT_HASH ? `${VERSION}-${GIT_HASH}` : VERSION;
|
||||
|
||||
export function Sidebar({ mobile }: Props): VNode {
|
||||
|
@ -180,7 +180,7 @@ function getStateFromStorage(): any {
|
||||
state = JSON.parse(s);
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
console.log("ERROR: getStateFromStorage ", e);
|
||||
}
|
||||
return state ?? undefined;
|
||||
}
|
||||
@ -203,7 +203,7 @@ export function useAnastasisReducer(): AnastasisReducerApi {
|
||||
JSON.stringify(newState.reducerState),
|
||||
);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
console.log("ERROR setAnastasisState", e);
|
||||
}
|
||||
setAnastasisStateInternal(newState);
|
||||
|
||||
@ -239,7 +239,7 @@ export function useAnastasisReducer(): AnastasisReducerApi {
|
||||
},
|
||||
});
|
||||
};
|
||||
doUpdate().catch((e) => console.log(e));
|
||||
doUpdate().catch((e) => console.log("ERROR doUpdate", e));
|
||||
};
|
||||
|
||||
tryUpdateProviders();
|
||||
|
@ -16,6 +16,7 @@
|
||||
import { AuthenticationProviderStatus } from "@gnu-taler/anastasis-core";
|
||||
import InvalidState from "../../../components/InvalidState.js";
|
||||
import NoReducer from "../../../components/NoReducer.js";
|
||||
import { Notification } from "../../../components/Notifications.js";
|
||||
import { compose, StateViewMap } from "../../../utils/index.js";
|
||||
import useComponentState from "./state.js";
|
||||
import { WithoutProviderType, WithProviderType } from "./views.js";
|
||||
@ -44,6 +45,7 @@ interface CommonProps {
|
||||
setProviderURL: (url: string) => Promise<void>;
|
||||
providerURL: string;
|
||||
errors: string | undefined;
|
||||
notifications: Notification[];
|
||||
}
|
||||
|
||||
export interface WithType extends CommonProps {
|
||||
@ -90,7 +92,7 @@ export async function testProvider(
|
||||
}
|
||||
return;
|
||||
} catch (e) {
|
||||
console.log("error", e);
|
||||
console.log("ERROR testProvider", e);
|
||||
const error =
|
||||
e instanceof Error
|
||||
? Error(
|
||||
|
@ -14,6 +14,7 @@
|
||||
GNU Anastasis; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
import { useEffect, useRef, useState } from "preact/hooks";
|
||||
import { Notification } from "../../../components/Notifications.js";
|
||||
import { useAnastasisContext } from "../../../context/anastasis.js";
|
||||
import { authMethods, KnownAuthMethods } from "../authMethod/index.jsx";
|
||||
import { AuthProvByStatusMap, State, testProvider } from "./index.js";
|
||||
@ -21,9 +22,10 @@ import { AuthProvByStatusMap, State, testProvider } from "./index.js";
|
||||
interface Props {
|
||||
providerType?: KnownAuthMethods;
|
||||
onCancel: () => Promise<void>;
|
||||
notifications?: Notification[];
|
||||
}
|
||||
|
||||
export default function useComponentState({ providerType, onCancel }: Props): State {
|
||||
export default function useComponentState({ providerType, onCancel, notifications = [] }: Props): State {
|
||||
const reducer = useAnastasisContext();
|
||||
|
||||
const [providerURL, setProviderURL] = useState("");
|
||||
@ -128,6 +130,7 @@ export default function useComponentState({ providerType, onCancel }: Props): St
|
||||
setProviderURL: async (s: string) => setProviderURL(s),
|
||||
errors,
|
||||
error,
|
||||
notifications
|
||||
}
|
||||
|
||||
if (!providerLabel) {
|
||||
|
@ -53,6 +53,7 @@ export const NewProvider = createExampleWithoutAnastasis(WithoutProviderType, {
|
||||
disabled: [],
|
||||
error: [],
|
||||
},
|
||||
notifications: [],
|
||||
});
|
||||
|
||||
export const NewProviderWithoutProviderList = createExampleWithoutAnastasis(
|
||||
@ -64,6 +65,7 @@ export const NewProviderWithoutProviderList = createExampleWithoutAnastasis(
|
||||
disabled: [],
|
||||
error: [],
|
||||
},
|
||||
notifications: [],
|
||||
},
|
||||
);
|
||||
|
||||
@ -75,6 +77,7 @@ export const NewSmsProvider = createExampleWithoutAnastasis(WithProviderType, {
|
||||
error: [],
|
||||
},
|
||||
providerLabel: "sms",
|
||||
notifications: [],
|
||||
});
|
||||
|
||||
export const NewIBANProvider = createExampleWithoutAnastasis(WithProviderType, {
|
||||
@ -85,4 +88,5 @@ export const NewIBANProvider = createExampleWithoutAnastasis(WithProviderType, {
|
||||
error: [],
|
||||
},
|
||||
providerLabel: "IBAN",
|
||||
notifications: [],
|
||||
});
|
||||
|
@ -20,6 +20,7 @@ import {
|
||||
import { h, VNode } from "preact";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
import { TextInput } from "../../../components/fields/TextInput.js";
|
||||
import { Notifications } from "../../../components/Notifications.js";
|
||||
import { AnastasisClientFrame } from "../index.js";
|
||||
import { testProvider, WithoutType, WithType } from "./index.js";
|
||||
|
||||
@ -31,6 +32,7 @@ export function WithProviderType(props: WithType): VNode {
|
||||
hideNext={props.errors}
|
||||
>
|
||||
<div>
|
||||
<Notifications notifications={props.notifications} />
|
||||
<p>Add a provider url for a {props.providerLabel} service</p>
|
||||
<div class="container">
|
||||
<TextInput
|
||||
@ -108,10 +110,11 @@ export function WithoutProviderType(props: WithoutType): VNode {
|
||||
return (
|
||||
<AnastasisClientFrame
|
||||
hideNav
|
||||
title="Backup: Manage providers2"
|
||||
title="Backup: Manage providers"
|
||||
hideNext={props.errors}
|
||||
>
|
||||
<div>
|
||||
<Notifications notifications={props.notifications} />
|
||||
<p>Add a provider url</p>
|
||||
<div class="container">
|
||||
<TextInput
|
||||
|
@ -174,85 +174,88 @@ export const OnePolicyWithAllTheChallengesInDifferentState = createExample(
|
||||
{ uuid: "uuid-7" },
|
||||
{ uuid: "uuid-8" },
|
||||
{ uuid: "uuid-9" },
|
||||
{ uuid: "uuid-10" },
|
||||
],
|
||||
],
|
||||
challenges: [
|
||||
{
|
||||
instructions: 'in state "solved"',
|
||||
instructions: 'this challenge is in state "solved"',
|
||||
type: "question",
|
||||
uuid: "uuid-1",
|
||||
},
|
||||
{
|
||||
instructions: 'in state "message"',
|
||||
instructions: 'this challenge is in state "code-in-file"',
|
||||
type: "question",
|
||||
uuid: "uuid-2",
|
||||
},
|
||||
{
|
||||
instructions: 'in state "auth iban"',
|
||||
instructions: 'this challenge is in state "code-sent"',
|
||||
type: "question",
|
||||
uuid: "uuid-3",
|
||||
},
|
||||
{
|
||||
instructions: 'in state "payment "',
|
||||
instructions: 'this challenge is in state "server-failure "',
|
||||
type: "question",
|
||||
uuid: "uuid-4",
|
||||
},
|
||||
{
|
||||
instructions: 'in state "rate limit"',
|
||||
instructions: 'this challenge is in state "truth-unknown"',
|
||||
type: "question",
|
||||
uuid: "uuid-5",
|
||||
},
|
||||
{
|
||||
instructions: 'in state "redirect"',
|
||||
instructions: 'this challenge is in state "taler-payment"',
|
||||
type: "question",
|
||||
uuid: "uuid-6",
|
||||
},
|
||||
{
|
||||
instructions: 'in state "server failure"',
|
||||
instructions: 'this challenge is in state "unsupported"',
|
||||
type: "question",
|
||||
uuid: "uuid-7",
|
||||
},
|
||||
{
|
||||
instructions: 'in state "truth unknown"',
|
||||
instructions: 'this challenge is in state "rate-limit-exceeded"',
|
||||
type: "question",
|
||||
uuid: "uuid-8",
|
||||
},
|
||||
{
|
||||
instructions: 'in state "unsupported"',
|
||||
instructions: 'this challenge is in state "iban-instructions"',
|
||||
type: "question",
|
||||
uuid: "uuid-9",
|
||||
},
|
||||
{
|
||||
instructions: 'this challenge is in state "incorrect-answer"',
|
||||
type: "question",
|
||||
uuid: "uuid-10",
|
||||
},
|
||||
],
|
||||
},
|
||||
challenge_feedback: {
|
||||
"uuid-1": { state: ChallengeFeedbackStatus.Solved.toString() },
|
||||
"uuid-3": {
|
||||
"uuid-2": { state: ChallengeFeedbackStatus.CodeInFile.toString() },
|
||||
"uuid-3": { state: ChallengeFeedbackStatus.CodeSent.toString() },
|
||||
"uuid-4": {
|
||||
state: ChallengeFeedbackStatus.ServerFailure.toString(),
|
||||
http_status: 500,
|
||||
error_response: "some error message or error object",
|
||||
},
|
||||
"uuid-5": { state: ChallengeFeedbackStatus.TruthUnknown.toString() },
|
||||
"uuid-6": {
|
||||
state: ChallengeFeedbackStatus.TalerPayment.toString(),
|
||||
taler_pay_uri: "taler://pay/...",
|
||||
provider: "https://localhost:8080/",
|
||||
payment_secret: "3P4561HAMHRRYEYD6CM6J7TS5VTD5SR2K2EXJDZEFSX92XKHR4KG",
|
||||
},
|
||||
"uuid-7": { state: ChallengeFeedbackStatus.Unsupported.toString() },
|
||||
"uuid-8": { state: ChallengeFeedbackStatus.RateLimitExceeded.toString() },
|
||||
"uuid-9": {
|
||||
state: ChallengeFeedbackStatus.IbanInstructions.toString(),
|
||||
challenge_amount: "EUR:1",
|
||||
target_iban: "DE12345789000",
|
||||
target_business_name: "Data Loss Incorporated",
|
||||
wire_transfer_subject: "Anastasis 987654321",
|
||||
},
|
||||
"uuid-4": {
|
||||
state: ChallengeFeedbackStatus.TalerPayment.toString(),
|
||||
taler_pay_uri: "taler://pay/...",
|
||||
provider: "https://localhost:8080/",
|
||||
payment_secret: "3P4561HAMHRRYEYD6CM6J7TS5VTD5SR2K2EXJDZEFSX92XKHR4KG",
|
||||
},
|
||||
"uuid-5": {
|
||||
state: ChallengeFeedbackStatus.RateLimitExceeded.toString(),
|
||||
// "error_code": 8121
|
||||
},
|
||||
"uuid-7": {
|
||||
state: ChallengeFeedbackStatus.ServerFailure.toString(),
|
||||
http_status: 500,
|
||||
error_response: "some error message or error object",
|
||||
},
|
||||
"uuid-8": {
|
||||
state: ChallengeFeedbackStatus.TruthUnknown.toString(),
|
||||
// "error_code": 8108
|
||||
},
|
||||
"uuid-9": { state: ChallengeFeedbackStatus.Unsupported.toString() },
|
||||
"uuid-10": { state: ChallengeFeedbackStatus.IncorrectAnswer.toString() },
|
||||
},
|
||||
} as ReducerState,
|
||||
);
|
||||
|
@ -17,22 +17,25 @@ import {
|
||||
ChallengeFeedback,
|
||||
ChallengeFeedbackStatus,
|
||||
} from "@gnu-taler/anastasis-core";
|
||||
import { h, VNode } from "preact";
|
||||
import { Fragment, h, VNode } from "preact";
|
||||
import { AsyncButton } from "../../components/AsyncButton.js";
|
||||
import { useAnastasisContext } from "../../context/anastasis.js";
|
||||
import { authMethods, KnownAuthMethods } from "./authMethod/index.js";
|
||||
import { AnastasisClientFrame } from "./index.js";
|
||||
|
||||
function OverviewFeedbackDisplay(props: { feedback?: ChallengeFeedback }) {
|
||||
function OverviewFeedbackDisplay(props: {
|
||||
feedback?: ChallengeFeedback;
|
||||
}): VNode {
|
||||
const { feedback } = props;
|
||||
if (!feedback) {
|
||||
return null;
|
||||
return <Fragment />;
|
||||
}
|
||||
|
||||
switch (feedback.state) {
|
||||
case ChallengeFeedbackStatus.Solved:
|
||||
return <div />;
|
||||
case ChallengeFeedbackStatus.IbanInstructions:
|
||||
return null;
|
||||
return <div class="block has-text-info">Payment required.</div>;
|
||||
case ChallengeFeedbackStatus.ServerFailure:
|
||||
return <div class="block has-text-danger">Server error.</div>;
|
||||
case ChallengeFeedbackStatus.RateLimitExceeded:
|
||||
@ -51,12 +54,20 @@ function OverviewFeedbackDisplay(props: { feedback?: ChallengeFeedback }) {
|
||||
case ChallengeFeedbackStatus.TruthUnknown:
|
||||
return (
|
||||
<div class="block has-text-danger">
|
||||
Provider doesn't recognize the challenge of the policy. Contact
|
||||
the provider for further information.
|
||||
Provider doesn't recognize the type of challenge. Use another
|
||||
version or contact the provider.
|
||||
</div>
|
||||
);
|
||||
default:
|
||||
return <div />;
|
||||
case ChallengeFeedbackStatus.IncorrectAnswer:
|
||||
return (
|
||||
<div class="block has-text-danger">The answer was not correct.</div>
|
||||
);
|
||||
case ChallengeFeedbackStatus.CodeInFile:
|
||||
return <div class="block has-text-info">code in file</div>;
|
||||
case ChallengeFeedbackStatus.CodeSent:
|
||||
return <div class="block has-text-info">Code sent</div>;
|
||||
case ChallengeFeedbackStatus.TalerPayment:
|
||||
return <div class="block has-text-info">Payment required</div>;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,29 +21,57 @@
|
||||
|
||||
import { ReducerState } from "@gnu-taler/anastasis-core";
|
||||
import { createExample, reducerStatesExample } from "../../utils/index.js";
|
||||
import { SecretSelectionScreen as TestedComponent } from "./SecretSelectionScreen.js";
|
||||
import {
|
||||
SecretSelectionScreen,
|
||||
SecretSelectionScreenFound,
|
||||
} from "./SecretSelectionScreen.js";
|
||||
|
||||
export default {
|
||||
component: TestedComponent,
|
||||
component: SecretSelectionScreen,
|
||||
args: {
|
||||
order: 4,
|
||||
},
|
||||
argTypes: {
|
||||
onUpdate: { action: "onUpdate" },
|
||||
onBack: { action: "onBack" },
|
||||
},
|
||||
};
|
||||
|
||||
export const Example = createExample(TestedComponent, {
|
||||
...reducerStatesExample.secretSelection,
|
||||
recovery_document: {
|
||||
provider_url: "https://kudos.demo.anastasis.lu/",
|
||||
secret_name: "secretName",
|
||||
version: 1,
|
||||
export const Example = createExample(
|
||||
SecretSelectionScreenFound,
|
||||
{
|
||||
...reducerStatesExample.secretSelection,
|
||||
recovery_document: {
|
||||
provider_url: "https://kudos.demo.anastasis.lu/",
|
||||
secret_name: "secretName",
|
||||
version: 1,
|
||||
},
|
||||
} as ReducerState,
|
||||
{
|
||||
policies: [
|
||||
{
|
||||
secret_name: "The secret name 1",
|
||||
attribute_mask: 1,
|
||||
policy_hash: "abcdefghijklmnopqrstuvwxyz",
|
||||
providers: [
|
||||
{
|
||||
url: "http://someurl",
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
secret_name: "The secret name 2",
|
||||
attribute_mask: 1,
|
||||
policy_hash: "abcdefghijklmnopqrstuvwxyz",
|
||||
providers: [
|
||||
{
|
||||
url: "http://someurl",
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
} as ReducerState);
|
||||
);
|
||||
|
||||
export const NoRecoveryDocumentFound = createExample(TestedComponent, {
|
||||
export const NoRecoveryDocumentFound = createExample(SecretSelectionScreen, {
|
||||
...reducerStatesExample.secretSelection,
|
||||
recovery_document: undefined,
|
||||
} as ReducerState);
|
||||
|
@ -14,6 +14,7 @@
|
||||
GNU Anastasis; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
import {
|
||||
AggregatedPolicyMetaInfo,
|
||||
AuthenticationProviderStatus,
|
||||
AuthenticationProviderStatusOk,
|
||||
} from "@gnu-taler/anastasis-core";
|
||||
@ -25,20 +26,16 @@ import { useAnastasisContext } from "../../context/anastasis.js";
|
||||
import AddingProviderScreen from "./AddingProviderScreen/index.js";
|
||||
import { AnastasisClientFrame } from "./index.js";
|
||||
|
||||
export function SecretSelectionScreen(): VNode {
|
||||
const [selectingVersion, setSelectingVersion] = useState<boolean>(false);
|
||||
export function SecretSelectionScreenFound({
|
||||
policies,
|
||||
onManageProvider,
|
||||
onNext,
|
||||
}: {
|
||||
policies: AggregatedPolicyMetaInfo[];
|
||||
onManageProvider: () => void;
|
||||
onNext: (version: AggregatedPolicyMetaInfo) => void;
|
||||
}): VNode {
|
||||
const reducer = useAnastasisContext();
|
||||
const [manageProvider, setManageProvider] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
async function f() {
|
||||
if (reducer) {
|
||||
await reducer.discoverStart();
|
||||
}
|
||||
}
|
||||
f().catch((e) => console.log(e));
|
||||
}, []);
|
||||
|
||||
if (!reducer) {
|
||||
return <div>no reducer in context</div>;
|
||||
}
|
||||
@ -49,45 +46,6 @@ export function SecretSelectionScreen(): VNode {
|
||||
) {
|
||||
return <div>invalid state</div>;
|
||||
}
|
||||
|
||||
const provs = reducer.currentReducerState.authentication_providers ?? {};
|
||||
const recoveryDocument = reducer.currentReducerState.recovery_document;
|
||||
|
||||
if (manageProvider) {
|
||||
return (
|
||||
<AddingProviderScreen onCancel={async () => setManageProvider(false)} />
|
||||
);
|
||||
}
|
||||
|
||||
if (reducer.discoveryState.state === "none") {
|
||||
// Can this even happen?
|
||||
return (
|
||||
<AnastasisClientFrame title="Recovery: Select secret">
|
||||
<div>waiting to start discovery</div>
|
||||
</AnastasisClientFrame>
|
||||
);
|
||||
}
|
||||
|
||||
if (reducer.discoveryState.state === "active") {
|
||||
return (
|
||||
<AnastasisClientFrame title="Recovery: Select secret">
|
||||
<div>loading secret versions</div>
|
||||
</AnastasisClientFrame>
|
||||
);
|
||||
}
|
||||
|
||||
const policies = reducer.discoveryState.aggregatedPolicies ?? [];
|
||||
|
||||
if (policies.length === 0) {
|
||||
return (
|
||||
<ChooseAnotherProviderScreen
|
||||
providers={provs}
|
||||
selected=""
|
||||
onChange={() => null}
|
||||
></ChooseAnotherProviderScreen>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<AnastasisClientFrame
|
||||
title="Recovery: Select secret"
|
||||
@ -115,9 +73,7 @@ export function SecretSelectionScreen(): VNode {
|
||||
<b>Id:</b>
|
||||
<span
|
||||
class="icon has-tooltip-top"
|
||||
data-tooltip={version.policy_hash
|
||||
.match(/(.{22})/g)
|
||||
?.join("\n")}
|
||||
data-tooltip={version.policy_hash}
|
||||
>
|
||||
<i class="mdi mdi-information" />
|
||||
</span>
|
||||
@ -128,9 +84,7 @@ export function SecretSelectionScreen(): VNode {
|
||||
<div>
|
||||
<AsyncButton
|
||||
class="button"
|
||||
onClick={() =>
|
||||
reducer.transition("select_version", version)
|
||||
}
|
||||
onClick={async () => onNext(version)}
|
||||
>
|
||||
Recover
|
||||
</AsyncButton>
|
||||
@ -145,9 +99,7 @@ export function SecretSelectionScreen(): VNode {
|
||||
challenges solving
|
||||
</p>
|
||||
<p class="block">
|
||||
<a onClick={() => setManageProvider(true)}>
|
||||
Manage recovery providers
|
||||
</a>
|
||||
<a onClick={onManageProvider}>Manage recovery providers</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -155,8 +107,7 @@ export function SecretSelectionScreen(): VNode {
|
||||
);
|
||||
}
|
||||
|
||||
export function OldSecretSelectionScreen(): VNode {
|
||||
const [selectingVersion, setSelectingVersion] = useState<boolean>(false);
|
||||
export function SecretSelectionScreen(): VNode {
|
||||
const reducer = useAnastasisContext();
|
||||
const [manageProvider, setManageProvider] = useState(false);
|
||||
|
||||
@ -169,15 +120,10 @@ export function OldSecretSelectionScreen(): VNode {
|
||||
f().catch((e) => console.log(e));
|
||||
}, []);
|
||||
|
||||
const currentVersion =
|
||||
(reducer?.currentReducerState &&
|
||||
"recovery_document" in reducer.currentReducerState &&
|
||||
reducer.currentReducerState.recovery_document?.version) ||
|
||||
0;
|
||||
|
||||
if (!reducer) {
|
||||
return <div>no reducer in context</div>;
|
||||
}
|
||||
|
||||
if (
|
||||
!reducer.currentReducerState ||
|
||||
reducer.currentReducerState.reducer_type !== "recovery"
|
||||
@ -185,97 +131,178 @@ export function OldSecretSelectionScreen(): VNode {
|
||||
return <div>invalid state</div>;
|
||||
}
|
||||
|
||||
async function doSelectVersion(p: string, n: number): Promise<void> {
|
||||
if (!reducer) return Promise.resolve();
|
||||
return reducer.runTransaction(async (tx) => {
|
||||
await tx.transition("select_version", {
|
||||
version: n,
|
||||
provider_url: p,
|
||||
});
|
||||
setSelectingVersion(false);
|
||||
});
|
||||
}
|
||||
|
||||
const provs = reducer.currentReducerState.authentication_providers ?? {};
|
||||
const recoveryDocument = reducer.currentReducerState.recovery_document;
|
||||
|
||||
if (!recoveryDocument) {
|
||||
return (
|
||||
<ChooseAnotherProviderScreen
|
||||
providers={provs}
|
||||
selected=""
|
||||
onChange={(newProv) => doSelectVersion(newProv, 0)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (selectingVersion) {
|
||||
return (
|
||||
<SelectOtherVersionProviderScreen
|
||||
providers={provs}
|
||||
provider={recoveryDocument.provider_url}
|
||||
version={recoveryDocument.version}
|
||||
onCancel={() => setSelectingVersion(false)}
|
||||
onConfirm={doSelectVersion}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (manageProvider) {
|
||||
return (
|
||||
<AddingProviderScreen onCancel={async () => setManageProvider(false)} />
|
||||
);
|
||||
}
|
||||
|
||||
const providerInfo = provs[
|
||||
recoveryDocument.provider_url
|
||||
] as AuthenticationProviderStatusOk;
|
||||
if (
|
||||
reducer.discoveryState.state === "none" ||
|
||||
reducer.discoveryState.state === "active"
|
||||
) {
|
||||
// Can this even happen?
|
||||
return <SecretSelectionScreenWaiting />;
|
||||
}
|
||||
|
||||
const policies = reducer.discoveryState.aggregatedPolicies ?? [];
|
||||
|
||||
if (policies.length === 0) {
|
||||
return (
|
||||
<AddingProviderScreen
|
||||
onCancel={async () => setManageProvider(false)}
|
||||
notifications={[
|
||||
{
|
||||
message: "Secret not found",
|
||||
type: "ERROR",
|
||||
description:
|
||||
"With the information you provided we could not found secret in any of the providers. You can try adding more providers if you think the data is correct.",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<AnastasisClientFrame title="Recovery: Select secret">
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
<div class="box" style={{ border: "2px solid green" }}>
|
||||
<h1 class="subtitle">{providerInfo.business_name}</h1>
|
||||
<div class="block">
|
||||
{currentVersion === 0 ? (
|
||||
<p>Set to recover the latest version</p>
|
||||
) : (
|
||||
<p>Set to recover the version number {currentVersion}</p>
|
||||
)}
|
||||
</div>
|
||||
<div class="buttons is-right">
|
||||
<button class="button" onClick={(e) => setSelectingVersion(true)}>
|
||||
Change secret's version
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<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>
|
||||
<SecretSelectionScreenFound
|
||||
policies={policies}
|
||||
onNext={(version) => reducer.transition("select_version", version)}
|
||||
onManageProvider={async () => setManageProvider(false)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// export function OldSecretSelectionScreen(): VNode {
|
||||
// const [selectingVersion, setSelectingVersion] = useState<boolean>(false);
|
||||
// const reducer = useAnastasisContext();
|
||||
// const [manageProvider, setManageProvider] = useState(false);
|
||||
|
||||
// useEffect(() => {
|
||||
// async function f() {
|
||||
// if (reducer) {
|
||||
// await reducer.discoverStart();
|
||||
// }
|
||||
// }
|
||||
// f().catch((e) => console.log(e));
|
||||
// }, []);
|
||||
|
||||
// const currentVersion =
|
||||
// (reducer?.currentReducerState &&
|
||||
// "recovery_document" in reducer.currentReducerState &&
|
||||
// reducer.currentReducerState.recovery_document?.version) ||
|
||||
// 0;
|
||||
|
||||
// if (!reducer) {
|
||||
// return <div>no reducer in context</div>;
|
||||
// }
|
||||
// if (
|
||||
// !reducer.currentReducerState ||
|
||||
// reducer.currentReducerState.reducer_type !== "recovery"
|
||||
// ) {
|
||||
// return <div>invalid state</div>;
|
||||
// }
|
||||
|
||||
// async function doSelectVersion(p: string, n: number): Promise<void> {
|
||||
// if (!reducer) return Promise.resolve();
|
||||
// return reducer.runTransaction(async (tx) => {
|
||||
// await tx.transition("select_version", {
|
||||
// version: n,
|
||||
// provider_url: p,
|
||||
// });
|
||||
// setSelectingVersion(false);
|
||||
// });
|
||||
// }
|
||||
|
||||
// const provs = reducer.currentReducerState.authentication_providers ?? {};
|
||||
// const recoveryDocument = reducer.currentReducerState.recovery_document;
|
||||
|
||||
// if (!recoveryDocument) {
|
||||
// return (
|
||||
// <ChooseAnotherProviderScreen
|
||||
// providers={provs}
|
||||
// selected=""
|
||||
// onChange={(newProv) => doSelectVersion(newProv, 0)}
|
||||
// />
|
||||
// );
|
||||
// }
|
||||
|
||||
// if (selectingVersion) {
|
||||
// return (
|
||||
// <SelectOtherVersionProviderScreen
|
||||
// providers={provs}
|
||||
// provider={recoveryDocument.provider_url}
|
||||
// version={recoveryDocument.version}
|
||||
// onCancel={() => setSelectingVersion(false)}
|
||||
// onConfirm={doSelectVersion}
|
||||
// />
|
||||
// );
|
||||
// }
|
||||
|
||||
// if (manageProvider) {
|
||||
// return (
|
||||
// <AddingProviderScreen onCancel={async () => setManageProvider(false)} />
|
||||
// );
|
||||
// }
|
||||
|
||||
// const providerInfo = provs[
|
||||
// recoveryDocument.provider_url
|
||||
// ] as AuthenticationProviderStatusOk;
|
||||
|
||||
// return (
|
||||
// <AnastasisClientFrame title="Recovery: Select secret">
|
||||
// <div class="columns">
|
||||
// <div class="column">
|
||||
// <div class="box" style={{ border: "2px solid green" }}>
|
||||
// <h1 class="subtitle">{providerInfo.business_name}</h1>
|
||||
// <div class="block">
|
||||
// {currentVersion === 0 ? (
|
||||
// <p>Set to recover the latest version</p>
|
||||
// ) : (
|
||||
// <p>Set to recover the version number {currentVersion}</p>
|
||||
// )}
|
||||
// </div>
|
||||
// <div class="buttons is-right">
|
||||
// <button class="button" onClick={(e) => setSelectingVersion(true)}>
|
||||
// Change secret's version
|
||||
// </button>
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>
|
||||
// <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>
|
||||
// );
|
||||
// }
|
||||
|
||||
function ChooseAnotherProviderScreen({
|
||||
providers,
|
||||
selected,
|
||||
onChange,
|
||||
}: {
|
||||
selected: string;
|
||||
providers: { [url: string]: AuthenticationProviderStatus };
|
||||
onChange: (prov: string) => void;
|
||||
}): VNode {
|
||||
const reducer = useAnastasisContext();
|
||||
|
||||
if (!reducer) {
|
||||
return <div>no reducer in context</div>;
|
||||
}
|
||||
|
||||
if (
|
||||
!reducer.currentReducerState ||
|
||||
reducer.currentReducerState.reducer_type !== "recovery"
|
||||
) {
|
||||
return <div>invalid state</div>;
|
||||
}
|
||||
const providers = reducer.currentReducerState.authentication_providers ?? {};
|
||||
|
||||
return (
|
||||
<AnastasisClientFrame
|
||||
hideNext="Recovery document not found"
|
||||
@ -286,13 +313,9 @@ function ChooseAnotherProviderScreen({
|
||||
<label class="label">Provider</label>
|
||||
<div class="control is-expanded has-icons-left">
|
||||
<div class="select is-fullwidth">
|
||||
<select
|
||||
onChange={(e) => onChange(e.currentTarget.value)}
|
||||
value={selected}
|
||||
>
|
||||
<select onChange={(e) => onChange(e.currentTarget.value)} value="">
|
||||
<option key="none" disabled selected value="">
|
||||
{" "}
|
||||
Choose a provider{" "}
|
||||
Choose a provider
|
||||
</option>
|
||||
{Object.keys(providers).map((url) => {
|
||||
const p = providers[url];
|
||||
@ -419,3 +442,11 @@ function SelectOtherVersionProviderScreen({
|
||||
</AnastasisClientFrame>
|
||||
);
|
||||
}
|
||||
|
||||
function SecretSelectionScreenWaiting(): VNode {
|
||||
return (
|
||||
<AnastasisClientFrame title="Recovery: Select secret">
|
||||
<div>loading secret versions</div>
|
||||
</AnastasisClientFrame>
|
||||
);
|
||||
}
|
||||
|
@ -40,7 +40,14 @@ export function SolveOverviewFeedbackDisplay(props: {
|
||||
message: `Message from provider`,
|
||||
description: (
|
||||
<span>
|
||||
To pay you can <a href={feedback.taler_pay_uri}>click here</a>
|
||||
To pay you can{" "}
|
||||
<a
|
||||
href={feedback.taler_pay_uri}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
click here
|
||||
</a>
|
||||
</span>
|
||||
),
|
||||
},
|
||||
@ -65,8 +72,12 @@ export function SolveOverviewFeedbackDisplay(props: {
|
||||
notifications={[
|
||||
{
|
||||
type: "ERROR",
|
||||
message: `Server error: Code ${feedback.http_status}`,
|
||||
description: feedback.error_response,
|
||||
message: `Server error: response code ${feedback.http_status}`,
|
||||
description: !feedback.error_response
|
||||
? undefined
|
||||
: `More information: ${JSON.stringify(
|
||||
feedback.error_response,
|
||||
)}`,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
@ -77,8 +88,7 @@ export function SolveOverviewFeedbackDisplay(props: {
|
||||
notifications={[
|
||||
{
|
||||
type: "ERROR",
|
||||
message: `Message from provider`,
|
||||
description: "There were to many failed attempts.",
|
||||
message: "There were to many failed attempts.",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
@ -107,11 +117,56 @@ export function SolveOverviewFeedbackDisplay(props: {
|
||||
]}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
console.warn(
|
||||
`unknown challenge feedback status ${JSON.stringify(feedback)}`,
|
||||
case ChallengeFeedbackStatus.CodeInFile:
|
||||
return (
|
||||
<Notifications
|
||||
notifications={[
|
||||
{
|
||||
type: "INFO",
|
||||
message: `Required TAN can be found in file "${feedback.filename}"`,
|
||||
description: feedback.display_hint
|
||||
? `HINT: ${feedback.display_hint}`
|
||||
: undefined,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
case ChallengeFeedbackStatus.CodeSent:
|
||||
return (
|
||||
<Notifications
|
||||
notifications={[
|
||||
{
|
||||
type: "INFO",
|
||||
message: `Code sent to address "${feedback.address_hint}"`,
|
||||
description: feedback.display_hint
|
||||
? `HINT: ${feedback.display_hint}`
|
||||
: undefined,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
case ChallengeFeedbackStatus.IncorrectAnswer:
|
||||
return (
|
||||
<Notifications
|
||||
notifications={[
|
||||
{
|
||||
type: "ERROR",
|
||||
message: `The answer is wrong.`,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
case ChallengeFeedbackStatus.Solved:
|
||||
return (
|
||||
<Notifications
|
||||
notifications={[
|
||||
{
|
||||
type: "SUCCESS",
|
||||
message: `This challenge is solved`,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
return <div />;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
ChallengeFeedbackBankTransferRequired,
|
||||
ChallengeFeedbackStatus,
|
||||
ReducerState,
|
||||
} from "@gnu-taler/anastasis-core";
|
||||
@ -61,45 +60,111 @@ export const WithoutFeedback = createExample(
|
||||
},
|
||||
);
|
||||
|
||||
const recovery_information = {
|
||||
challenges: [
|
||||
{
|
||||
instructions: "does P equal NP?",
|
||||
type: "question",
|
||||
uuid: "ASDASDSAD!1",
|
||||
},
|
||||
],
|
||||
policies: [],
|
||||
};
|
||||
|
||||
export const CodeInFileFeedback = createExample(TestedComponent[type].solve, {
|
||||
...reducerStatesExample.challengeSolving,
|
||||
recovery_information,
|
||||
selected_challenge_uuid: "ASDASDSAD!1",
|
||||
challenge_feedback: {
|
||||
"ASDASDSAD!1": {
|
||||
state: ChallengeFeedbackStatus.CodeInFile,
|
||||
filename: "asd",
|
||||
display_hint: "hint",
|
||||
},
|
||||
},
|
||||
} as ReducerState);
|
||||
|
||||
export const CodeSentFeedback = createExample(TestedComponent[type].solve, {
|
||||
...reducerStatesExample.challengeSolving,
|
||||
recovery_information,
|
||||
selected_challenge_uuid: "ASDASDSAD!1",
|
||||
challenge_feedback: {
|
||||
"ASDASDSAD!1": {
|
||||
state: ChallengeFeedbackStatus.CodeSent,
|
||||
address_hint: "asdasd",
|
||||
display_hint: "qweqweqw",
|
||||
},
|
||||
},
|
||||
} as ReducerState);
|
||||
|
||||
export const SolvedFeedback = createExample(TestedComponent[type].solve, {
|
||||
...reducerStatesExample.challengeSolving,
|
||||
recovery_information,
|
||||
selected_challenge_uuid: "ASDASDSAD!1",
|
||||
challenge_feedback: {
|
||||
"ASDASDSAD!1": {
|
||||
state: ChallengeFeedbackStatus.Solved,
|
||||
},
|
||||
},
|
||||
} as ReducerState);
|
||||
|
||||
export const ServerFailureFeedback = createExample(
|
||||
TestedComponent[type].solve,
|
||||
{
|
||||
...reducerStatesExample.challengeSolving,
|
||||
recovery_information: {
|
||||
challenges: [
|
||||
{
|
||||
instructions: "does P equal NP?",
|
||||
type: "question",
|
||||
uuid: "ASDASDSAD!1",
|
||||
},
|
||||
],
|
||||
policies: [],
|
||||
},
|
||||
recovery_information,
|
||||
selected_challenge_uuid: "ASDASDSAD!1",
|
||||
challenge_feedback: {
|
||||
"ASDASDSAD!1": {
|
||||
state: ChallengeFeedbackStatus.ServerFailure,
|
||||
http_status: 500,
|
||||
error_response: "Couldn't connect to mysql",
|
||||
},
|
||||
},
|
||||
} as ReducerState,
|
||||
);
|
||||
|
||||
export const MessageRateLimitExceededFeedback = createExample(
|
||||
export const TruthUnknownFeedback = createExample(TestedComponent[type].solve, {
|
||||
...reducerStatesExample.challengeSolving,
|
||||
recovery_information,
|
||||
selected_challenge_uuid: "ASDASDSAD!1",
|
||||
challenge_feedback: {
|
||||
"ASDASDSAD!1": {
|
||||
state: ChallengeFeedbackStatus.TruthUnknown,
|
||||
},
|
||||
},
|
||||
} as ReducerState);
|
||||
|
||||
export const TalerPaymentFeedback = createExample(TestedComponent[type].solve, {
|
||||
...reducerStatesExample.challengeSolving,
|
||||
recovery_information,
|
||||
selected_challenge_uuid: "ASDASDSAD!1",
|
||||
challenge_feedback: {
|
||||
"ASDASDSAD!1": {
|
||||
state: ChallengeFeedbackStatus.TalerPayment,
|
||||
payment_secret: "secret",
|
||||
provider: "asdasdas",
|
||||
taler_pay_uri: "taler://pay/...",
|
||||
},
|
||||
},
|
||||
} as ReducerState);
|
||||
|
||||
export const UnsupportedFeedback = createExample(TestedComponent[type].solve, {
|
||||
...reducerStatesExample.challengeSolving,
|
||||
recovery_information,
|
||||
selected_challenge_uuid: "ASDASDSAD!1",
|
||||
challenge_feedback: {
|
||||
"ASDASDSAD!1": {
|
||||
state: ChallengeFeedbackStatus.Unsupported,
|
||||
unsupported_method: "method",
|
||||
},
|
||||
},
|
||||
} as ReducerState);
|
||||
|
||||
export const RateLimitExceededFeedback = createExample(
|
||||
TestedComponent[type].solve,
|
||||
{
|
||||
...reducerStatesExample.challengeSolving,
|
||||
recovery_information: {
|
||||
challenges: [
|
||||
{
|
||||
instructions: "does P equals NP?",
|
||||
type: "question",
|
||||
uuid: "ASDASDSAD!1",
|
||||
},
|
||||
],
|
||||
policies: [],
|
||||
},
|
||||
recovery_information,
|
||||
selected_challenge_uuid: "ASDASDSAD!1",
|
||||
challenge_feedback: {
|
||||
"ASDASDSAD!1": {
|
||||
@ -109,94 +174,76 @@ export const MessageRateLimitExceededFeedback = createExample(
|
||||
} as ReducerState,
|
||||
);
|
||||
|
||||
export const UnsupportedFeedback = createExample(TestedComponent[type].solve, {
|
||||
...reducerStatesExample.challengeSolving,
|
||||
recovery_information: {
|
||||
challenges: [
|
||||
{
|
||||
instructions: "does P equals NP?",
|
||||
type: "question",
|
||||
uuid: "ASDASDSAD!1",
|
||||
export const IbanInstructionsFeedback = createExample(
|
||||
TestedComponent[type].solve,
|
||||
{
|
||||
...reducerStatesExample.challengeSolving,
|
||||
recovery_information,
|
||||
selected_challenge_uuid: "ASDASDSAD!1",
|
||||
challenge_feedback: {
|
||||
"ASDASDSAD!1": {
|
||||
state: ChallengeFeedbackStatus.IbanInstructions,
|
||||
challenge_amount: "EUR:1",
|
||||
target_iban: "DE12345789000",
|
||||
target_business_name: "Data Loss Incorporated",
|
||||
wire_transfer_subject: "Anastasis 987654321",
|
||||
answer_code: 987654321,
|
||||
},
|
||||
],
|
||||
policies: [],
|
||||
},
|
||||
selected_challenge_uuid: "ASDASDSAD!1",
|
||||
challenge_feedback: {
|
||||
"ASDASDSAD!1": {
|
||||
state: ChallengeFeedbackStatus.Unsupported,
|
||||
http_status: 500,
|
||||
unsupported_method: "Question",
|
||||
},
|
||||
},
|
||||
} as ReducerState);
|
||||
} as ReducerState,
|
||||
);
|
||||
|
||||
export const TruthUnknownFeedback = createExample(TestedComponent[type].solve, {
|
||||
...reducerStatesExample.challengeSolving,
|
||||
recovery_information: {
|
||||
challenges: [
|
||||
{
|
||||
instructions: "does P equals NP?",
|
||||
type: "question",
|
||||
uuid: "ASDASDSAD!1",
|
||||
export const IncorrectAnswerFeedback = createExample(
|
||||
TestedComponent[type].solve,
|
||||
{
|
||||
...reducerStatesExample.challengeSolving,
|
||||
recovery_information,
|
||||
selected_challenge_uuid: "ASDASDSAD!1",
|
||||
challenge_feedback: {
|
||||
"ASDASDSAD!1": {
|
||||
state: ChallengeFeedbackStatus.IncorrectAnswer,
|
||||
},
|
||||
],
|
||||
policies: [],
|
||||
},
|
||||
selected_challenge_uuid: "ASDASDSAD!1",
|
||||
challenge_feedback: {
|
||||
"ASDASDSAD!1": {
|
||||
state: ChallengeFeedbackStatus.TruthUnknown,
|
||||
},
|
||||
},
|
||||
} as ReducerState);
|
||||
} as ReducerState,
|
||||
);
|
||||
|
||||
const ibanFeedback: ChallengeFeedbackBankTransferRequired = {
|
||||
state: ChallengeFeedbackStatus.IbanInstructions,
|
||||
challenge_amount: "EUR:1",
|
||||
target_iban: "DE12345789000",
|
||||
target_business_name: "Data Loss Incorporated",
|
||||
wire_transfer_subject: "Anastasis 987654321",
|
||||
answer_code: 987654321,
|
||||
};
|
||||
// export const AuthIbanFeedback = createExample(TestedComponent[type].solve, {
|
||||
// ...reducerStatesExample.challengeSolving,
|
||||
// recovery_information: {
|
||||
// challenges: [
|
||||
// {
|
||||
// instructions: "does P equals NP?",
|
||||
// type: "question",
|
||||
// uuid: "ASDASDSAD!1",
|
||||
// },
|
||||
// ],
|
||||
// policies: [],
|
||||
// },
|
||||
// selected_challenge_uuid: "ASDASDSAD!1",
|
||||
// challenge_feedback: {
|
||||
// "ASDASDSAD!1": ibanFeedback,
|
||||
// },
|
||||
// } as ReducerState);
|
||||
|
||||
export const AuthIbanFeedback = createExample(TestedComponent[type].solve, {
|
||||
...reducerStatesExample.challengeSolving,
|
||||
recovery_information: {
|
||||
challenges: [
|
||||
{
|
||||
instructions: "does P equals NP?",
|
||||
type: "question",
|
||||
uuid: "ASDASDSAD!1",
|
||||
},
|
||||
],
|
||||
policies: [],
|
||||
},
|
||||
selected_challenge_uuid: "ASDASDSAD!1",
|
||||
challenge_feedback: {
|
||||
"ASDASDSAD!1": ibanFeedback,
|
||||
},
|
||||
} as ReducerState);
|
||||
|
||||
export const PaymentFeedback = createExample(TestedComponent[type].solve, {
|
||||
...reducerStatesExample.challengeSolving,
|
||||
recovery_information: {
|
||||
challenges: [
|
||||
{
|
||||
instructions: "does P equals NP?",
|
||||
type: "question",
|
||||
uuid: "ASDASDSAD!1",
|
||||
},
|
||||
],
|
||||
policies: [],
|
||||
},
|
||||
selected_challenge_uuid: "ASDASDSAD!1",
|
||||
challenge_feedback: {
|
||||
"ASDASDSAD!1": {
|
||||
state: ChallengeFeedbackStatus.TalerPayment,
|
||||
taler_pay_uri: "taler://pay/...",
|
||||
provider: "https://localhost:8080/",
|
||||
payment_secret: "3P4561HAMHRRYEYD6CM6J7TS5VTD5SR2K2EXJDZEFSX92XKHR4KG",
|
||||
},
|
||||
},
|
||||
} as ReducerState);
|
||||
// export const PaymentFeedback = createExample(TestedComponent[type].solve, {
|
||||
// ...reducerStatesExample.challengeSolving,
|
||||
// recovery_information: {
|
||||
// challenges: [
|
||||
// {
|
||||
// instructions: "does P equals NP?",
|
||||
// type: "question",
|
||||
// uuid: "ASDASDSAD!1",
|
||||
// },
|
||||
// ],
|
||||
// policies: [],
|
||||
// },
|
||||
// selected_challenge_uuid: "ASDASDSAD!1",
|
||||
// challenge_feedback: {
|
||||
// "ASDASDSAD!1": {
|
||||
// state: ChallengeFeedbackStatus.TalerPayment,
|
||||
// taler_pay_uri: "taler://pay/...",
|
||||
// provider: "https://localhost:8080/",
|
||||
// payment_secret: "3P4561HAMHRRYEYD6CM6J7TS5VTD5SR2K2EXJDZEFSX92XKHR4KG",
|
||||
// },
|
||||
// },
|
||||
// } as ReducerState);
|
||||
|
@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
export * as AddingProviderScreen from "./AddingProviderScreen/stories.js";
|
||||
export * as algo from "./AttributeEntryScreen.stories.js";
|
||||
export * as AttributeEntryScreen from "./AttributeEntryScreen.stories.js";
|
||||
|
||||
export * as AuthenticationEditorScreen from "./AuthenticationEditorScreen.stories.js";
|
||||
export * as authMethod_AuthMethodEmailSetup from "./authMethod/AuthMethodEmailSetup.stories.js";
|
||||
|
@ -85,7 +85,7 @@ function ErrorBoundary(props: {
|
||||
children: ComponentChildren;
|
||||
}): VNode {
|
||||
const [error, resetError] = useErrorBoundary((error) =>
|
||||
console.log("got error", error),
|
||||
console.log("ErrorBoundary got error", error),
|
||||
);
|
||||
if (error) {
|
||||
return (
|
||||
@ -132,7 +132,7 @@ export function AnastasisClientFrame(props: AnastasisClientFrameProps): VNode {
|
||||
|
||||
history.pushState({ id: nextId }, "unused", `#${nextId}`);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
console.log("ERROR doNext ", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,6 @@ function parseExampleImport(
|
||||
im: any,
|
||||
name?: string,
|
||||
): ComponentItem {
|
||||
console.log(im);
|
||||
const component = name || im.default.title;
|
||||
const order: number = im.default.args?.order || 0;
|
||||
return {
|
||||
@ -372,9 +371,8 @@ function LiveReload({ port = 8002 }: { port?: number }): VNode {
|
||||
}
|
||||
|
||||
function setupLiveReload(port: number, onReload: () => void): void {
|
||||
const protocol = location.protocol === "https:" ? "wss:" : "ws:";
|
||||
const host = location.hostname;
|
||||
const socketPath = `${protocol}//${host}:${port}/socket`;
|
||||
const socketPath = `ws://localhost:8003/socket`;
|
||||
// const socketPath = `${protocol}//${host}:${port}/socket`;
|
||||
|
||||
const ws = new WebSocket(socketPath);
|
||||
ws.onmessage = (message) => {
|
||||
|
@ -54,7 +54,7 @@ export function createExample<Props>(
|
||||
discoverMore: noop,
|
||||
discoverStart: noop,
|
||||
discoveryState: {
|
||||
state: "none",
|
||||
state: "finished",
|
||||
},
|
||||
currentError: undefined,
|
||||
back: noop,
|
||||
@ -204,14 +204,17 @@ const base = {
|
||||
} as AuthenticationProviderStatusOk,
|
||||
|
||||
"http://localhost:8087/": {
|
||||
status: "error",
|
||||
code: 8414,
|
||||
hint: "request to provider failed",
|
||||
} as AuthenticationProviderStatusError,
|
||||
"http://localhost:8088/": {
|
||||
status: "error",
|
||||
code: 8414,
|
||||
hint: "request to provider failed",
|
||||
} as AuthenticationProviderStatusError,
|
||||
"http://localhost:8089/": {
|
||||
status: "error",
|
||||
code: 8414,
|
||||
hint: "request to provider failed",
|
||||
} as AuthenticationProviderStatusError,
|
||||
|
@ -1,4 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
#clean up
|
||||
rm /tmp/send_signal
|
||||
|
||||
socat TCP-LISTEN:8003,fork,reuseaddr,keepalive EXEC:"./watch/reply.sh"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user