import { ChallengeFeedback, ChallengeFeedbackStatus } from "anastasis-core"; import { h, VNode } from "preact"; import { useAnastasisContext } from "../../context/anastasis"; import { AnastasisClientFrame } from "./index"; import { authMethods, KnownAuthMethods } from "./authMethod"; function OverviewFeedbackDisplay(props: { feedback?: ChallengeFeedback }) { const { feedback } = props; if (!feedback) { return null; } switch (feedback.state) { case ChallengeFeedbackStatus.Message: return (
{feedback.message}
); case ChallengeFeedbackStatus.Solved: return
case ChallengeFeedbackStatus.Pending: case ChallengeFeedbackStatus.Solved: case ChallengeFeedbackStatus.AuthIban: return null; case ChallengeFeedbackStatus.ServerFailure: return
Server error.
; case ChallengeFeedbackStatus.RateLimitExceeded: return
There were to many failed attempts.
; case ChallengeFeedbackStatus.Unsupported: return
This client doesn't support solving this type of challenge. Use another version or contact the provider.
; case ChallengeFeedbackStatus.TruthUnknown: return
Provider doesn't recognize the challenge of the policy. Contact the provider for further information.
; case ChallengeFeedbackStatus.Redirect: default: return
; } } export function ChallengeOverviewScreen(): VNode { const reducer = useAnastasisContext(); if (!reducer) { return
no reducer in context
; } if ( !reducer.currentReducerState || reducer.currentReducerState.recovery_state === undefined ) { return
invalid state
; } const policies = reducer.currentReducerState.recovery_information?.policies ?? []; const knownChallengesArray = reducer.currentReducerState.recovery_information?.challenges ?? []; const challengeFeedback = reducer.currentReducerState?.challenge_feedback ?? {}; const knownChallengesMap: { [uuid: string]: { type: string; instructions: string; cost: string; feedback: ChallengeFeedback | undefined; }; } = {}; for (const ch of knownChallengesArray) { knownChallengesMap[ch.uuid] = { type: ch.type, cost: ch.cost, instructions: ch.instructions, feedback: challengeFeedback[ch.uuid], }; } const policiesWithInfo = policies.map((row) => { let isPolicySolved = true; const challenges = row .map(({ uuid }) => { const info = knownChallengesMap[uuid]; const isChallengeSolved = info?.feedback?.state === "solved"; isPolicySolved = isPolicySolved && isChallengeSolved; return { info, uuid, isChallengeSolved }; }) .filter((ch) => ch.info !== undefined); return { isPolicySolved, challenges }; }); const atLeastThereIsOnePolicySolved = policiesWithInfo.find((p) => p.isPolicySolved) !== undefined; const errors = !atLeastThereIsOnePolicySolved ? "Solve one policy before proceeding" : undefined; return ( {!policies.length ? (

No policies found, try with another version of the secret

) : policies.length === 1 ? (

One policy found for this secret. You need to solve all the challenges in order to recover your secret.

) : (

We have found {policies.length} polices. You need to solve all the challenges from one policy in order to recover your secret.

)} {policiesWithInfo.map((policy, policy_index) => { const tableBody = policy.challenges.map(({ info, uuid }) => { const isFree = !info.cost || info.cost.endsWith(":0"); const method = authMethods[info.type as KnownAuthMethods]; if (!method) { return
unknown challenge
} function ChallengeButton({ id, feedback }: { id: string; feedback?: ChallengeFeedback }): VNode { function selectChallenge(): void { if (reducer) reducer.transition("select_challenge", { uuid: id }) } if (!feedback) { return
} switch (feedback.state) { case ChallengeFeedbackStatus.ServerFailure: case ChallengeFeedbackStatus.Unsupported: case ChallengeFeedbackStatus.TruthUnknown: case ChallengeFeedbackStatus.RateLimitExceeded: return
case ChallengeFeedbackStatus.AuthIban: case ChallengeFeedbackStatus.Payment: return
case ChallengeFeedbackStatus.Redirect: return
case ChallengeFeedbackStatus.Solved: return
Solved
default: return
} // return
// {feedback.state !== "solved" ? ( // // } // > // {isFree ? "Solve" : `Pay and Solve`} // // ) : null} // {feedback.state === "solved" ? ( // //
Solved
//
Solved
// ) : null} //
} return (
{method?.icon} {info.instructions}
); }); const policyName = policy.challenges .map((x) => x.info.type) .join(" + "); const opa = !atLeastThereIsOnePolicySolved ? undefined : policy.isPolicySolved ? undefined : "0.6"; return (

Policy #{policy_index + 1}: {policyName}

{policy.challenges.length === 0 && (

This policy doesn't have challenges.

)} {policy.challenges.length === 1 && (

This policy just have one challenge.

)} {policy.challenges.length > 1 && (

This policy have {policy.challenges.length} challenges.

)} {tableBody}
); })} ); }