refactoring challenge overview to look more like policy reviewing
This commit is contained in:
parent
aa78c1105e
commit
1fd337f4fe
@ -3,7 +3,7 @@ import { AuthMethod } from "anastasis-core";
|
||||
import { ComponentChildren, h, VNode } from "preact";
|
||||
import { useState } from "preact/hooks";
|
||||
import { useAnastasisContext } from "../../context/anastasis";
|
||||
import { authMethods, KnownAuthMethods } from "./authMethodSetup";
|
||||
import { authMethods, KnownAuthMethods } from "./authMethod";
|
||||
import { AnastasisClientFrame } from "./index";
|
||||
|
||||
|
||||
|
@ -56,17 +56,17 @@ export const SomePoliciesOneSolved = createExample(TestedComponent, {
|
||||
policies: [[{ uuid: '1' }, { uuid: '2' }], [{ uuid: 'uuid-3' }]],
|
||||
challenges: [{
|
||||
cost: 'USD:1',
|
||||
instructions: 'just go for it',
|
||||
instructions: 'this question cost 1 USD',
|
||||
type: 'question',
|
||||
uuid: '1',
|
||||
}, {
|
||||
cost: 'USD:1',
|
||||
instructions: 'just go for it',
|
||||
cost: 'USD:0',
|
||||
instructions: 'answering this question is free',
|
||||
type: 'question',
|
||||
uuid: '2',
|
||||
}, {
|
||||
cost: 'USD:1',
|
||||
instructions: 'just go for it',
|
||||
instructions: 'this question is already answered',
|
||||
type: 'question',
|
||||
uuid: 'uuid-3',
|
||||
}]
|
||||
@ -84,8 +84,8 @@ export const OneBadConfiguredPolicy = createExample(TestedComponent, {
|
||||
policies: [[{ uuid: '1' }, { uuid: '2' }]],
|
||||
challenges: [{
|
||||
cost: 'USD:1',
|
||||
instructions: 'just go for it',
|
||||
type: 'sasd',
|
||||
instructions: 'this policy has a missing uuid (the other auth method)',
|
||||
type: 'totp',
|
||||
uuid: '1',
|
||||
}],
|
||||
},
|
||||
@ -101,35 +101,48 @@ export const OnePolicyWithAllTheChallenges = createExample(TestedComponent, {
|
||||
{ uuid: '4' },
|
||||
{ uuid: '5' },
|
||||
{ uuid: '6' },
|
||||
{ uuid: '7' },
|
||||
{ uuid: '8' },
|
||||
]],
|
||||
challenges: [{
|
||||
cost: 'USD:1',
|
||||
instructions: 'answer the a question correctly',
|
||||
instructions: 'Does P equals NP?',
|
||||
type: 'question',
|
||||
uuid: '1',
|
||||
},{
|
||||
cost: 'USD:1',
|
||||
instructions: 'enter a text received by a sms',
|
||||
instructions: 'SMS to 555-555',
|
||||
type: 'sms',
|
||||
uuid: '2',
|
||||
},{
|
||||
cost: 'USD:1',
|
||||
instructions: 'enter a text received by a email',
|
||||
instructions: 'Email to qwe@asd.com',
|
||||
type: 'email',
|
||||
uuid: '3',
|
||||
},{
|
||||
cost: 'USD:1',
|
||||
instructions: 'enter a code based on a time-based one-time password',
|
||||
instructions: 'Enter 8 digits code for "Anastasis"',
|
||||
type: 'totp',
|
||||
uuid: '4',
|
||||
},{
|
||||
cost: 'USD:1',
|
||||
instructions: 'send a wire transfer to an account',
|
||||
},{//
|
||||
cost: 'USD:0',
|
||||
instructions: 'Wire transfer from ASDXCVQWE123123 with holder Florian',
|
||||
type: 'iban',
|
||||
uuid: '5',
|
||||
},{
|
||||
cost: 'USD:1',
|
||||
instructions: 'just go for it',
|
||||
instructions: 'Join a video call',
|
||||
type: 'video',//Enter 8 digits code for "Anastasis"
|
||||
uuid: '7',
|
||||
},{
|
||||
},{
|
||||
cost: 'USD:1',
|
||||
instructions: 'Letter to address in postal code DE123123',
|
||||
type: 'post',//Enter 8 digits code for "Anastasis"
|
||||
uuid: '8',
|
||||
},{
|
||||
cost: 'USD:1',
|
||||
instructions: 'instruction for an unknown type of challenge',
|
||||
type: 'new-type-of-challenge',
|
||||
uuid: '6',
|
||||
}],
|
||||
@ -154,52 +167,52 @@ export const OnePolicyWithAllTheChallengesInDifferentState = createExample(Teste
|
||||
]],
|
||||
challenges: [{
|
||||
cost: 'USD:1',
|
||||
instructions: 'answer the a question correctly',
|
||||
instructions: 'in state "solved"',
|
||||
type: 'question',
|
||||
uuid: '1',
|
||||
},{
|
||||
cost: 'USD:1',
|
||||
instructions: 'answer the a question correctly',
|
||||
instructions: 'in state "hint"',
|
||||
type: 'question',
|
||||
uuid: '2',
|
||||
},{
|
||||
cost: 'USD:1',
|
||||
instructions: 'answer the a question correctly',
|
||||
instructions: 'in state "details"',
|
||||
type: 'question',
|
||||
uuid: '3',
|
||||
},{
|
||||
cost: 'USD:1',
|
||||
instructions: 'answer the a question correctly',
|
||||
instructions: 'in state "body"',
|
||||
type: 'question',
|
||||
uuid: '4',
|
||||
},{
|
||||
cost: 'USD:1',
|
||||
instructions: 'answer the a question correctly',
|
||||
instructions: 'in state "redirect"',
|
||||
type: 'question',
|
||||
uuid: '5',
|
||||
},{
|
||||
cost: 'USD:1',
|
||||
instructions: 'answer the a question correctly',
|
||||
instructions: 'in state "server-failure"',
|
||||
type: 'question',
|
||||
uuid: '6',
|
||||
},{
|
||||
cost: 'USD:1',
|
||||
instructions: 'answer the a question correctly',
|
||||
instructions: 'in state "truth-unknown"',
|
||||
type: 'question',
|
||||
uuid: '7',
|
||||
},{
|
||||
cost: 'USD:1',
|
||||
instructions: 'answer the a question correctly',
|
||||
instructions: 'in state "rate-limit-exceeded"',
|
||||
type: 'question',
|
||||
uuid: '8',
|
||||
},{
|
||||
cost: 'USD:1',
|
||||
instructions: 'answer the a question correctly',
|
||||
instructions: 'in state "authentication-timeout"',
|
||||
type: 'question',
|
||||
uuid: '9',
|
||||
},{
|
||||
cost: 'USD:1',
|
||||
instructions: 'answer the a question correctly',
|
||||
instructions: 'in state "external-instructions"',
|
||||
type: 'question',
|
||||
uuid: '10',
|
||||
}],
|
||||
|
@ -1,7 +1,9 @@
|
||||
/* eslint-disable @typescript-eslint/camelcase */
|
||||
import { ChallengeFeedback } from "anastasis-core";
|
||||
import { h, VNode } from "preact";
|
||||
import { useAnastasisContext } from "../../context/anastasis";
|
||||
import { AnastasisClientFrame } from "./index";
|
||||
import { authMethods, KnownAuthMethods } from "./authMethod";
|
||||
|
||||
export function ChallengeOverviewScreen(): VNode {
|
||||
const reducer = useAnastasisContext()
|
||||
@ -50,59 +52,61 @@ export function ChallengeOverviewScreen(): VNode {
|
||||
const errors = !atLeastThereIsOnePolicySolved ? "Solve one policy before proceeding" : undefined;
|
||||
return (
|
||||
<AnastasisClientFrame hideNext={errors} title="Recovery: Solve challenges">
|
||||
{!policies.length ? <p>
|
||||
{!policies.length ? <p class="block">
|
||||
No policies found, try with another version of the secret
|
||||
</p> : (policies.length === 1 ? <p>
|
||||
</p> : (policies.length === 1 ? <p class="block">
|
||||
One policy found for this secret. You need to solve all the challenges in order to recover your secret.
|
||||
</p> : <p>
|
||||
</p> : <p class="block">
|
||||
We have found {policies.length} polices. You need to solve all the challenges from one policy in order
|
||||
to recover your secret.
|
||||
</p>)}
|
||||
{policiesWithInfo.map((row, i) => {
|
||||
const tableBody = row.challenges.map(({ info, uuid }) => {
|
||||
{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]
|
||||
return (
|
||||
<tr key={uuid}>
|
||||
<td>{info.type}</td>
|
||||
<td>
|
||||
<div key={uuid} class="block" style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<div style={{display:'flex', alignItems:'center'}}>
|
||||
<span class="icon">
|
||||
{method?.icon}
|
||||
</span>
|
||||
<span>
|
||||
{info.instructions}
|
||||
</td>
|
||||
<td>{info.feedback?.state ?? "unknown"}</td>
|
||||
<td>{info.cost}</td>
|
||||
<td>
|
||||
{info.feedback?.state !== "solved" ? (
|
||||
<a onClick={() => reducer.transition("select_challenge", { uuid })}>
|
||||
Solve
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
{method && info.feedback?.state !== "solved" ? (
|
||||
<a class="button" onClick={() => reducer.transition("select_challenge", { uuid })}>
|
||||
{isFree ? "Solve" : `Pay and Solve`}
|
||||
</a>
|
||||
) : null}
|
||||
</td>
|
||||
</tr>
|
||||
{info.feedback?.state === "solved" ? (
|
||||
<a class="button is-success"> Solved </a>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
|
||||
const policyName = policy.challenges.map(x => x.info.type).join(" + ");
|
||||
const opa = !atLeastThereIsOnePolicySolved ? undefined : ( policy.isPolicySolved ? undefined : '0.6')
|
||||
return (
|
||||
<div key={i}>
|
||||
<b>Policy #{i + 1}</b>
|
||||
{row.challenges.length === 0 && <p>
|
||||
This policy doesn't have challenges
|
||||
<div key={policy_index} class="box" style={{
|
||||
opacity: opa
|
||||
}}>
|
||||
<h3 class="subtitle">
|
||||
Policy #{policy_index + 1}: {policyName}
|
||||
</h3>
|
||||
{policy.challenges.length === 0 && <p>
|
||||
This policy doesn't have challenges.
|
||||
</p>}
|
||||
{row.challenges.length === 1 && <p>
|
||||
This policy just have one challenge to be solved
|
||||
{policy.challenges.length === 1 && <p>
|
||||
This policy just have one challenge.
|
||||
</p>}
|
||||
{row.challenges.length > 1 && <p>
|
||||
This policy have {row.challenges.length} challenges
|
||||
{policy.challenges.length > 1 && <p>
|
||||
This policy have {policy.challenges.length} challenges.
|
||||
</p>}
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>Challenge type</td>
|
||||
<td>Description</td>
|
||||
<td>Status</td>
|
||||
<td>Cost</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{tableBody}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
@ -2,7 +2,7 @@
|
||||
import { h, VNode } from "preact";
|
||||
import { useAnastasisContext } from "../../context/anastasis";
|
||||
import { AnastasisClientFrame } from "./index";
|
||||
import { authMethods, KnownAuthMethods } from "./authMethodSetup";
|
||||
import { authMethods, KnownAuthMethods } from "./authMethod";
|
||||
|
||||
export function ReviewPoliciesScreen(): VNode {
|
||||
const reducer = useAnastasisContext()
|
||||
|
@ -51,7 +51,7 @@ export function AuthMethodEmailSetup({ cancel, addAuthMethod, configured }: Auth
|
||||
</div></section>}
|
||||
<div>
|
||||
<div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
|
||||
<button class="button" onClick={cancel}>Canceul</button>
|
||||
<button class="button" onClick={cancel}>Cancel</button>
|
||||
<span data-tooltip={errors}>
|
||||
<button class="button is-info" disabled={errors !== undefined} onClick={addEmailAuth}>Add</button>
|
||||
</span>
|
@ -25,7 +25,7 @@ export function AuthMethodTotpSetup({ addAuthMethod, cancel, configured }: AuthM
|
||||
const addTotpAuth = (): void => addAuthMethod({
|
||||
authentication_method: {
|
||||
type: "totp",
|
||||
instructions: `Enter ${digits} digits code for ${name}`,
|
||||
instructions: `Enter ${digits} digits code for "${name}"`,
|
||||
challenge: encodeCrock(stringToBytes(totpURL)),
|
||||
},
|
||||
});
|
@ -15,7 +15,7 @@ export function AuthMethodVideoSetup({cancel, addAuthMethod, configured}: AuthMe
|
||||
addAuthMethod({
|
||||
authentication_method: {
|
||||
type: "video",
|
||||
instructions: image,
|
||||
instructions: 'Join a video call',
|
||||
challenge: encodeCrock(stringToBytes(image)),
|
||||
},
|
||||
})
|
Loading…
Reference in New Issue
Block a user