refactoring challenge overview to look more like policy reviewing

This commit is contained in:
Sebastian 2021-11-02 12:31:37 -03:00
parent aa78c1105e
commit 1fd337f4fe
No known key found for this signature in database
GPG Key ID: BE4FF68352439FC1
20 changed files with 85 additions and 68 deletions

View File

@ -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";

View File

@ -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',
}],

View File

@ -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>
);
})}

View File

@ -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()

View File

@ -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>

View File

@ -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)),
},
});

View File

@ -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)),
},
})