aboutsummaryrefslogtreecommitdiff
path: root/packages/anastasis-webui/src/pages/home
diff options
context:
space:
mode:
Diffstat (limited to 'packages/anastasis-webui/src/pages/home')
-rw-r--r--packages/anastasis-webui/src/pages/home/AddingProviderScreen.stories.tsx52
-rw-r--r--packages/anastasis-webui/src/pages/home/AddingProviderScreen.tsx261
-rw-r--r--packages/anastasis-webui/src/pages/home/AttributeEntryScreen.stories.tsx120
-rw-r--r--packages/anastasis-webui/src/pages/home/AttributeEntryScreen.tsx107
-rw-r--r--packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.stories.tsx105
-rw-r--r--packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx26
-rw-r--r--packages/anastasis-webui/src/pages/home/BackupFinishedScreen.stories.tsx45
-rw-r--r--packages/anastasis-webui/src/pages/home/BackupFinishedScreen.tsx85
-rw-r--r--packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.stories.tsx14
-rw-r--r--packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.tsx208
-rw-r--r--packages/anastasis-webui/src/pages/home/ChallengePayingScreen.stories.tsx22
-rw-r--r--packages/anastasis-webui/src/pages/home/ChallengePayingScreen.tsx18
-rw-r--r--packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.stories.tsx33
-rw-r--r--packages/anastasis-webui/src/pages/home/EditPoliciesScreen.stories.tsx190
-rw-r--r--packages/anastasis-webui/src/pages/home/EditPoliciesScreen.tsx200
-rw-r--r--packages/anastasis-webui/src/pages/home/PoliciesPayingScreen.stories.tsx41
-rw-r--r--packages/anastasis-webui/src/pages/home/PoliciesPayingScreen.tsx17
-rw-r--r--packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.stories.tsx26
-rw-r--r--packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.tsx60
-rw-r--r--packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.stories.tsx216
-rw-r--r--packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx119
-rw-r--r--packages/anastasis-webui/src/pages/home/SecretEditorScreen.stories.tsx21
-rw-r--r--packages/anastasis-webui/src/pages/home/SecretSelectionScreen.stories.tsx24
-rw-r--r--packages/anastasis-webui/src/pages/home/SecretSelectionScreen.tsx185
-rw-r--r--packages/anastasis-webui/src/pages/home/SolveScreen.stories.tsx62
-rw-r--r--packages/anastasis-webui/src/pages/home/SolveScreen.tsx196
-rw-r--r--packages/anastasis-webui/src/pages/home/StartScreen.stories.tsx22
-rw-r--r--packages/anastasis-webui/src/pages/home/StartScreen.tsx26
-rw-r--r--packages/anastasis-webui/src/pages/home/TruthsPayingScreen.stories.tsx26
-rw-r--r--packages/anastasis-webui/src/pages/home/TruthsPayingScreen.tsx16
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSetup.stories.tsx84
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSetup.tsx95
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.stories.tsx106
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.tsx38
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSetup.stories.tsx84
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSetup.tsx110
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSolve.stories.tsx58
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSolve.tsx39
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSetup.stories.tsx84
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSetup.tsx118
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.stories.tsx58
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.tsx37
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSetup.stories.tsx86
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSetup.tsx95
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.stories.tsx293
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.tsx37
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSetup.stories.tsx84
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSetup.tsx72
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSolve.stories.tsx58
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSolve.tsx37
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSetup.stories.tsx84
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSetup.tsx109
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.stories.tsx58
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.tsx37
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.stories.tsx85
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.tsx81
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.stories.tsx58
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.tsx37
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/index.tsx29
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/totp.ts57
60 files changed, 2910 insertions, 1941 deletions
diff --git a/packages/anastasis-webui/src/pages/home/AddingProviderScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/AddingProviderScreen.stories.tsx
index 08e2b4371..9b067127d 100644
--- a/packages/anastasis-webui/src/pages/home/AddingProviderScreen.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/AddingProviderScreen.stories.tsx
@@ -15,24 +15,23 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { ReducerState } from 'anastasis-core';
-import { createExample, reducerStatesExample } from '../../utils';
-import { AddingProviderScreen as TestedComponent } from './AddingProviderScreen';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { ReducerState } from "anastasis-core";
+import { createExample, reducerStatesExample } from "../../utils";
+import { AddingProviderScreen as TestedComponent } from "./AddingProviderScreen";
export default {
- title: 'Pages/ManageProvider',
+ title: "Pages/ManageProvider",
component: TestedComponent,
args: {
order: 1,
},
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
@@ -40,20 +39,31 @@ export const NewProvider = createExample(TestedComponent, {
...reducerStatesExample.authEditing,
} as ReducerState);
-
export const NewProviderWithoutProviderList = createExample(TestedComponent, {
...reducerStatesExample.authEditing,
- authentication_providers: {}
+ authentication_providers: {},
} as ReducerState);
-export const NewVideoProvider = createExample(TestedComponent, {
- ...reducerStatesExample.authEditing,
-} as ReducerState, { providerType: 'video'});
+export const NewVideoProvider = createExample(
+ TestedComponent,
+ {
+ ...reducerStatesExample.authEditing,
+ } as ReducerState,
+ { providerType: "video" },
+);
-export const NewSmsProvider = createExample(TestedComponent, {
- ...reducerStatesExample.authEditing,
-} as ReducerState, { providerType: 'sms'});
+export const NewSmsProvider = createExample(
+ TestedComponent,
+ {
+ ...reducerStatesExample.authEditing,
+ } as ReducerState,
+ { providerType: "sms" },
+);
-export const NewIBANProvider = createExample(TestedComponent, {
- ...reducerStatesExample.authEditing,
-} as ReducerState, { providerType: 'iban' });
+export const NewIBANProvider = createExample(
+ TestedComponent,
+ {
+ ...reducerStatesExample.authEditing,
+ } as ReducerState,
+ { providerType: "iban" },
+);
diff --git a/packages/anastasis-webui/src/pages/home/AddingProviderScreen.tsx b/packages/anastasis-webui/src/pages/home/AddingProviderScreen.tsx
index 7504f4d2b..96b38e92d 100644
--- a/packages/anastasis-webui/src/pages/home/AddingProviderScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/AddingProviderScreen.tsx
@@ -11,185 +11,250 @@ interface Props {
onCancel: () => void;
}
-
-async function testProvider(url: string, expectedMethodType?: string): Promise<void> {
+async function testProvider(
+ url: string,
+ expectedMethodType?: string,
+): Promise<void> {
try {
- const response = await fetch(new URL("config", url).href)
- const json = await (response.json().catch(d => ({})))
+ const response = await fetch(new URL("config", url).href);
+ const json = await response.json().catch((d) => ({}));
if (!("methods" in json) || !Array.isArray(json.methods)) {
- throw Error("This provider doesn't have authentication method. Check the provider URL")
+ throw Error(
+ "This provider doesn't have authentication method. Check the provider URL",
+ );
}
- console.log("expected", expectedMethodType)
+ console.log("expected", expectedMethodType);
if (!expectedMethodType) {
- return
+ return;
}
- let found = false
+ let found = false;
for (let i = 0; i < json.methods.length && !found; i++) {
- found = json.methods[i].type === expectedMethodType
+ found = json.methods[i].type === expectedMethodType;
}
if (!found) {
- throw Error(`This provider does not support authentication method ${expectedMethodType}`)
+ throw Error(
+ `This provider does not support authentication method ${expectedMethodType}`,
+ );
}
- return
+ return;
} catch (e) {
- console.log("error", e)
- const error = e instanceof Error ?
- Error(`There was an error testing this provider, try another one. ${e.message}`) :
- Error(`There was an error testing this provider, try another one.`)
- throw error
+ console.log("error", e);
+ const error =
+ e instanceof Error
+ ? Error(
+ `There was an error testing this provider, try another one. ${e.message}`,
+ )
+ : Error(`There was an error testing this provider, try another one.`);
+ throw error;
}
-
}
export function AddingProviderScreen({ providerType, onCancel }: Props): VNode {
const reducer = useAnastasisContext();
const [providerURL, setProviderURL] = useState("");
- const [error, setError] = useState<string | undefined>()
- const [testing, setTesting] = useState(false)
- const providerLabel = providerType ? authMethods[providerType].label : undefined
+ const [error, setError] = useState<string | undefined>();
+ const [testing, setTesting] = useState(false);
+ const providerLabel = providerType
+ ? authMethods[providerType].label
+ : undefined;
//FIXME: move this timeout logic into a hook
const timeout = useRef<number | undefined>(undefined);
useEffect(() => {
- if (timeout) window.clearTimeout(timeout.current)
+ if (timeout) window.clearTimeout(timeout.current);
timeout.current = window.setTimeout(async () => {
- const url = providerURL.endsWith('/') ? providerURL : (providerURL + '/')
+ const url = providerURL.endsWith("/") ? providerURL : providerURL + "/";
if (!providerURL || authProviders.includes(url)) return;
try {
- setTesting(true)
- await testProvider(url, providerType)
+ setTesting(true);
+ await testProvider(url, providerType);
// this is use as tested but everything when ok
// undefined will mean that the field is not dirty
- setError("")
+ setError("");
} catch (e) {
- console.log("tuvieja", e)
- if (e instanceof Error) setError(e.message)
+ console.log("tuvieja", e);
+ if (e instanceof Error) setError(e.message);
}
- setTesting(false)
+ setTesting(false);
}, 200);
- }, [providerURL, reducer])
-
+ }, [providerURL, reducer]);
if (!reducer) {
return <div>no reducer in context</div>;
}
- if (!reducer.currentReducerState || !("authentication_providers" in reducer.currentReducerState)) {
- return <div>invalid state</div>
+ if (
+ !reducer.currentReducerState ||
+ !("authentication_providers" in reducer.currentReducerState)
+ ) {
+ return <div>invalid state</div>;
}
async function addProvider(provider_url: string): Promise<void> {
- await reducer?.transition("add_provider", { provider_url })
- onCancel()
+ await reducer?.transition("add_provider", { provider_url });
+ onCancel();
}
function deleteProvider(provider_url: string): void {
- reducer?.transition("delete_provider", { provider_url })
+ reducer?.transition("delete_provider", { provider_url });
}
- const allAuthProviders = reducer.currentReducerState.authentication_providers || {}
- const authProviders = Object.keys(allAuthProviders).filter(provUrl => {
+ const allAuthProviders =
+ reducer.currentReducerState.authentication_providers || {};
+ const authProviders = Object.keys(allAuthProviders).filter((provUrl) => {
const p = allAuthProviders[provUrl];
if (!providerLabel) {
- return p && ("currency" in p)
+ return p && "currency" in p;
} else {
- return p && ("currency" in p) && p.methods.findIndex(m => m.type === providerType) !== -1
+ return (
+ p &&
+ "currency" in p &&
+ p.methods.findIndex((m) => m.type === providerType) !== -1
+ );
}
- })
+ });
- let errors = !providerURL ? 'Add provider URL' : undefined
+ let errors = !providerURL ? "Add provider URL" : undefined;
let url: string | undefined;
try {
- url = new URL("",providerURL).href
+ url = new URL("", providerURL).href;
} catch {
- errors = 'Check the URL'
+ errors = "Check the URL";
}
if (!!error && !errors) {
- errors = error
+ errors = error;
}
if (!errors && authProviders.includes(url!)) {
- errors = 'That provider is already known'
+ errors = "That provider is already known";
}
return (
- <AnastasisClientFrame hideNav
+ <AnastasisClientFrame
+ hideNav
title="Backup: Manage providers"
- hideNext={errors}>
+ hideNext={errors}
+ >
<div>
- {!providerLabel ?
- <p>
- Add a provider url
- </p> :
- <p>
- Add a provider url for a {providerLabel} service
- </p>
- }
+ {!providerLabel ? (
+ <p>Add a provider url</p>
+ ) : (
+ <p>Add a provider url for a {providerLabel} service</p>
+ )}
<div class="container">
<TextInput
label="Provider URL"
placeholder="https://provider.com"
grabFocus
error={errors}
- bind={[providerURL, setProviderURL]} />
+ bind={[providerURL, setProviderURL]}
+ />
</div>
- <p class="block">
- Example: https://kudos.demo.anastasis.lu
- </p>
+ <p class="block">Example: https://kudos.demo.anastasis.lu</p>
{testing && <p class="has-text-info">Testing</p>}
-
- <div class="block" style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
- <button class="button" onClick={onCancel}>Cancel</button>
+
+ <div
+ class="block"
+ style={{
+ marginTop: "2em",
+ display: "flex",
+ justifyContent: "space-between",
+ }}
+ >
+ <button class="button" onClick={onCancel}>
+ Cancel
+ </button>
<span data-tooltip={errors}>
- <button class="button is-info" disabled={error !== "" || testing} onClick={() => addProvider(url!)}>Add</button>
+ <button
+ class="button is-info"
+ disabled={error !== "" || testing}
+ onClick={() => addProvider(url!)}
+ >
+ Add
+ </button>
</span>
</div>
{authProviders.length > 0 ? (
- !providerLabel ?
+ !providerLabel ? (
+ <p class="subtitle">Current providers</p>
+ ) : (
<p class="subtitle">
- Current providers
- </p> : <p class="subtitle">
Current providers for {providerLabel} service
</p>
+ )
+ ) : !providerLabel ? (
+ <p class="subtitle">No known providers, add one.</p>
) : (
- !providerLabel ? <p class="subtitle">
- No known providers, add one.
- </p> : <p class="subtitle">
- No known providers for {providerLabel} service
- </p>
+ <p class="subtitle">No known providers for {providerLabel} service</p>
)}
- {authProviders.map(k => {
- const p = allAuthProviders[k] as AuthenticationProviderStatusOk
- return <TableRow url={k} info={p} onDelete={deleteProvider} />
+ {authProviders.map((k) => {
+ const p = allAuthProviders[k] as AuthenticationProviderStatusOk;
+ return <TableRow url={k} info={p} onDelete={deleteProvider} />;
})}
</div>
</AnastasisClientFrame>
);
}
-function TableRow({ url, info, onDelete }: { onDelete: (s: string) => void, url: string, info: AuthenticationProviderStatusOk }) {
- const [status, setStatus] = useState("checking")
+function TableRow({
+ url,
+ info,
+ onDelete,
+}: {
+ onDelete: (s: string) => void;
+ url: string;
+ info: AuthenticationProviderStatusOk;
+}) {
+ 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 <div class="box" style={{ display: 'flex', justifyContent: 'space-between' }}>
- <div>
- <div class="subtitle">{url}</div>
- <dl>
- <dt><b>Business Name</b></dt>
- <dd>{info.business_name}</dd>
- <dt><b>Supported methods</b></dt>
- <dd>{info.methods.map(m => m.type).join(',')}</dd>
- <dt><b>Maximum storage</b></dt>
- <dd>{info.storage_limit_in_megabytes} Mb</dd>
- <dt><b>Status</b></dt>
- <dd>{status}</dd>
- </dl>
- </div>
- <div class="block" style={{ marginTop: 'auto', marginBottom: 'auto', display: 'flex', justifyContent: 'space-between', flexDirection: 'column' }}>
- <button class="button is-danger" onClick={() => onDelete(url)}>Remove</button>
+ testProvider(url.endsWith("/") ? url.substring(0, url.length - 1) : url)
+ .then(function () {
+ setStatus("responding");
+ })
+ .catch(function () {
+ setStatus("failed to contact");
+ });
+ });
+ return (
+ <div
+ class="box"
+ style={{ display: "flex", justifyContent: "space-between" }}
+ >
+ <div>
+ <div class="subtitle">{url}</div>
+ <dl>
+ <dt>
+ <b>Business Name</b>
+ </dt>
+ <dd>{info.business_name}</dd>
+ <dt>
+ <b>Supported methods</b>
+ </dt>
+ <dd>{info.methods.map((m) => m.type).join(",")}</dd>
+ <dt>
+ <b>Maximum storage</b>
+ </dt>
+ <dd>{info.storage_limit_in_megabytes} Mb</dd>
+ <dt>
+ <b>Status</b>
+ </dt>
+ <dd>{status}</dd>
+ </dl>
+ </div>
+ <div
+ class="block"
+ style={{
+ marginTop: "auto",
+ marginBottom: "auto",
+ display: "flex",
+ justifyContent: "space-between",
+ flexDirection: "column",
+ }}
+ >
+ <button class="button is-danger" onClick={() => onDelete(url)}>
+ Remove
+ </button>
+ </div>
</div>
- </div>
-} \ No newline at end of file
+ );
+}
diff --git a/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.stories.tsx
index 9cdd132ef..d48e94403 100644
--- a/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.stories.tsx
@@ -15,76 +15,83 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { ReducerState } from 'anastasis-core';
-import { createExample, reducerStatesExample } from '../../utils';
-import { AttributeEntryScreen as TestedComponent } from './AttributeEntryScreen';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { ReducerState } from "anastasis-core";
+import { createExample, reducerStatesExample } from "../../utils";
+import { AttributeEntryScreen as TestedComponent } from "./AttributeEntryScreen";
export default {
- title: 'Pages/PersonalInformation',
+ title: "Pages/PersonalInformation",
component: TestedComponent,
args: {
order: 3,
},
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
export const Backup = createExample(TestedComponent, {
...reducerStatesExample.backupAttributeEditing,
- required_attributes: [{
- name: 'first name',
- label: 'first',
- type: 'string',
- uuid: 'asdasdsa1',
- widget: 'wid',
- }, {
- name: 'last name',
- label: 'second',
- type: 'string',
- uuid: 'asdasdsa2',
- widget: 'wid',
- }, {
- name: 'birthdate',
- label: 'birthdate',
- type: 'date',
- uuid: 'asdasdsa3',
- widget: 'calendar',
- }]
+ required_attributes: [
+ {
+ name: "first name",
+ label: "first",
+ type: "string",
+ uuid: "asdasdsa1",
+ widget: "wid",
+ },
+ {
+ name: "last name",
+ label: "second",
+ type: "string",
+ uuid: "asdasdsa2",
+ widget: "wid",
+ },
+ {
+ name: "birthdate",
+ label: "birthdate",
+ type: "date",
+ uuid: "asdasdsa3",
+ widget: "calendar",
+ },
+ ],
} as ReducerState);
export const Recovery = createExample(TestedComponent, {
...reducerStatesExample.recoveryAttributeEditing,
- required_attributes: [{
- name: 'first',
- label: 'first',
- type: 'string',
- uuid: 'asdasdsa1',
- widget: 'wid',
- }, {
- name: 'pepe',
- label: 'second',
- type: 'string',
- uuid: 'asdasdsa2',
- widget: 'wid',
- }, {
- name: 'pepe2',
- label: 'third',
- type: 'date',
- uuid: 'asdasdsa3',
- widget: 'calendar',
- }]
+ required_attributes: [
+ {
+ name: "first",
+ label: "first",
+ type: "string",
+ uuid: "asdasdsa1",
+ widget: "wid",
+ },
+ {
+ name: "pepe",
+ label: "second",
+ type: "string",
+ uuid: "asdasdsa2",
+ widget: "wid",
+ },
+ {
+ name: "pepe2",
+ label: "third",
+ type: "date",
+ uuid: "asdasdsa3",
+ widget: "calendar",
+ },
+ ],
} as ReducerState);
export const WithNoRequiredAttribute = createExample(TestedComponent, {
...reducerStatesExample.backupAttributeEditing,
- required_attributes: undefined
+ required_attributes: undefined,
} as ReducerState);
const allWidgets = [
@@ -107,23 +114,22 @@ const allWidgets = [
"anastasis_gtk_ia_tax_de",
"anastasis_gtk_xx_prime",
"anastasis_gtk_xx_square",
-]
+];
function typeForWidget(name: string): string {
- if (["anastasis_gtk_xx_prime",
- "anastasis_gtk_xx_square",
- ].includes(name)) return "number";
- if (["anastasis_gtk_ia_birthdate"].includes(name)) return "date"
+ if (["anastasis_gtk_xx_prime", "anastasis_gtk_xx_square"].includes(name))
+ return "number";
+ if (["anastasis_gtk_ia_birthdate"].includes(name)) return "date";
return "string";
}
export const WithAllPosibleWidget = createExample(TestedComponent, {
...reducerStatesExample.backupAttributeEditing,
- required_attributes: allWidgets.map(w => ({
+ required_attributes: allWidgets.map((w) => ({
name: w,
label: `widget: ${w}`,
type: typeForWidget(w),
uuid: `uuid-${w}`,
- widget: w
- }))
+ widget: w,
+ })),
} as ReducerState);
diff --git a/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.tsx b/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.tsx
index 557718458..0918c2db5 100644
--- a/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.tsx
@@ -9,24 +9,32 @@ import { useAnastasisContext } from "../../context/anastasis";
import { AnastasisClientFrame, withProcessLabel } from "./index";
export function AttributeEntryScreen(): VNode {
- const reducer = useAnastasisContext()
- const state = reducer?.currentReducerState
- const currentIdentityAttributes = state && "identity_attributes" in state ? (state.identity_attributes || {}) : {}
- const [attrs, setAttrs] = useState<Record<string, string>>(currentIdentityAttributes);
+ const reducer = useAnastasisContext();
+ const state = reducer?.currentReducerState;
+ const currentIdentityAttributes =
+ state && "identity_attributes" in state
+ ? state.identity_attributes || {}
+ : {};
+ const [attrs, setAttrs] = useState<Record<string, string>>(
+ currentIdentityAttributes,
+ );
if (!reducer) {
- return <div>no reducer in context</div>
+ return <div>no reducer in context</div>;
}
- if (!reducer.currentReducerState || !("required_attributes" in reducer.currentReducerState)) {
- return <div>invalid state</div>
+ if (
+ !reducer.currentReducerState ||
+ !("required_attributes" in reducer.currentReducerState)
+ ) {
+ return <div>invalid state</div>;
}
- const reqAttr = reducer.currentReducerState.required_attributes || []
+ const reqAttr = reducer.currentReducerState.required_attributes || [];
let hasErrors = false;
const fieldList: VNode[] = reqAttr.map((spec, i: number) => {
- const value = attrs[spec.name]
- const error = checkIfValid(value, spec)
- hasErrors = hasErrors || error !== undefined
+ const value = attrs[spec.name];
+ const error = checkIfValid(value, spec);
+ hasErrors = hasErrors || error !== undefined;
return (
<AttributeEntryField
key={i}
@@ -34,23 +42,24 @@ export function AttributeEntryScreen(): VNode {
setValue={(v: string) => setAttrs({ ...attrs, [spec.name]: v })}
spec={spec}
errorMessage={error}
- value={value} />
+ value={value}
+ />
);
- })
+ });
return (
<AnastasisClientFrame
title={withProcessLabel(reducer, "Who are you?")}
hideNext={hasErrors ? "Complete the form." : undefined}
- onNext={() => reducer.transition("enter_user_attributes", {
- identity_attributes: attrs,
- })}
+ onNext={() =>
+ reducer.transition("enter_user_attributes", {
+ identity_attributes: attrs,
+ })
+ }
>
- <div class="columns" style={{ maxWidth: 'unset' }}>
+ <div class="columns" style={{ maxWidth: "unset" }}>
+ <div class="column">{fieldList}</div>
<div class="column">
- {fieldList}
- </div>
- <div class="column" >
<p>This personal information will help to locate your secret.</p>
<h1 class="title">This stays private</h1>
<p>The information you have entered here:</p>
@@ -61,9 +70,12 @@ export function AttributeEntryScreen(): VNode {
</span>
Will be hashed, and therefore unreadable
</li>
- <li><span class="icon is-right">
- <i class="mdi mdi-circle-small" />
- </span>The non-hashed version is not shared</li>
+ <li>
+ <span class="icon is-right">
+ <i class="mdi mdi-circle-small" />
+ </span>
+ The non-hashed version is not shared
+ </li>
</ul>
</div>
</div>
@@ -78,22 +90,22 @@ interface AttributeEntryFieldProps {
spec: UserAttributeSpec;
errorMessage: string | undefined;
}
-const possibleBirthdayYear: Array<number> = []
+const possibleBirthdayYear: Array<number> = [];
for (let i = 0; i < 100; i++) {
- possibleBirthdayYear.push(2020 - i)
+ possibleBirthdayYear.push(2020 - i);
}
function AttributeEntryField(props: AttributeEntryFieldProps): VNode {
-
return (
<div>
- {props.spec.type === 'date' &&
+ {props.spec.type === "date" &&
<DateInput
grabFocus={props.isFirst}
label={props.spec.label}
years={possibleBirthdayYear}
error={props.errorMessage}
bind={[props.value, props.setValue]}
- />}
+ />
+ }
{props.spec.type === 'number' &&
<PhoneNumberInput
grabFocus={props.isFirst}
@@ -102,14 +114,14 @@ function AttributeEntryField(props: AttributeEntryFieldProps): VNode {
bind={[props.value, props.setValue]}
/>
}
- {props.spec.type === 'string' &&
+ {props.spec.type === "string" && (
<TextInput
grabFocus={props.isFirst}
label={props.spec.label}
error={props.errorMessage}
bind={[props.value, props.setValue]}
/>
- }
+ )}
<div class="block">
This stays private
<span class="icon is-right">
@@ -119,40 +131,43 @@ function AttributeEntryField(props: AttributeEntryFieldProps): VNode {
</div>
);
}
-const YEAR_REGEX = /^[0-9]+-[0-9]+-[0-9]+$/
-
+const YEAR_REGEX = /^[0-9]+-[0-9]+-[0-9]+$/;
-function checkIfValid(value: string, spec: UserAttributeSpec): string | undefined {
- const pattern = spec['validation-regex']
+function checkIfValid(
+ value: string,
+ spec: UserAttributeSpec,
+): string | undefined {
+ const pattern = spec["validation-regex"];
if (pattern) {
- const re = new RegExp(pattern)
- if (!re.test(value)) return 'The value is invalid'
+ const re = new RegExp(pattern);
+ if (!re.test(value)) return "The value is invalid";
}
- const logic = spec['validation-logic']
+ const logic = spec["validation-logic"];
if (logic) {
const func = (validators as any)[logic];
- if (func && typeof func === 'function' && !func(value)) return 'Please check the value'
+ if (func && typeof func === "function" && !func(value))
+ return "Please check the value";
}
- const optional = spec.optional
+ const optional = spec.optional;
if (!optional && !value) {
- return 'This value is required'
+ return "This value is required";
}
if ("date" === spec.type) {
if (!YEAR_REGEX.test(value)) {
- return "The date doesn't follow the format"
+ return "The date doesn't follow the format";
}
try {
- const v = parse(value, 'yyyy-MM-dd', new Date());
+ const v = parse(value, "yyyy-MM-dd", new Date());
if (Number.isNaN(v.getTime())) {
- return "Some numeric values seems out of range for a date"
+ return "Some numeric values seems out of range for a date";
}
if ("birthdate" === spec.name && isAfter(v, new Date())) {
- return "A birthdate cannot be in the future"
+ return "A birthdate cannot be in the future";
}
} catch (e) {
- return "Could not parse the date"
+ return "Could not parse the date";
}
}
- return undefined
+ return undefined;
}
diff --git a/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.stories.tsx
index 2712522ce..8acf1c8c8 100644
--- a/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.stories.tsx
@@ -15,73 +15,84 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { ReducerState } from 'anastasis-core';
-import { createExample, reducerStatesExample } from '../../utils';
-import { AuthenticationEditorScreen as TestedComponent } from './AuthenticationEditorScreen';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { ReducerState } from "anastasis-core";
+import { createExample, reducerStatesExample } from "../../utils";
+import { AuthenticationEditorScreen as TestedComponent } from "./AuthenticationEditorScreen";
export default {
- title: 'Pages/backup/AuthorizationMethod',
+ title: "Pages/backup/AuthorizationMethod",
component: TestedComponent,
args: {
order: 4,
},
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
-export const InitialState = createExample(TestedComponent, reducerStatesExample.authEditing);
+export const InitialState = createExample(
+ TestedComponent,
+ reducerStatesExample.authEditing,
+);
export const OneAuthMethodConfigured = createExample(TestedComponent, {
...reducerStatesExample.authEditing,
- authentication_methods: [{
- type: 'question',
- instructions: 'what time is it?',
- challenge: 'asd',
- }]
+ authentication_methods: [
+ {
+ type: "question",
+ instructions: "what time is it?",
+ challenge: "asd",
+ },
+ ],
} as ReducerState);
-
export const SomeMoreAuthMethodConfigured = createExample(TestedComponent, {
...reducerStatesExample.authEditing,
- authentication_methods: [{
- type: 'question',
- instructions: 'what time is it?',
- challenge: 'asd',
- },{
- type: 'question',
- instructions: 'what time is it?',
- challenge: 'qwe',
- },{
- type: 'sms',
- instructions: 'what time is it?',
- challenge: 'asd',
- },{
- type: 'email',
- instructions: 'what time is it?',
- challenge: 'asd',
- },{
- type: 'email',
- instructions: 'what time is it?',
- challenge: 'asd',
- },{
- type: 'email',
- instructions: 'what time is it?',
- challenge: 'asd',
- },{
- type: 'email',
- instructions: 'what time is it?',
- challenge: 'asd',
- }]
+ authentication_methods: [
+ {
+ type: "question",
+ instructions: "what time is it?",
+ challenge: "asd",
+ },
+ {
+ type: "question",
+ instructions: "what time is it?",
+ challenge: "qwe",
+ },
+ {
+ type: "sms",
+ instructions: "what time is it?",
+ challenge: "asd",
+ },
+ {
+ type: "email",
+ instructions: "what time is it?",
+ challenge: "asd",
+ },
+ {
+ type: "email",
+ instructions: "what time is it?",
+ challenge: "asd",
+ },
+ {
+ type: "email",
+ instructions: "what time is it?",
+ challenge: "asd",
+ },
+ {
+ type: "email",
+ instructions: "what time is it?",
+ challenge: "asd",
+ },
+ ],
} as ReducerState);
export const NoAuthMethodProvided = createExample(TestedComponent, {
...reducerStatesExample.authEditing,
authentication_providers: {},
- authentication_methods: []
+ authentication_methods: [],
} as ReducerState);
diff --git a/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx b/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx
index 00eb54d4d..1ef326773 100644
--- a/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx
@@ -20,7 +20,9 @@ export function AuthenticationEditorScreen(): VNode {
KnownAuthMethods | undefined
>(undefined);
const [tooFewAuths, setTooFewAuths] = useState(false);
- const [manageProvider, setManageProvider] = useState<string | undefined>(undefined)
+ const [manageProvider, setManageProvider] = useState<string | undefined>(
+ undefined,
+ );
// const [addingProvider, setAddingProvider] = useState<string | undefined>(undefined)
const reducer = useAnastasisContext();
@@ -68,11 +70,14 @@ export function AuthenticationEditorScreen(): VNode {
}
if (manageProvider !== undefined) {
-
- return <AddingProviderScreen
- onCancel={() => setManageProvider(undefined)}
- providerType={isKnownAuthMethods(manageProvider) ? manageProvider : undefined}
- />
+ return (
+ <AddingProviderScreen
+ onCancel={() => setManageProvider(undefined)}
+ providerType={
+ isKnownAuthMethods(manageProvider) ? manageProvider : undefined
+ }
+ />
+ );
}
if (selectedMethod) {
@@ -100,7 +105,7 @@ export function AuthenticationEditorScreen(): VNode {
description="No providers founds"
label="Add a provider manually"
onConfirm={() => {
- setManageProvider(selectedMethod)
+ setManageProvider(selectedMethod);
}}
>
<p>
@@ -193,7 +198,7 @@ export function AuthenticationEditorScreen(): VNode {
description="No providers founds"
label="Add a provider manually"
onConfirm={() => {
- setManageProvider("")
+ setManageProvider("");
}}
>
<p>
@@ -214,7 +219,10 @@ export function AuthenticationEditorScreen(): VNode {
authentication method is defined by the backup provider list.
</p>
<p class="block">
- <button class="button is-info" onClick={() => setManageProvider("")}>
+ <button
+ class="button is-info"
+ onClick={() => setManageProvider("")}
+ >
Manage backup providers
</button>
</p>
diff --git a/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.stories.tsx
index 306adacbb..0789ee6ad 100644
--- a/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.stories.tsx
@@ -15,48 +15,51 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { ReducerState } from 'anastasis-core';
-import { createExample, reducerStatesExample } from '../../utils';
-import { BackupFinishedScreen as TestedComponent } from './BackupFinishedScreen';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { ReducerState } from "anastasis-core";
+import { createExample, reducerStatesExample } from "../../utils";
+import { BackupFinishedScreen as TestedComponent } from "./BackupFinishedScreen";
export default {
- title: 'Pages/backup/Finished',
+ title: "Pages/backup/Finished",
component: TestedComponent,
args: {
order: 8,
},
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
-export const WithoutName = createExample(TestedComponent, reducerStatesExample.backupFinished);
+export const WithoutName = createExample(
+ TestedComponent,
+ reducerStatesExample.backupFinished,
+);
-export const WithName = createExample(TestedComponent, {...reducerStatesExample.backupFinished,
- secret_name: 'super_secret',
+export const WithName = createExample(TestedComponent, {
+ ...reducerStatesExample.backupFinished,
+ secret_name: "super_secret",
} as ReducerState);
export const WithDetails = createExample(TestedComponent, {
...reducerStatesExample.backupFinished,
- secret_name: 'super_secret',
+ secret_name: "super_secret",
success_details: {
- 'http://anastasis.net': {
+ "http://anastasis.net": {
policy_expiration: {
- t_ms: 'never'
+ t_ms: "never",
},
- policy_version: 0
+ policy_version: 0,
},
- 'http://taler.net': {
+ "http://taler.net": {
policy_expiration: {
- t_ms: new Date().getTime() + 60*60*24*1000
+ t_ms: new Date().getTime() + 60 * 60 * 24 * 1000,
},
- policy_version: 1
+ policy_version: 1,
},
- }
+ },
} as ReducerState);
diff --git a/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.tsx b/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.tsx
index 7938baca4..825ec5dc0 100644
--- a/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.tsx
@@ -4,41 +4,62 @@ import { useAnastasisContext } from "../../context/anastasis";
import { AnastasisClientFrame } from "./index";
export function BackupFinishedScreen(): VNode {
- const reducer = useAnastasisContext()
+ const reducer = useAnastasisContext();
if (!reducer) {
- return <div>no reducer in context</div>
+ return <div>no reducer in context</div>;
}
- if (!reducer.currentReducerState || reducer.currentReducerState.backup_state === undefined) {
- return <div>invalid state</div>
+ if (
+ !reducer.currentReducerState ||
+ reducer.currentReducerState.backup_state === undefined
+ ) {
+ return <div>invalid state</div>;
}
- const details = reducer.currentReducerState.success_details
+ const details = reducer.currentReducerState.success_details;
- return (<AnastasisClientFrame hideNav title="Backup finished">
- {reducer.currentReducerState.secret_name ? <p>
- Your backup of secret <b>"{reducer.currentReducerState.secret_name}"</b> was
- successful.
- </p> :
- <p>
- Your secret was successfully backed up.
- </p>}
+ return (
+ <AnastasisClientFrame hideNav title="Backup finished">
+ {reducer.currentReducerState.secret_name ? (
+ <p>
+ Your backup of secret{" "}
+ <b>"{reducer.currentReducerState.secret_name}"</b> was successful.
+ </p>
+ ) : (
+ <p>Your secret was successfully backed up.</p>
+ )}
- {details && <div class="block">
- <p>The backup is stored by the following providers:</p>
- {Object.keys(details).map((x, i) => {
- const sd = details[x];
- return (
- <div key={i} class="box">
- {x}
- <p>
- version {sd.policy_version}
- {sd.policy_expiration.t_ms !== 'never' ? ` expires at: ${format(sd.policy_expiration.t_ms, 'dd-MM-yyyy')}` : ' without expiration date'}
- </p>
- </div>
- );
- })}
- </div>}
- <div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
- <button class="button" onClick={() => reducer.back()}>Back</button>
- </div>
- </AnastasisClientFrame>);
+ {details && (
+ <div class="block">
+ <p>The backup is stored by the following providers:</p>
+ {Object.keys(details).map((x, i) => {
+ const sd = details[x];
+ return (
+ <div key={i} class="box">
+ {x}
+ <p>
+ version {sd.policy_version}
+ {sd.policy_expiration.t_ms !== "never"
+ ? ` expires at: ${format(
+ sd.policy_expiration.t_ms,
+ "dd-MM-yyyy",
+ )}`
+ : " without expiration date"}
+ </p>
+ </div>
+ );
+ })}
+ </div>
+ )}
+ <div
+ style={{
+ marginTop: "2em",
+ display: "flex",
+ justifyContent: "space-between",
+ }}
+ >
+ <button class="button" onClick={() => reducer.back()}>
+ Back
+ </button>
+ </div>
+ </AnastasisClientFrame>
+ );
}
diff --git a/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.stories.tsx
index 46c574cf2..56aee8763 100644
--- a/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.stories.tsx
@@ -19,7 +19,11 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { ChallengeFeedbackStatus, RecoveryStates, ReducerState } from "anastasis-core";
+import {
+ ChallengeFeedbackStatus,
+ RecoveryStates,
+ ReducerState,
+} from "anastasis-core";
import { createExample, reducerStatesExample } from "../../utils";
import { ChallengeOverviewScreen as TestedComponent } from "./ChallengeOverviewScreen";
@@ -247,20 +251,20 @@ export const OnePolicyWithAllTheChallengesInDifferentState = createExample(
"uuid-1": { state: ChallengeFeedbackStatus.Solved.toString() },
"uuid-2": {
state: ChallengeFeedbackStatus.Message.toString(),
- message: 'Challenge should be solved'
+ message: "Challenge should be solved",
},
"uuid-3": {
state: ChallengeFeedbackStatus.AuthIban.toString(),
challenge_amount: "EUR:1",
credit_iban: "DE12345789000",
business_name: "Data Loss Incorporated",
- wire_transfer_subject: "Anastasis 987654321"
+ wire_transfer_subject: "Anastasis 987654321",
},
"uuid-4": {
state: ChallengeFeedbackStatus.Payment.toString(),
taler_pay_uri: "taler://pay/...",
provider: "https://localhost:8080/",
- payment_secret: "3P4561HAMHRRYEYD6CM6J7TS5VTD5SR2K2EXJDZEFSX92XKHR4KG"
+ payment_secret: "3P4561HAMHRRYEYD6CM6J7TS5VTD5SR2K2EXJDZEFSX92XKHR4KG",
},
"uuid-5": {
state: ChallengeFeedbackStatus.RateLimitExceeded.toString(),
@@ -269,7 +273,7 @@ export const OnePolicyWithAllTheChallengesInDifferentState = createExample(
"uuid-6": {
state: ChallengeFeedbackStatus.Redirect.toString(),
redirect_url: "https://videoconf.example.com/",
- http_status: 303
+ http_status: 303,
},
"uuid-7": {
state: ChallengeFeedbackStatus.ServerFailure.toString(),
diff --git a/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.tsx b/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.tsx
index ae03dd4d4..c6de00e98 100644
--- a/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.tsx
@@ -11,23 +11,34 @@ function OverviewFeedbackDisplay(props: { feedback?: ChallengeFeedback }) {
}
switch (feedback.state) {
case ChallengeFeedbackStatus.Message:
- return (
- <div class="block has-text-danger">{feedback.message}</div>
- );
+ return <div class="block has-text-danger">{feedback.message}</div>;
case ChallengeFeedbackStatus.Solved:
- return <div />
+ return <div />;
case ChallengeFeedbackStatus.Pending:
- case ChallengeFeedbackStatus.Solved:
case ChallengeFeedbackStatus.AuthIban:
return null;
case ChallengeFeedbackStatus.ServerFailure:
return <div class="block has-text-danger">Server error.</div>;
case ChallengeFeedbackStatus.RateLimitExceeded:
- return <div class="block has-text-danger">There were to many failed attempts.</div>;
+ return (
+ <div class="block has-text-danger">
+ There were to many failed attempts.
+ </div>
+ );
case ChallengeFeedbackStatus.Unsupported:
- return <div class="block has-text-danger">This client doesn't support solving this type of challenge. Use another version or contact the provider.</div>;
+ return (
+ <div class="block has-text-danger">
+ This client doesn't support solving this type of challenge. Use
+ another version or contact the provider.
+ </div>
+ );
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.</div>;
+ return (
+ <div class="block has-text-danger">
+ Provider doesn't recognize the challenge of the policy. Contact the
+ provider for further information.
+ </div>
+ );
case ChallengeFeedbackStatus.Redirect:
default:
return <div />;
@@ -70,19 +81,25 @@ export function ChallengeOverviewScreen(): VNode {
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);
+ 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 };
- });
+ return {
+ isPolicySolved,
+ challenges,
+ corrupted: row.length > challenges.length,
+ };
+ })
+ .filter((p) => !p.corrupted);
const atLeastThereIsOnePolicySolved =
policiesWithInfo.find((p) => p.isPolicySolved) !== undefined;
@@ -92,19 +109,19 @@ export function ChallengeOverviewScreen(): VNode {
: undefined;
return (
<AnastasisClientFrame hideNext={errors} title="Recovery: Solve challenges">
- {!policies.length ? (
+ {!policiesWithInfo.length ? (
<p class="block">
No policies found, try with another version of the secret
</p>
- ) : policies.length === 1 ? (
+ ) : policiesWithInfo.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 class="block">
- We have found {policies.length} polices. You need to solve all the
- challenges from one policy in order to recover your secret.
+ We have found {policiesWithInfo.length} polices. You need to solve all
+ the challenges from one policy in order to recover your secret.
</p>
)}
{policiesWithInfo.map((policy, policy_index) => {
@@ -113,74 +130,100 @@ export function ChallengeOverviewScreen(): VNode {
const method = authMethods[info.type as KnownAuthMethods];
if (!method) {
- return <div
- key={uuid}
- class="block"
- style={{ display: "flex", justifyContent: "space-between" }}
- >
- <div style={{ display: "flex", alignItems: "center" }}>
- <span>unknown challenge</span>
+ return (
+ <div
+ key={uuid}
+ class="block"
+ style={{ display: "flex", justifyContent: "space-between" }}
+ >
+ <div style={{ display: "flex", alignItems: "center" }}>
+ <span>unknown challenge</span>
+ </div>
</div>
-
- </div>
+ );
}
- function ChallengeButton({ id, feedback }: { id: string; feedback?: ChallengeFeedback }): VNode {
+ function ChallengeButton({
+ id,
+ feedback,
+ }: {
+ id: string;
+ feedback?: ChallengeFeedback;
+ }): VNode {
function selectChallenge(): void {
- if (reducer) reducer.transition("select_challenge", { uuid: id })
+ if (reducer) reducer.transition("select_challenge", { uuid: id });
}
if (!feedback) {
- return <div>
- <button class="button" onClick={selectChallenge}>
- Solve
- </button>
- </div>
+ return (
+ <div>
+ <button
+ class="button"
+ disabled={
+ atLeastThereIsOnePolicySolved && !policy.isPolicySolved
+ }
+ onClick={selectChallenge}
+ >
+ Solve
+ </button>
+ </div>
+ );
}
switch (feedback.state) {
case ChallengeFeedbackStatus.ServerFailure:
case ChallengeFeedbackStatus.Unsupported:
case ChallengeFeedbackStatus.TruthUnknown:
- case ChallengeFeedbackStatus.RateLimitExceeded: return <div />
+ case ChallengeFeedbackStatus.RateLimitExceeded:
+ return <div />;
case ChallengeFeedbackStatus.AuthIban:
- case ChallengeFeedbackStatus.Payment: return <div>
- <button class="button" onClick={selectChallenge}>
- Pay
- </button>
- </div>
- case ChallengeFeedbackStatus.Redirect: return <div>
- <button class="button" onClick={selectChallenge}>
- Go to {feedback.redirect_url}
- </button>
- </div>
- case ChallengeFeedbackStatus.Solved: return <div>
- <div class="tag is-success is-large">
- Solved
- </div>
- </div>
- default: return <div>
- <button class="button" onClick={selectChallenge}>
- Solve
- </button>
- </div>
-
+ case ChallengeFeedbackStatus.Payment:
+ return (
+ <div>
+ <button
+ class="button"
+ disabled={
+ atLeastThereIsOnePolicySolved && !policy.isPolicySolved
+ }
+ onClick={selectChallenge}
+ >
+ Pay
+ </button>
+ </div>
+ );
+ case ChallengeFeedbackStatus.Redirect:
+ return (
+ <div>
+ <button
+ class="button"
+ disabled={
+ atLeastThereIsOnePolicySolved && !policy.isPolicySolved
+ }
+ onClick={selectChallenge}
+ >
+ Go to {feedback.redirect_url}
+ </button>
+ </div>
+ );
+ case ChallengeFeedbackStatus.Solved:
+ return (
+ <div>
+ <div class="tag is-success is-large">Solved</div>
+ </div>
+ );
+ default:
+ return (
+ <div>
+ <button
+ class="button"
+ disabled={
+ atLeastThereIsOnePolicySolved && !policy.isPolicySolved
+ }
+ onClick={selectChallenge}
+ >
+ Solve
+ </button>
+ </div>
+ );
}
- // return <div>
- // {feedback.state !== "solved" ? (
- // <a
- // class="button"
- // onClick={() =>
-
- // }
- // >
- // {isFree ? "Solve" : `Pay and Solve`}
- // </a>
- // ) : null}
- // {feedback.state === "solved" ? (
- // // <div class="block is-success" > Solved </div>
- // <div class="tag is-success is-large">Solved</div>
-
- // ) : null}
- // </div>
}
return (
<div
@@ -202,7 +245,6 @@ export function ChallengeOverviewScreen(): VNode {
</div>
<ChallengeButton id={uuid} feedback={info.feedback} />
-
</div>
);
});
@@ -210,11 +252,13 @@ export function ChallengeOverviewScreen(): VNode {
const policyName = policy.challenges
.map((x) => x.info.type)
.join(" + ");
+
const opa = !atLeastThereIsOnePolicySolved
? undefined
: policy.isPolicySolved
- ? undefined
- : "0.6";
+ ? undefined
+ : "0.6";
+
return (
<div
key={policy_index}
diff --git a/packages/anastasis-webui/src/pages/home/ChallengePayingScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/ChallengePayingScreen.stories.tsx
index fbcaa0e95..8c788e556 100644
--- a/packages/anastasis-webui/src/pages/home/ChallengePayingScreen.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/ChallengePayingScreen.stories.tsx
@@ -15,24 +15,26 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { createExample, reducerStatesExample } from '../../utils';
-import { ChallengePayingScreen as TestedComponent } from './ChallengePayingScreen';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { createExample, reducerStatesExample } from "../../utils";
+import { ChallengePayingScreen as TestedComponent } from "./ChallengePayingScreen";
export default {
- title: 'Pages/recovery/__ChallengePaying',
+ title: "Pages/recovery/__ChallengePaying",
component: TestedComponent,
args: {
order: 10,
},
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
-export const Example = createExample(TestedComponent, reducerStatesExample.challengePaying);
+export const Example = createExample(
+ TestedComponent,
+ reducerStatesExample.challengePaying,
+);
diff --git a/packages/anastasis-webui/src/pages/home/ChallengePayingScreen.tsx b/packages/anastasis-webui/src/pages/home/ChallengePayingScreen.tsx
index 84896a2ec..ffcc8fafc 100644
--- a/packages/anastasis-webui/src/pages/home/ChallengePayingScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/ChallengePayingScreen.tsx
@@ -3,19 +3,19 @@ import { useAnastasisContext } from "../../context/anastasis";
import { AnastasisClientFrame } from "./index";
export function ChallengePayingScreen(): VNode {
- const reducer = useAnastasisContext()
+ const reducer = useAnastasisContext();
if (!reducer) {
- return <div>no reducer in context</div>
+ return <div>no reducer in context</div>;
}
- if (!reducer.currentReducerState || reducer.currentReducerState.recovery_state === undefined) {
- return <div>invalid state</div>
+ if (
+ !reducer.currentReducerState ||
+ reducer.currentReducerState.recovery_state === undefined
+ ) {
+ return <div>invalid state</div>;
}
- const payments = ['']; //reducer.currentReducerState.payments ??
+ const payments = [""]; //reducer.currentReducerState.payments ??
return (
- <AnastasisClientFrame
- hideNav
- title="Recovery: Challenge Paying"
- >
+ <AnastasisClientFrame hideNav title="Recovery: Challenge Paying">
<p>
Some of the providers require a payment to store the encrypted
authentication information.
diff --git a/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.stories.tsx
index 6bdb3515d..0948d603e 100644
--- a/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.stories.tsx
@@ -16,37 +16,42 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { ReducerState } from 'anastasis-core';
-import { createExample, reducerStatesExample } from '../../utils';
-import { ContinentSelectionScreen as TestedComponent } from './ContinentSelectionScreen';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { ReducerState } from "anastasis-core";
+import { createExample, reducerStatesExample } from "../../utils";
+import { ContinentSelectionScreen as TestedComponent } from "./ContinentSelectionScreen";
export default {
- title: 'Pages/Location',
+ title: "Pages/Location",
component: TestedComponent,
args: {
order: 2,
},
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
-export const BackupSelectContinent = createExample(TestedComponent, reducerStatesExample.backupSelectContinent);
+export const BackupSelectContinent = createExample(
+ TestedComponent,
+ reducerStatesExample.backupSelectContinent,
+);
export const BackupSelectCountry = createExample(TestedComponent, {
...reducerStatesExample.backupSelectContinent,
- selected_continent: 'Testcontinent',
+ selected_continent: "Testcontinent",
} as ReducerState);
-export const RecoverySelectContinent = createExample(TestedComponent, reducerStatesExample.recoverySelectContinent);
+export const RecoverySelectContinent = createExample(
+ TestedComponent,
+ reducerStatesExample.recoverySelectContinent,
+);
export const RecoverySelectCountry = createExample(TestedComponent, {
...reducerStatesExample.recoverySelectContinent,
- selected_continent: 'Testcontinent',
+ selected_continent: "Testcontinent",
} as ReducerState);
diff --git a/packages/anastasis-webui/src/pages/home/EditPoliciesScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/EditPoliciesScreen.stories.tsx
index 3d5fcce55..4cbeb8308 100644
--- a/packages/anastasis-webui/src/pages/home/EditPoliciesScreen.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/EditPoliciesScreen.stories.tsx
@@ -16,94 +16,126 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { ReducerState } from 'anastasis-core';
-import { createExample, reducerStatesExample } from '../../utils';
-import { EditPoliciesScreen as TestedComponent } from './EditPoliciesScreen';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { ReducerState } from "anastasis-core";
+import { createExample, reducerStatesExample } from "../../utils";
+import { EditPoliciesScreen as TestedComponent } from "./EditPoliciesScreen";
export default {
- title: 'Pages/backup/ReviewPolicies/EditPolicies',
+ title: "Pages/backup/ReviewPolicies/EditPolicies",
args: {
order: 6,
},
component: TestedComponent,
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
-export const EditingAPolicy = createExample(TestedComponent, {
- ...reducerStatesExample.policyReview,
- policies: [{
- methods: [{
- authentication_method: 1,
- provider: 'https://anastasis.demo.taler.net/'
- }, {
- authentication_method: 2,
- provider: 'http://localhost:8086/'
- }]
- }, {
- methods: [{
- authentication_method: 1,
- provider: 'http://localhost:8086/'
- }]
- }],
- authentication_methods: [{
- type: "email",
- instructions: "Email to qwe@asd.com",
- challenge: "E5VPA"
- }, {
- type: "totp",
- instructions: "Response code for 'Anastasis'",
- challenge: "E5VPA"
- }, {
- type: "sms",
- instructions: "SMS to 6666-6666",
- challenge: ""
- }, {
- type: "question",
- instructions: "How did the chicken cross the road?",
- challenge: "C5SP8"
- }]
-} as ReducerState, { index : 0});
-
-export const CreatingAPolicy = createExample(TestedComponent, {
- ...reducerStatesExample.policyReview,
- policies: [{
- methods: [{
- authentication_method: 1,
- provider: 'https://anastasis.demo.taler.net/'
- }, {
- authentication_method: 2,
- provider: 'http://localhost:8086/'
- }]
- }, {
- methods: [{
- authentication_method: 1,
- provider: 'http://localhost:8086/'
- }]
- }],
- authentication_methods: [{
- type: "email",
- instructions: "Email to qwe@asd.com",
- challenge: "E5VPA"
- }, {
- type: "totp",
- instructions: "Response code for 'Anastasis'",
- challenge: "E5VPA"
- }, {
- type: "sms",
- instructions: "SMS to 6666-6666",
- challenge: ""
- }, {
- type: "question",
- instructions: "How did the chicken cross the road?",
- challenge: "C5SP8"
- }]
-} as ReducerState, { index : 3});
+export const EditingAPolicy = createExample(
+ TestedComponent,
+ {
+ ...reducerStatesExample.policyReview,
+ policies: [
+ {
+ methods: [
+ {
+ authentication_method: 1,
+ provider: "https://anastasis.demo.taler.net/",
+ },
+ {
+ authentication_method: 2,
+ provider: "http://localhost:8086/",
+ },
+ ],
+ },
+ {
+ methods: [
+ {
+ authentication_method: 1,
+ provider: "http://localhost:8086/",
+ },
+ ],
+ },
+ ],
+ authentication_methods: [
+ {
+ type: "email",
+ instructions: "Email to qwe@asd.com",
+ challenge: "E5VPA",
+ },
+ {
+ type: "totp",
+ instructions: "Response code for 'Anastasis'",
+ challenge: "E5VPA",
+ },
+ {
+ type: "sms",
+ instructions: "SMS to 6666-6666",
+ challenge: "",
+ },
+ {
+ type: "question",
+ instructions: "How did the chicken cross the road?",
+ challenge: "C5SP8",
+ },
+ ],
+ } as ReducerState,
+ { index: 0 },
+);
+export const CreatingAPolicy = createExample(
+ TestedComponent,
+ {
+ ...reducerStatesExample.policyReview,
+ policies: [
+ {
+ methods: [
+ {
+ authentication_method: 1,
+ provider: "https://anastasis.demo.taler.net/",
+ },
+ {
+ authentication_method: 2,
+ provider: "http://localhost:8086/",
+ },
+ ],
+ },
+ {
+ methods: [
+ {
+ authentication_method: 1,
+ provider: "http://localhost:8086/",
+ },
+ ],
+ },
+ ],
+ authentication_methods: [
+ {
+ type: "email",
+ instructions: "Email to qwe@asd.com",
+ challenge: "E5VPA",
+ },
+ {
+ type: "totp",
+ instructions: "Response code for 'Anastasis'",
+ challenge: "E5VPA",
+ },
+ {
+ type: "sms",
+ instructions: "SMS to 6666-6666",
+ challenge: "",
+ },
+ {
+ type: "question",
+ instructions: "How did the chicken cross the road?",
+ challenge: "C5SP8",
+ },
+ ],
+ } as ReducerState,
+ { index: 3 },
+);
diff --git a/packages/anastasis-webui/src/pages/home/EditPoliciesScreen.tsx b/packages/anastasis-webui/src/pages/home/EditPoliciesScreen.tsx
index 85cc96c46..198209399 100644
--- a/packages/anastasis-webui/src/pages/home/EditPoliciesScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/EditPoliciesScreen.tsx
@@ -20,7 +20,6 @@ interface Props {
index: number;
cancel: () => void;
confirm: (changes: MethodProvider[]) => void;
-
}
export interface MethodProvider {
@@ -28,106 +27,151 @@ export interface MethodProvider {
provider: string;
}
-export function EditPoliciesScreen({ index: policy_index, cancel, confirm }: Props): VNode {
- const [changedProvider, setChangedProvider] = useState<Array<string>>([])
+export function EditPoliciesScreen({
+ index: policy_index,
+ cancel,
+ confirm,
+}: Props): VNode {
+ const [changedProvider, setChangedProvider] = useState<Array<string>>([]);
- const reducer = useAnastasisContext()
+ const reducer = useAnastasisContext();
if (!reducer) {
- return <div>no reducer in context</div>
+ return <div>no reducer in context</div>;
}
- if (!reducer.currentReducerState || reducer.currentReducerState.backup_state === undefined) {
- return <div>invalid state</div>
+ if (
+ !reducer.currentReducerState ||
+ reducer.currentReducerState.backup_state === undefined
+ ) {
+ return <div>invalid state</div>;
}
- const selectableProviders: ProviderInfoByType = {}
- const allProviders = Object.entries(reducer.currentReducerState.authentication_providers || {})
+ const selectableProviders: ProviderInfoByType = {};
+ const allProviders = Object.entries(
+ reducer.currentReducerState.authentication_providers || {},
+ );
for (let index = 0; index < allProviders.length; index++) {
- const [url, status] = allProviders[index]
+ const [url, status] = allProviders[index];
if ("methods" in status) {
- status.methods.map(m => {
- const type: KnownAuthMethods = m.type as KnownAuthMethods
- const values = selectableProviders[type] || []
- const isFree = !m.usage_fee || m.usage_fee.endsWith(":0")
- values.push({ url, cost: m.usage_fee, isFree })
- selectableProviders[type] = values
- })
+ status.methods.map((m) => {
+ const type: KnownAuthMethods = m.type as KnownAuthMethods;
+ const values = selectableProviders[type] || [];
+ const isFree = !m.usage_fee || m.usage_fee.endsWith(":0");
+ values.push({ url, cost: m.usage_fee, isFree });
+ selectableProviders[type] = values;
+ });
}
}
- const allAuthMethods = reducer.currentReducerState.authentication_methods ?? [];
+ const allAuthMethods =
+ reducer.currentReducerState.authentication_methods ?? [];
const policies = reducer.currentReducerState.policies ?? [];
- const policy = policies[policy_index]
-
- for(let method_index = 0; method_index < allAuthMethods.length; method_index++ ) {
- policy?.methods.find(m => m.authentication_method === method_index)?.provider
+ const policy = policies[policy_index];
+
+ for (
+ let method_index = 0;
+ method_index < allAuthMethods.length;
+ method_index++
+ ) {
+ policy?.methods.find((m) => m.authentication_method === method_index)
+ ?.provider;
}
function sendChanges(): void {
- const newMethods: MethodProvider[] = []
+ const newMethods: MethodProvider[] = [];
allAuthMethods.forEach((method, index) => {
- const oldValue = policy?.methods.find(m => m.authentication_method === index)
+ const oldValue = policy?.methods.find(
+ (m) => m.authentication_method === index,
+ );
if (changedProvider[index] === undefined && oldValue !== undefined) {
- newMethods.push(oldValue)
+ newMethods.push(oldValue);
}
- if (changedProvider[index] !== undefined && changedProvider[index] !== "") {
+ if (
+ changedProvider[index] !== undefined &&
+ changedProvider[index] !== ""
+ ) {
newMethods.push({
authentication_method: index,
- provider: changedProvider[index]
- })
+ provider: changedProvider[index],
+ });
}
- })
- confirm(newMethods)
+ });
+ confirm(newMethods);
}
- return <AnastasisClientFrame hideNav title={!policy ? "Backup: New Policy" : "Backup: Edit Policy"}>
- <section class="section">
- {!policy ? <p>
- Creating a new policy #{policy_index}
- </p> : <p>
- Editing policy #{policy_index}
- </p>}
- {allAuthMethods.map((method, index) => {
- //take the url from the updated change or from the policy
- const providerURL = changedProvider[index] === undefined ?
- policy?.methods.find(m => m.authentication_method === index)?.provider :
- changedProvider[index];
+ return (
+ <AnastasisClientFrame
+ hideNav
+ title={!policy ? "Backup: New Policy" : "Backup: Edit Policy"}
+ >
+ <section class="section">
+ {!policy ? (
+ <p>Creating a new policy #{policy_index}</p>
+ ) : (
+ <p>Editing policy #{policy_index}</p>
+ )}
+ {allAuthMethods.map((method, index) => {
+ //take the url from the updated change or from the policy
+ const providerURL =
+ changedProvider[index] === undefined
+ ? policy?.methods.find((m) => m.authentication_method === index)
+ ?.provider
+ : changedProvider[index];
- const type: KnownAuthMethods = method.type as KnownAuthMethods
- function changeProviderTo(url: string): void {
- const copy = [...changedProvider]
- copy[index] = url
- setChangedProvider(copy)
- }
- return (
- <div key={index} class="block" style={{ display: 'flex', alignItems: 'center' }}>
- <span class="icon">
- {authMethods[type]?.icon}
- </span>
- <span>
- {method.instructions}
- </span>
- <span>
- <span class="select " >
- <select onChange={(e) => changeProviderTo(e.currentTarget.value)} value={providerURL ?? ""}>
- <option key="none" value=""> &lt;&lt; off &gt;&gt; </option>
- {selectableProviders[type]?.map(prov => (
- <option key={prov.url} value={prov.url}>
- {prov.url}
+ const type: KnownAuthMethods = method.type as KnownAuthMethods;
+ function changeProviderTo(url: string): void {
+ const copy = [...changedProvider];
+ copy[index] = url;
+ setChangedProvider(copy);
+ }
+ return (
+ <div
+ key={index}
+ class="block"
+ style={{ display: "flex", alignItems: "center" }}
+ >
+ <span class="icon">{authMethods[type]?.icon}</span>
+ <span>{method.instructions}</span>
+ <span>
+ <span class="select ">
+ <select
+ onChange={(e) => changeProviderTo(e.currentTarget.value)}
+ value={providerURL ?? ""}
+ >
+ <option key="none" value="">
+ {" "}
+ &lt;&lt; off &gt;&gt;{" "}
</option>
- ))}
- </select>
+ {selectableProviders[type]?.map((prov) => (
+ <option key={prov.url} value={prov.url}>
+ {prov.url}
+ </option>
+ ))}
+ </select>
+ </span>
</span>
- </span>
- </div>
- );
- })}
- <div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
- <button class="button" onClick={cancel}>Cancel</button>
- <span class="buttons">
- <button class="button" onClick={() => setChangedProvider([])}>Reset</button>
- <button class="button is-info" onClick={sendChanges}>Confirm</button>
- </span>
- </div>
- </section>
- </AnastasisClientFrame>
+ </div>
+ );
+ })}
+ <div
+ style={{
+ marginTop: "2em",
+ display: "flex",
+ justifyContent: "space-between",
+ }}
+ >
+ <button class="button" onClick={cancel}>
+ Cancel
+ </button>
+ <span class="buttons">
+ <button class="button" onClick={() => setChangedProvider([])}>
+ Reset
+ </button>
+ <button class="button is-info" onClick={sendChanges}>
+ Confirm
+ </button>
+ </span>
+ </div>
+ </section>
+ </AnastasisClientFrame>
+ );
}
diff --git a/packages/anastasis-webui/src/pages/home/PoliciesPayingScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/PoliciesPayingScreen.stories.tsx
index 3ddf8011e..9bebcfbc9 100644
--- a/packages/anastasis-webui/src/pages/home/PoliciesPayingScreen.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/PoliciesPayingScreen.stories.tsx
@@ -15,35 +15,40 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { ReducerState } from 'anastasis-core';
-import { createExample, reducerStatesExample } from '../../utils';
-import { PoliciesPayingScreen as TestedComponent } from './PoliciesPayingScreen';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { ReducerState } from "anastasis-core";
+import { createExample, reducerStatesExample } from "../../utils";
+import { PoliciesPayingScreen as TestedComponent } from "./PoliciesPayingScreen";
export default {
- title: 'Pages/backup/__PoliciesPaying',
+ title: "Pages/backup/__PoliciesPaying",
component: TestedComponent,
args: {
order: 9,
},
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
-export const Example = createExample(TestedComponent, reducerStatesExample.policyPay);
+export const Example = createExample(
+ TestedComponent,
+ reducerStatesExample.policyPay,
+);
export const WithSomePaymentRequest = createExample(TestedComponent, {
...reducerStatesExample.policyPay,
- policy_payment_requests: [{
- payto: 'payto://x-taler-bank/bank.taler/account-a',
- provider: 'provider1'
- }, {
- payto: 'payto://x-taler-bank/bank.taler/account-b',
- provider: 'provider2'
- }]
+ policy_payment_requests: [
+ {
+ payto: "payto://x-taler-bank/bank.taler/account-a",
+ provider: "provider1",
+ },
+ {
+ payto: "payto://x-taler-bank/bank.taler/account-b",
+ provider: "provider2",
+ },
+ ],
} as ReducerState);
diff --git a/packages/anastasis-webui/src/pages/home/PoliciesPayingScreen.tsx b/packages/anastasis-webui/src/pages/home/PoliciesPayingScreen.tsx
index a470f5155..c3568b32d 100644
--- a/packages/anastasis-webui/src/pages/home/PoliciesPayingScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/PoliciesPayingScreen.tsx
@@ -3,20 +3,23 @@ import { useAnastasisContext } from "../../context/anastasis";
import { AnastasisClientFrame } from "./index";
export function PoliciesPayingScreen(): VNode {
- const reducer = useAnastasisContext()
+ const reducer = useAnastasisContext();
if (!reducer) {
- return <div>no reducer in context</div>
+ return <div>no reducer in context</div>;
}
- if (!reducer.currentReducerState || reducer.currentReducerState.backup_state === undefined) {
- return <div>invalid state</div>
+ if (
+ !reducer.currentReducerState ||
+ reducer.currentReducerState.backup_state === undefined
+ ) {
+ return <div>invalid state</div>;
}
const payments = reducer.currentReducerState.policy_payment_requests ?? [];
-
+
return (
<AnastasisClientFrame hideNav title="Backup: Recovery Document Payments">
<p>
- Some of the providers require a payment to store the encrypted
- recovery document.
+ Some of the providers require a payment to store the encrypted recovery
+ document.
</p>
<ul>
{payments.map((x, i) => {
diff --git a/packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.stories.tsx
index e92a231a8..47860db29 100644
--- a/packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.stories.tsx
@@ -16,30 +16,32 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { ReducerState } from 'anastasis-core';
-import { createExample, reducerStatesExample } from '../../utils';
-import { RecoveryFinishedScreen as TestedComponent } from './RecoveryFinishedScreen';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { ReducerState } from "anastasis-core";
+import { createExample, reducerStatesExample } from "../../utils";
+import { RecoveryFinishedScreen as TestedComponent } from "./RecoveryFinishedScreen";
export default {
- title: 'Pages/recovery/Finished',
+ title: "Pages/recovery/Finished",
args: {
order: 7,
},
component: TestedComponent,
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
export const GoodEnding = createExample(TestedComponent, {
...reducerStatesExample.recoveryFinished,
- core_secret: { mime: 'text/plain', value: 'hello' }
+ core_secret: { mime: "text/plain", value: "hello" },
} as ReducerState);
-export const BadEnding = createExample(TestedComponent, reducerStatesExample.recoveryFinished);
+export const BadEnding = createExample(
+ TestedComponent,
+ reducerStatesExample.recoveryFinished,
+);
diff --git a/packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.tsx b/packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.tsx
index a61ef9efa..11ae09d4f 100644
--- a/packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.tsx
@@ -1,39 +1,53 @@
-import {
- bytesToString,
- decodeCrock
-} from "@gnu-taler/taler-util";
+import { bytesToString, decodeCrock } from "@gnu-taler/taler-util";
import { h, VNode } from "preact";
import { useAnastasisContext } from "../../context/anastasis";
import { AnastasisClientFrame } from "./index";
export function RecoveryFinishedScreen(): VNode {
- const reducer = useAnastasisContext()
+ const reducer = useAnastasisContext();
if (!reducer) {
- return <div>no reducer in context</div>
+ return <div>no reducer in context</div>;
}
- if (!reducer.currentReducerState || reducer.currentReducerState.recovery_state === undefined) {
- return <div>invalid state</div>
+ if (
+ !reducer.currentReducerState ||
+ reducer.currentReducerState.recovery_state === undefined
+ ) {
+ return <div>invalid state</div>;
}
- const encodedSecret = reducer.currentReducerState.core_secret
+ const encodedSecret = reducer.currentReducerState.core_secret;
if (!encodedSecret) {
- return <AnastasisClientFrame title="Recovery Problem" hideNav>
- <p>
- Secret not found
- </p>
- <div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
- <button class="button" onClick={() => reducer.back()}>Back</button>
- </div>
- </AnastasisClientFrame>
+ return (
+ <AnastasisClientFrame title="Recovery Problem" hideNav>
+ <p>Secret not found</p>
+ <div
+ style={{
+ marginTop: "2em",
+ display: "flex",
+ justifyContent: "space-between",
+ }}
+ >
+ <button class="button" onClick={() => reducer.back()}>
+ Back
+ </button>
+ </div>
+ </AnastasisClientFrame>
+ );
}
- const secret = bytesToString(decodeCrock(encodedSecret.value))
+ const secret = bytesToString(decodeCrock(encodedSecret.value));
return (
<AnastasisClientFrame title="Recovery Finished" hideNav>
- <p>
- Secret: {secret}
- </p>
- <div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
- <button class="button" onClick={() => reducer.back()}>Back</button>
+ <p>Your secret: {secret}</p>
+ <div
+ style={{
+ marginTop: "2em",
+ display: "flex",
+ justifyContent: "space-between",
+ }}
+ >
+ <button class="button" onClick={() => reducer.back()}>
+ Back
+ </button>
</div>
</AnastasisClientFrame>
);
diff --git a/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.stories.tsx
index e348101ee..4a1cba6a8 100644
--- a/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.stories.tsx
@@ -15,44 +15,51 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { ReducerState } from 'anastasis-core';
-import { createExample, reducerStatesExample } from '../../utils';
-import { ReviewPoliciesScreen as TestedComponent } from './ReviewPoliciesScreen';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { ReducerState } from "anastasis-core";
+import { createExample, reducerStatesExample } from "../../utils";
+import { ReviewPoliciesScreen as TestedComponent } from "./ReviewPoliciesScreen";
export default {
- title: 'Pages/backup/ReviewPolicies',
+ title: "Pages/backup/ReviewPolicies",
args: {
order: 6,
},
component: TestedComponent,
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
export const HasPoliciesButMethodListIsEmpty = createExample(TestedComponent, {
...reducerStatesExample.policyReview,
- policies: [{
- methods: [{
- authentication_method: 0,
- provider: 'asd'
- }, {
- authentication_method: 1,
- provider: 'asd'
- }]
- }, {
- methods: [{
- authentication_method: 1,
- provider: 'asd'
- }]
- }],
- authentication_methods: []
+ policies: [
+ {
+ methods: [
+ {
+ authentication_method: 0,
+ provider: "asd",
+ },
+ {
+ authentication_method: 1,
+ provider: "asd",
+ },
+ ],
+ },
+ {
+ methods: [
+ {
+ authentication_method: 1,
+ provider: "asd",
+ },
+ ],
+ },
+ ],
+ authentication_methods: [],
} as ReducerState);
export const SomePoliciesWithMethods = createExample(TestedComponent, {
@@ -62,186 +69,193 @@ export const SomePoliciesWithMethods = createExample(TestedComponent, {
methods: [
{
authentication_method: 0,
- provider: "https://kudos.demo.anastasis.lu/"
+ provider: "https://kudos.demo.anastasis.lu/",
},
{
authentication_method: 1,
- provider: "https://kudos.demo.anastasis.lu/"
+ provider: "https://kudos.demo.anastasis.lu/",
},
{
authentication_method: 2,
- provider: "https://kudos.demo.anastasis.lu/"
- }
- ]
+ provider: "https://kudos.demo.anastasis.lu/",
+ },
+ ],
},
{
methods: [
{
authentication_method: 0,
- provider: "https://kudos.demo.anastasis.lu/"
+ provider: "https://kudos.demo.anastasis.lu/",
},
{
authentication_method: 1,
- provider: "https://kudos.demo.anastasis.lu/"
+ provider: "https://kudos.demo.anastasis.lu/",
},
{
authentication_method: 3,
- provider: "https://anastasis.demo.taler.net/"
- }
- ]
+ provider: "https://anastasis.demo.taler.net/",
+ },
+ ],
},
{
methods: [
{
authentication_method: 0,
- provider: "https://kudos.demo.anastasis.lu/"
+ provider: "https://kudos.demo.anastasis.lu/",
},
{
authentication_method: 1,
- provider: "https://kudos.demo.anastasis.lu/"
+ provider: "https://kudos.demo.anastasis.lu/",
},
{
authentication_method: 4,
- provider: "https://anastasis.demo.taler.net/"
- }
- ]
+ provider: "https://anastasis.demo.taler.net/",
+ },
+ ],
},
{
methods: [
{
authentication_method: 0,
- provider: "https://kudos.demo.anastasis.lu/"
+ provider: "https://kudos.demo.anastasis.lu/",
},
{
authentication_method: 2,
- provider: "https://kudos.demo.anastasis.lu/"
+ provider: "https://kudos.demo.anastasis.lu/",
},
{
authentication_method: 3,
- provider: "https://anastasis.demo.taler.net/"
- }
- ]
+ provider: "https://anastasis.demo.taler.net/",
+ },
+ ],
},
{
methods: [
{
authentication_method: 0,
- provider: "https://kudos.demo.anastasis.lu/"
+ provider: "https://kudos.demo.anastasis.lu/",
},
{
authentication_method: 2,
- provider: "https://kudos.demo.anastasis.lu/"
+ provider: "https://kudos.demo.anastasis.lu/",
},
{
authentication_method: 4,
- provider: "https://anastasis.demo.taler.net/"
- }
- ]
+ provider: "https://anastasis.demo.taler.net/",
+ },
+ ],
},
{
methods: [
{
authentication_method: 0,
- provider: "https://kudos.demo.anastasis.lu/"
+ provider: "https://kudos.demo.anastasis.lu/",
},
{
authentication_method: 3,
- provider: "https://anastasis.demo.taler.net/"
+ provider: "https://anastasis.demo.taler.net/",
},
{
authentication_method: 4,
- provider: "https://anastasis.demo.taler.net/"
- }
- ]
+ provider: "https://anastasis.demo.taler.net/",
+ },
+ ],
},
{
methods: [
{
authentication_method: 1,
- provider: "https://kudos.demo.anastasis.lu/"
+ provider: "https://kudos.demo.anastasis.lu/",
},
{
authentication_method: 2,
- provider: "https://kudos.demo.anastasis.lu/"
+ provider: "https://kudos.demo.anastasis.lu/",
},
{
authentication_method: 3,
- provider: "https://anastasis.demo.taler.net/"
- }
- ]
+ provider: "https://anastasis.demo.taler.net/",
+ },
+ ],
},
{
methods: [
{
authentication_method: 1,
- provider: "https://kudos.demo.anastasis.lu/"
+ provider: "https://kudos.demo.anastasis.lu/",
},
{
authentication_method: 2,
- provider: "https://kudos.demo.anastasis.lu/"
+ provider: "https://kudos.demo.anastasis.lu/",
},
{
authentication_method: 4,
- provider: "https://anastasis.demo.taler.net/"
- }
- ]
+ provider: "https://anastasis.demo.taler.net/",
+ },
+ ],
},
{
methods: [
{
authentication_method: 1,
- provider: "https://kudos.demo.anastasis.lu/"
+ provider: "https://kudos.demo.anastasis.lu/",
},
{
authentication_method: 3,
- provider: "https://anastasis.demo.taler.net/"
+ provider: "https://anastasis.demo.taler.net/",
},
{
authentication_method: 4,
- provider: "https://anastasis.demo.taler.net/"
- }
- ]
+ provider: "https://anastasis.demo.taler.net/",
+ },
+ ],
},
{
methods: [
{
authentication_method: 2,
- provider: "https://kudos.demo.anastasis.lu/"
+ provider: "https://kudos.demo.anastasis.lu/",
},
{
authentication_method: 3,
- provider: "https://anastasis.demo.taler.net/"
+ provider: "https://anastasis.demo.taler.net/",
},
{
authentication_method: 4,
- provider: "https://anastasis.demo.taler.net/"
- }
- ]
- }
+ provider: "https://anastasis.demo.taler.net/",
+ },
+ ],
+ },
+ ],
+ authentication_methods: [
+ {
+ type: "email",
+ instructions: "Email to qwe@asd.com",
+ challenge: "E5VPA",
+ },
+ {
+ type: "sms",
+ instructions: "SMS to 555-555",
+ challenge: "",
+ },
+ {
+ type: "question",
+ instructions: "Does P equal NP?",
+ challenge: "C5SP8",
+ },
+ {
+ type: "totp",
+ instructions: "Response code for 'Anastasis'",
+ challenge: "E5VPA",
+ },
+ {
+ type: "sms",
+ instructions: "SMS to 6666-6666",
+ challenge: "",
+ },
+ {
+ type: "question",
+ instructions: "How did the chicken cross the road?",
+ challenge: "C5SP8",
+ },
],
- authentication_methods: [{
- type: "email",
- instructions: "Email to qwe@asd.com",
- challenge: "E5VPA"
- }, {
- type: "sms",
- instructions: "SMS to 555-555",
- challenge: ""
- }, {
- type: "question",
- instructions: "Does P equal NP?",
- challenge: "C5SP8"
- },{
- type: "totp",
- instructions: "Response code for 'Anastasis'",
- challenge: "E5VPA"
- }, {
- type: "sms",
- instructions: "SMS to 6666-6666",
- challenge: ""
- }, {
- type: "question",
- instructions: "How did the chicken cross the road?",
- challenge: "C5SP8"
-}]
} as ReducerState);
diff --git a/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx b/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx
index aa98b5dd9..c43f0cdea 100644
--- a/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx
@@ -6,16 +6,20 @@ import { EditPoliciesScreen } from "./EditPoliciesScreen";
import { AnastasisClientFrame } from "./index";
export function ReviewPoliciesScreen(): VNode {
- const [editingPolicy, setEditingPolicy] = useState<number | undefined>()
- const reducer = useAnastasisContext()
+ const [editingPolicy, setEditingPolicy] = useState<number | undefined>();
+ const reducer = useAnastasisContext();
if (!reducer) {
- return <div>no reducer in context</div>
+ return <div>no reducer in context</div>;
}
- if (!reducer.currentReducerState || reducer.currentReducerState.backup_state === undefined) {
- return <div>invalid state</div>
+ if (
+ !reducer.currentReducerState ||
+ reducer.currentReducerState.backup_state === undefined
+ ) {
+ return <div>invalid state</div>;
}
- const configuredAuthMethods = reducer.currentReducerState.authentication_methods ?? [];
+ const configuredAuthMethods =
+ reducer.currentReducerState.authentication_methods ?? [];
const policies = reducer.currentReducerState.policies ?? [];
if (editingPolicy !== undefined) {
@@ -28,58 +32,109 @@ export function ReviewPoliciesScreen(): VNode {
policy_index: editingPolicy,
policy: newMethods,
});
- setEditingPolicy(undefined)
+ setEditingPolicy(undefined);
}}
/>
- )
+ );
}
- const errors = policies.length < 1 ? 'Need more policies' : undefined
+ const errors = policies.length < 1 ? "Need more policies" : undefined;
return (
- <AnastasisClientFrame hideNext={errors} title="Backup: Review Recovery Policies">
- {policies.length > 0 && <p class="block">
- Based on your configured authentication method you have created, some policies
- have been configured. In order to recover your secret you have to solve all the
- challenges of at least one policy.
- </p>}
- {policies.length < 1 && <p class="block">
- No policies had been created. Go back and add more authentication methods.
- </p>}
- <div class="block" style={{ justifyContent: 'flex-end' }} >
- <button class="button is-success" onClick={() => setEditingPolicy(policies.length + 1)}>Add new policy</button>
+ <AnastasisClientFrame
+ hideNext={errors}
+ title="Backup: Review Recovery Policies"
+ >
+ {policies.length > 0 && (
+ <p class="block">
+ Based on your configured authentication method you have created, some
+ policies have been configured. In order to recover your secret you
+ have to solve all the challenges of at least one policy.
+ </p>
+ )}
+ {policies.length < 1 && (
+ <p class="block">
+ No policies had been created. Go back and add more authentication
+ methods.
+ </p>
+ )}
+ <div class="block" style={{ justifyContent: "flex-end" }}>
+ <button
+ class="button is-success"
+ onClick={() => setEditingPolicy(policies.length + 1)}
+ >
+ Add new policy
+ </button>
</div>
{policies.map((p, policy_index) => {
const methods = p.methods
- .map(x => configuredAuthMethods[x.authentication_method] && ({ ...configuredAuthMethods[x.authentication_method], provider: x.provider }))
- .filter(x => !!x)
+ .map(
+ (x) =>
+ configuredAuthMethods[x.authentication_method] && {
+ ...configuredAuthMethods[x.authentication_method],
+ provider: x.provider,
+ },
+ )
+ .filter((x) => !!x);
- const policyName = methods.map(x => x.type).join(" + ");
+ const policyName = methods.map((x) => x.type).join(" + ");
+
+ if (p.methods.length > methods.length) {
+ //there is at least one authentication method that is corrupted
+ return null;
+ }
return (
- <div key={policy_index} class="box" style={{ display: 'flex', justifyContent: 'space-between' }}>
+ <div
+ key={policy_index}
+ class="box"
+ style={{ display: "flex", justifyContent: "space-between" }}
+ >
<div>
<h3 class="subtitle">
Policy #{policy_index + 1}: {policyName}
</h3>
- {!methods.length && <p>
- No auth method found
- </p>}
+ {!methods.length && <p>No auth method found</p>}
{methods.map((m, i) => {
return (
- <p key={i} class="block" style={{ display: 'flex', alignItems: 'center' }}>
+ <p
+ key={i}
+ class="block"
+ style={{ display: "flex", alignItems: "center" }}
+ >
<span class="icon">
{authMethods[m.type as KnownAuthMethods]?.icon}
</span>
<span>
- {m.instructions} recovery provided by <a href={m.provider}>{m.provider}</a>
+ {m.instructions} recovery provided by{" "}
+ <a href={m.provider}>{m.provider}</a>
</span>
</p>
);
})}
</div>
- <div style={{ marginTop: 'auto', marginBottom: 'auto', display: 'flex', justifyContent: 'space-between', flexDirection: 'column' }}>
- <button class="button is-info block" onClick={() => setEditingPolicy(policy_index)}>Edit</button>
- <button class="button is-danger block" onClick={() => reducer.transition("delete_policy", { policy_index })}>Delete</button>
+ <div
+ style={{
+ marginTop: "auto",
+ marginBottom: "auto",
+ display: "flex",
+ justifyContent: "space-between",
+ flexDirection: "column",
+ }}
+ >
+ <button
+ class="button is-info block"
+ onClick={() => setEditingPolicy(policy_index)}
+ >
+ Edit
+ </button>
+ <button
+ class="button is-danger block"
+ onClick={() =>
+ reducer.transition("delete_policy", { policy_index })
+ }
+ >
+ Delete
+ </button>
</div>
</div>
);
diff --git a/packages/anastasis-webui/src/pages/home/SecretEditorScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/SecretEditorScreen.stories.tsx
index db061d936..3f2c6a245 100644
--- a/packages/anastasis-webui/src/pages/home/SecretEditorScreen.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/SecretEditorScreen.stories.tsx
@@ -15,30 +15,29 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { ReducerState } from 'anastasis-core';
-import { createExample, reducerStatesExample } from '../../utils';
-import { SecretEditorScreen as TestedComponent } from './SecretEditorScreen';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { ReducerState } from "anastasis-core";
+import { createExample, reducerStatesExample } from "../../utils";
+import { SecretEditorScreen as TestedComponent } from "./SecretEditorScreen";
export default {
- title: 'Pages/backup/SecretInput',
+ title: "Pages/backup/SecretInput",
component: TestedComponent,
args: {
order: 7,
},
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
export const WithSecretNamePreselected = createExample(TestedComponent, {
...reducerStatesExample.secretEdition,
- secret_name: 'someSecretName',
+ secret_name: "someSecretName",
} as ReducerState);
export const WithoutName = createExample(TestedComponent, {
diff --git a/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.stories.tsx
index 8d02ebfbe..01ce3f0a7 100644
--- a/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.stories.tsx
@@ -15,37 +15,35 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { ReducerState } from 'anastasis-core';
-import { createExample, reducerStatesExample } from '../../utils';
-import { SecretSelectionScreen as TestedComponent } from './SecretSelectionScreen';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { ReducerState } from "anastasis-core";
+import { createExample, reducerStatesExample } from "../../utils";
+import { SecretSelectionScreen as TestedComponent } from "./SecretSelectionScreen";
export default {
- title: 'Pages/recovery/SecretSelection',
+ title: "Pages/recovery/SecretSelection",
component: TestedComponent,
args: {
order: 4,
},
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ 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',
+ provider_url: "https://kudos.demo.anastasis.lu/",
+ secret_name: "secretName",
version: 1,
},
} as ReducerState);
-
export const NoRecoveryDocumentFound = createExample(TestedComponent, {
...reducerStatesExample.secretSelection,
recovery_document: undefined,
diff --git a/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.tsx b/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.tsx
index 398393619..4000f9bfe 100644
--- a/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.tsx
@@ -8,18 +8,23 @@ import { AnastasisClientFrame } from "./index";
export function SecretSelectionScreen(): VNode {
const [selectingVersion, setSelectingVersion] = useState<boolean>(false);
- const reducer = useAnastasisContext()
+ const reducer = useAnastasisContext();
- const [manageProvider, setManageProvider] = useState(false)
- const currentVersion = (reducer?.currentReducerState
- && ("recovery_document" in reducer.currentReducerState)
- && reducer.currentReducerState.recovery_document?.version) || 0;
+ const [manageProvider, setManageProvider] = useState(false);
+ const currentVersion =
+ (reducer?.currentReducerState &&
+ "recovery_document" in reducer.currentReducerState &&
+ reducer.currentReducerState.recovery_document?.version) ||
+ 0;
if (!reducer) {
- return <div>no reducer in context</div>
+ return <div>no reducer in context</div>;
}
- if (!reducer.currentReducerState || reducer.currentReducerState.recovery_state === undefined) {
- return <div>invalid state</div>
+ if (
+ !reducer.currentReducerState ||
+ reducer.currentReducerState.recovery_state === undefined
+ ) {
+ return <div>invalid state</div>;
}
async function doSelectVersion(p: string, n: number): Promise<void> {
@@ -33,72 +38,101 @@ export function SecretSelectionScreen(): VNode {
});
}
- const providerList = Object.keys(reducer.currentReducerState.authentication_providers ?? {})
- const recoveryDocument = reducer.currentReducerState.recovery_document
+ const providerList = Object.keys(
+ reducer.currentReducerState.authentication_providers ?? {},
+ );
+ const recoveryDocument = reducer.currentReducerState.recovery_document;
if (!recoveryDocument) {
- return <ChooseAnotherProviderScreen
- providers={providerList} selected=""
- onChange={(newProv) => doSelectVersion(newProv, 0)}
- />
+ return (
+ <ChooseAnotherProviderScreen
+ providers={providerList}
+ selected=""
+ onChange={(newProv) => doSelectVersion(newProv, 0)}
+ />
+ );
}
if (selectingVersion) {
- return <SelectOtherVersionProviderScreen providers={providerList}
- provider={recoveryDocument.provider_url} version={recoveryDocument.version}
- onCancel={() => setSelectingVersion(false)}
- onConfirm={doSelectVersion}
- />
+ return (
+ <SelectOtherVersionProviderScreen
+ providers={providerList}
+ provider={recoveryDocument.provider_url}
+ version={recoveryDocument.version}
+ onCancel={() => setSelectingVersion(false)}
+ onConfirm={doSelectVersion}
+ />
+ );
}
if (manageProvider) {
- return <AddingProviderScreen onCancel={() => setManageProvider(false)} />
+ return <AddingProviderScreen onCancel={() => setManageProvider(false)} />;
}
return (
<AnastasisClientFrame title="Recovery: Select secret">
<div class="columns">
<div class="column">
- <div class="box" style={{ border: '2px solid green' }}>
+ <div class="box" style={{ border: "2px solid green" }}>
<h1 class="subtitle">{recoveryDocument.provider_url}</h1>
<div class="block">
- {currentVersion === 0 ? <p>
- Set to recover the latest version
- </p> : <p>
- Set to recover the version number {currentVersion}
- </p>}
+ {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>
+ <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>
+ Secret found, you can select another version or continue to the
+ challenges solving
+ </p>
<p class="block">
- <button class="button is-info" onClick={() => setManageProvider(true)}>
+ <a onClick={() => setManageProvider(true)}>
Manage recovery providers
- </button>
+ </a>
</p>
-
</div>
</div>
</AnastasisClientFrame>
);
}
-
-function ChooseAnotherProviderScreen({ providers, selected, onChange }: { selected: string; providers: string[]; onChange: (prov: string) => void }): VNode {
+function ChooseAnotherProviderScreen({
+ providers,
+ selected,
+ onChange,
+}: {
+ selected: string;
+ providers: string[];
+ onChange: (prov: string) => void;
+}): VNode {
return (
- <AnastasisClientFrame hideNext="Recovery document not found" title="Recovery: Problem">
+ <AnastasisClientFrame
+ hideNext="Recovery document not found"
+ title="Recovery: Problem"
+ >
<p>No recovery document found, try with another provider</p>
<div class="field">
<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}>
- <option key="none" disabled selected value=""> Choose a provider </option>
- {providers.map(prov => (
+ <select
+ onChange={(e) => onChange(e.currentTarget.value)}
+ value={selected}
+ >
+ <option key="none" disabled selected value="">
+ {" "}
+ Choose a provider{" "}
+ </option>
+ {providers.map((prov) => (
<option key={prov} value={prov}>
{prov}
</option>
@@ -114,9 +148,23 @@ function ChooseAnotherProviderScreen({ providers, selected, onChange }: { select
);
}
-function SelectOtherVersionProviderScreen({ providers, provider, version, onConfirm, onCancel }: { onCancel: () => void; provider: string; version: number; providers: string[]; onConfirm: (prov: string, v: number) => Promise<void>; }): VNode {
+function SelectOtherVersionProviderScreen({
+ providers,
+ provider,
+ version,
+ onConfirm,
+ onCancel,
+}: {
+ onCancel: () => void;
+ provider: string;
+ version: number;
+ providers: string[];
+ onConfirm: (prov: string, v: number) => Promise<void>;
+}): VNode {
const [otherProvider, setOtherProvider] = useState<string>(provider);
- const [otherVersion, setOtherVersion] = useState(version > 0 ? String(version) : "");
+ const [otherVersion, setOtherVersion] = useState(
+ version > 0 ? String(version) : "",
+ );
return (
<AnastasisClientFrame hideNav title="Recovery: Select secret">
@@ -125,11 +173,11 @@ function SelectOtherVersionProviderScreen({ providers, provider, version, onConf
<div class="box">
<h1 class="subtitle">Provider {otherProvider}</h1>
<div class="block">
- {version === 0 ? <p>
- Set to recover the latest version
- </p> : <p>
- Set to recover the version number {version}
- </p>}
+ {version === 0 ? (
+ <p>Set to recover the latest version</p>
+ ) : (
+ <p>Set to recover the version number {version}</p>
+ )}
<p>Specify other version below or use the latest</p>
</div>
@@ -137,9 +185,15 @@ function SelectOtherVersionProviderScreen({ providers, provider, version, onConf
<label class="label">Provider</label>
<div class="control is-expanded has-icons-left">
<div class="select is-fullwidth">
- <select onChange={(e) => setOtherProvider(e.currentTarget.value)} value={otherProvider}>
- <option key="none" disabled selected value=""> Choose a provider </option>
- {providers.map(prov => (
+ <select
+ onChange={(e) => setOtherProvider(e.currentTarget.value)}
+ value={otherProvider}
+ >
+ <option key="none" disabled selected value="">
+ {" "}
+ Choose a provider{" "}
+ </option>
+ {providers.map((prov) => (
<option key={prov} value={prov}>
{prov}
</option>
@@ -156,23 +210,40 @@ function SelectOtherVersionProviderScreen({ providers, provider, version, onConf
label="Version"
placeholder="version number to recover"
grabFocus
- bind={[otherVersion, setOtherVersion]} />
+ bind={[otherVersion, setOtherVersion]}
+ />
</div>
</div>
- <div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
- <button class="button" onClick={onCancel}>Cancel</button>
+ <div
+ style={{
+ marginTop: "2em",
+ display: "flex",
+ justifyContent: "space-between",
+ }}
+ >
+ <button class="button" onClick={onCancel}>
+ Cancel
+ </button>
<div class="buttons">
- <AsyncButton class="button" onClick={() => onConfirm(otherProvider, 0)}>Use latest</AsyncButton>
- <AsyncButton class="button is-info" onClick={() => onConfirm(otherProvider, parseInt(otherVersion, 10))}>Confirm</AsyncButton>
+ <AsyncButton
+ class="button"
+ onClick={() => onConfirm(otherProvider, 0)}
+ >
+ Use latest
+ </AsyncButton>
+ <AsyncButton
+ class="button is-info"
+ onClick={() =>
+ onConfirm(otherProvider, parseInt(otherVersion, 10))
+ }
+ >
+ Confirm
+ </AsyncButton>
</div>
</div>
</div>
- <div class="column">
- .
- </div>
+ <div class="column">.</div>
</div>
-
</AnastasisClientFrame>
);
-
}
diff --git a/packages/anastasis-webui/src/pages/home/SolveScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/SolveScreen.stories.tsx
index f1f2802ae..76d0700db 100644
--- a/packages/anastasis-webui/src/pages/home/SolveScreen.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/SolveScreen.stories.tsx
@@ -15,55 +15,63 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { ChallengeFeedbackStatus, RecoveryStates, ReducerState } from 'anastasis-core';
-import { createExample, reducerStatesExample } from '../../utils';
-import { SolveScreen as TestedComponent } from './SolveScreen';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import {
+ ChallengeFeedbackStatus,
+ RecoveryStates,
+ ReducerState,
+} from "anastasis-core";
+import { createExample, reducerStatesExample } from "../../utils";
+import { SolveScreen as TestedComponent } from "./SolveScreen";
export default {
- title: 'Pages/recovery/SolveChallenge/Solve',
+ title: "Pages/recovery/SolveChallenge/Solve",
component: TestedComponent,
args: {
order: 6,
},
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
-export const NoInformation = createExample(TestedComponent, reducerStatesExample.challengeSolving);
+export const NoInformation = createExample(
+ TestedComponent,
+ reducerStatesExample.challengeSolving,
+);
export const NotSupportedChallenge = createExample(TestedComponent, {
...reducerStatesExample.challengeSolving,
recovery_information: {
- challenges: [{
- cost: 'USD:1',
- instructions: 'does P equals NP?',
- type: 'chall-type',
- uuid: 'ASDASDSAD!1'
- }],
+ challenges: [
+ {
+ cost: "USD:1",
+ instructions: "does P equals NP?",
+ type: "chall-type",
+ uuid: "ASDASDSAD!1",
+ },
+ ],
policies: [],
},
- selected_challenge_uuid: 'ASDASDSAD!1',
-
+ selected_challenge_uuid: "ASDASDSAD!1",
} as ReducerState);
export const MismatchedChallengeId = createExample(TestedComponent, {
...reducerStatesExample.challengeSolving,
recovery_information: {
- challenges: [{
- cost: 'USD:1',
- instructions: 'does P equals NP?',
- type: 'chall-type',
- uuid: 'ASDASDSAD!1'
- }],
+ challenges: [
+ {
+ cost: "USD:1",
+ instructions: "does P equals NP?",
+ type: "chall-type",
+ uuid: "ASDASDSAD!1",
+ },
+ ],
policies: [],
},
- selected_challenge_uuid: 'no-no-no'
+ selected_challenge_uuid: "no-no-no",
} as ReducerState);
-
diff --git a/packages/anastasis-webui/src/pages/home/SolveScreen.tsx b/packages/anastasis-webui/src/pages/home/SolveScreen.tsx
index 5e17c9aa1..b87dad2ce 100644
--- a/packages/anastasis-webui/src/pages/home/SolveScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/SolveScreen.tsx
@@ -2,76 +2,126 @@ import { h, VNode } from "preact";
import { AnastasisClientFrame } from ".";
import {
ChallengeFeedback,
- ChallengeFeedbackStatus
+ ChallengeFeedbackStatus,
} from "../../../../anastasis-core/lib";
import { Notifications } from "../../components/Notifications";
import { useAnastasisContext } from "../../context/anastasis";
import { authMethods, KnownAuthMethods } from "./authMethod";
-export function SolveOverviewFeedbackDisplay(props: { feedback?: ChallengeFeedback }): VNode {
+export function SolveOverviewFeedbackDisplay(props: {
+ feedback?: ChallengeFeedback;
+}): VNode {
const { feedback } = props;
if (!feedback) {
return <div />;
}
switch (feedback.state) {
case ChallengeFeedbackStatus.Message:
- return (<Notifications notifications={[{
- type: "INFO",
- message: `Message from provider`,
- description: feedback.message
- }]} />);
+ return (
+ <Notifications
+ notifications={[
+ {
+ type: "INFO",
+ message: `Message from provider`,
+ description: feedback.message,
+ },
+ ]}
+ />
+ );
case ChallengeFeedbackStatus.Payment:
- return <Notifications notifications={[{
- type: "INFO",
- message: `Message from provider`,
- description: <span>
- To pay you can <a href={feedback.taler_pay_uri}>click here</a>
- </span>
- }]} />
+ return (
+ <Notifications
+ notifications={[
+ {
+ type: "INFO",
+ message: `Message from provider`,
+ description: (
+ <span>
+ To pay you can <a href={feedback.taler_pay_uri}>click here</a>
+ </span>
+ ),
+ },
+ ]}
+ />
+ );
case ChallengeFeedbackStatus.AuthIban:
- return <Notifications notifications={[{
- type: "INFO",
- message: `Message from provider`,
- description: `Need to send a wire transfer to "${feedback.business_name}"`
- }]} />;
+ return (
+ <Notifications
+ notifications={[
+ {
+ type: "INFO",
+ message: `Message from provider`,
+ description: `Need to send a wire transfer to "${feedback.business_name}"`,
+ },
+ ]}
+ />
+ );
case ChallengeFeedbackStatus.ServerFailure:
- return (<Notifications notifications={[{
- type: "ERROR",
- message: `Server error: Code ${feedback.http_status}`,
- description: feedback.error_response
- }]} />);
+ return (
+ <Notifications
+ notifications={[
+ {
+ type: "ERROR",
+ message: `Server error: Code ${feedback.http_status}`,
+ description: feedback.error_response,
+ },
+ ]}
+ />
+ );
case ChallengeFeedbackStatus.RateLimitExceeded:
- return (<Notifications notifications={[{
- type: "ERROR",
- message: `Message from provider`,
- description: "There were to many failed attempts."
- }]} />);
+ return (
+ <Notifications
+ notifications={[
+ {
+ type: "ERROR",
+ message: `Message from provider`,
+ description: "There were to many failed attempts.",
+ },
+ ]}
+ />
+ );
case ChallengeFeedbackStatus.Redirect:
- return (<Notifications notifications={[{
- type: "INFO",
- message: `Message from provider`,
- description: <span>
- Please visit this link: <a>{feedback.redirect_url}</a>
- </span>
- }]} />);
+ return (
+ <Notifications
+ notifications={[
+ {
+ type: "INFO",
+ message: `Message from provider`,
+ description: (
+ <span>
+ Please visit this link: <a>{feedback.redirect_url}</a>
+ </span>
+ ),
+ },
+ ]}
+ />
+ );
case ChallengeFeedbackStatus.Unsupported:
- return (<Notifications notifications={[{
- type: "ERROR",
- message: `This client doesn't support solving this type of challenge`,
- description: `Use another version or contact the provider. Type of challenge "${feedback.unsupported_method}"`
- }]} />);
+ return (
+ <Notifications
+ notifications={[
+ {
+ type: "ERROR",
+ message: `This client doesn't support solving this type of challenge`,
+ description: `Use another version or contact the provider. Type of challenge "${feedback.unsupported_method}"`,
+ },
+ ]}
+ />
+ );
case ChallengeFeedbackStatus.TruthUnknown:
- return (<Notifications notifications={[{
- type: "ERROR",
- message: `Provider doesn't recognize the type of challenge`,
- description: "Contact the provider for further information"
- }]} />);
- default:
return (
- <div>
- <pre>{JSON.stringify(feedback)}</pre>
- </div>
+ <Notifications
+ notifications={[
+ {
+ type: "ERROR",
+ message: `Provider doesn't recognize the type of challenge`,
+ description: "Contact the provider for further information",
+ },
+ ]}
+ />
);
+ default:
+ return <div />;
}
}
@@ -110,8 +160,16 @@ export function SolveScreen(): VNode {
return (
<AnastasisClientFrame hideNav title="Recovery problem">
<div>invalid state</div>
- <div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
- <button class="button" onClick={() => reducer.back()}>Back</button>
+ <div
+ style={{
+ marginTop: "2em",
+ display: "flex",
+ justifyContent: "space-between",
+ }}
+ >
+ <button class="button" onClick={() => reducer.back()}>
+ Back
+ </button>
</div>
</AnastasisClientFrame>
);
@@ -120,26 +178,36 @@ export function SolveScreen(): VNode {
return (
<AnastasisClientFrame hideNav title="Not implemented">
<p>
- The challenge selected is not supported for this UI. Please update this
- version or try using another policy.
+ The challenge selected is not supported for this UI. Please update
+ this version or try using another policy.
</p>
- {reducer &&
- <div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
- <button class="button" onClick={() => reducer.back()}>Back</button>
+ {reducer && (
+ <div
+ style={{
+ marginTop: "2em",
+ display: "flex",
+ justifyContent: "space-between",
+ }}
+ >
+ <button class="button" onClick={() => reducer.back()}>
+ Back
+ </button>
</div>
- }
+ )}
</AnastasisClientFrame>
);
}
-
const chArr = reducer.currentReducerState.recovery_information.challenges;
const selectedUuid = reducer.currentReducerState.selected_challenge_uuid;
- const selectedChallenge = chArr.find(ch => ch.uuid === selectedUuid)
+ const selectedChallenge = chArr.find((ch) => ch.uuid === selectedUuid);
- const SolveDialog = !selectedChallenge || !authMethods[selectedChallenge.type as KnownAuthMethods] ?
- SolveNotImplemented :
- authMethods[selectedChallenge.type as KnownAuthMethods].solve ?? SolveNotImplemented
+ const SolveDialog =
+ !selectedChallenge ||
+ !authMethods[selectedChallenge.type as KnownAuthMethods]
+ ? SolveNotImplemented
+ : authMethods[selectedChallenge.type as KnownAuthMethods].solve ??
+ SolveNotImplemented;
- return <SolveDialog id={selectedUuid} />
+ return <SolveDialog id={selectedUuid} />;
}
diff --git a/packages/anastasis-webui/src/pages/home/StartScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/StartScreen.stories.tsx
index 41082c128..fcddaf87a 100644
--- a/packages/anastasis-webui/src/pages/home/StartScreen.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/StartScreen.stories.tsx
@@ -15,24 +15,26 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { createExample, reducerStatesExample } from '../../utils';
-import { StartScreen as TestedComponent } from './StartScreen';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { createExample, reducerStatesExample } from "../../utils";
+import { StartScreen as TestedComponent } from "./StartScreen";
export default {
- title: 'Pages/Start',
+ title: "Pages/Start",
component: TestedComponent,
args: {
order: 1,
},
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
-export const InitialState = createExample(TestedComponent, reducerStatesExample.initial); \ No newline at end of file
+export const InitialState = createExample(
+ TestedComponent,
+ reducerStatesExample.initial,
+);
diff --git a/packages/anastasis-webui/src/pages/home/StartScreen.tsx b/packages/anastasis-webui/src/pages/home/StartScreen.tsx
index d53df4cae..8b24ef684 100644
--- a/packages/anastasis-webui/src/pages/home/StartScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/StartScreen.tsx
@@ -1,27 +1,36 @@
-
import { h, VNode } from "preact";
import { useAnastasisContext } from "../../context/anastasis";
import { AnastasisClientFrame } from "./index";
export function StartScreen(): VNode {
- const reducer = useAnastasisContext()
+ const reducer = useAnastasisContext();
if (!reducer) {
- return <div>no reducer in context</div>
+ return <div>no reducer in context</div>;
}
return (
<AnastasisClientFrame hideNav title="Home">
<div class="columns">
<div class="column" />
<div class="column is-four-fifths">
-
<div class="buttons">
- <button class="button is-success" autoFocus onClick={() => reducer.startBackup()}>
- <div class="icon"><i class="mdi mdi-arrow-up" /></div>
+ <button
+ class="button is-success"
+ autoFocus
+ onClick={() => reducer.startBackup()}
+ >
+ <div class="icon">
+ <i class="mdi mdi-arrow-up" />
+ </div>
<span>Backup a secret</span>
</button>
- <button class="button is-info" onClick={() => reducer.startRecover()}>
- <div class="icon"><i class="mdi mdi-arrow-down" /></div>
+ <button
+ class="button is-info"
+ onClick={() => reducer.startRecover()}
+ >
+ <div class="icon">
+ <i class="mdi mdi-arrow-down" />
+ </div>
<span>Recover a secret</span>
</button>
@@ -30,7 +39,6 @@ export function StartScreen(): VNode {
<span>Restore a session</span>
</button> */}
</div>
-
</div>
<div class="column" />
</div>
diff --git a/packages/anastasis-webui/src/pages/home/TruthsPayingScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/TruthsPayingScreen.stories.tsx
index 38b71bc36..245ad8889 100644
--- a/packages/anastasis-webui/src/pages/home/TruthsPayingScreen.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/TruthsPayingScreen.stories.tsx
@@ -15,29 +15,31 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { ReducerState } from 'anastasis-core';
-import { createExample, reducerStatesExample } from '../../utils';
-import { TruthsPayingScreen as TestedComponent } from './TruthsPayingScreen';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { ReducerState } from "anastasis-core";
+import { createExample, reducerStatesExample } from "../../utils";
+import { TruthsPayingScreen as TestedComponent } from "./TruthsPayingScreen";
export default {
- title: 'Pages/backup/__TruthsPaying',
+ title: "Pages/backup/__TruthsPaying",
component: TestedComponent,
args: {
order: 10,
},
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
-export const Example = createExample(TestedComponent, reducerStatesExample.truthsPaying);
+export const Example = createExample(
+ TestedComponent,
+ reducerStatesExample.truthsPaying,
+);
export const WithPaytoList = createExample(TestedComponent, {
...reducerStatesExample.truthsPaying,
- payments: ['payto://x-taler-bank/bank/account']
+ payments: ["payto://x-taler-bank/bank/account"],
} as ReducerState);
diff --git a/packages/anastasis-webui/src/pages/home/TruthsPayingScreen.tsx b/packages/anastasis-webui/src/pages/home/TruthsPayingScreen.tsx
index 0b32e0db5..6f95fa93b 100644
--- a/packages/anastasis-webui/src/pages/home/TruthsPayingScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/TruthsPayingScreen.tsx
@@ -3,19 +3,19 @@ import { useAnastasisContext } from "../../context/anastasis";
import { AnastasisClientFrame } from "./index";
export function TruthsPayingScreen(): VNode {
- const reducer = useAnastasisContext()
+ const reducer = useAnastasisContext();
if (!reducer) {
- return <div>no reducer in context</div>
+ return <div>no reducer in context</div>;
}
- if (!reducer.currentReducerState || reducer.currentReducerState.backup_state === undefined) {
- return <div>invalid state</div>
+ if (
+ !reducer.currentReducerState ||
+ reducer.currentReducerState.backup_state === undefined
+ ) {
+ return <div>invalid state</div>;
}
const payments = reducer.currentReducerState.payments ?? [];
return (
- <AnastasisClientFrame
- hideNext={"FIXME"}
- title="Backup: Truths Paying"
- >
+ <AnastasisClientFrame hideNext={"FIXME"} title="Backup: Truths Paying">
<p>
Some of the providers require a payment to store the encrypted
authentication information.
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSetup.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSetup.stories.tsx
index da87b7a8b..080a7ab31 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSetup.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSetup.stories.tsx
@@ -15,51 +15,67 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { createExample, reducerStatesExample } from '../../../utils';
-import { authMethods as TestedComponent, KnownAuthMethods } from './index';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { createExample, reducerStatesExample } from "../../../utils";
+import { authMethods as TestedComponent, KnownAuthMethods } from "./index";
export default {
- title: 'Pages/backup/AuthorizationMethod/AuthMethods/email',
+ title: "Pages/backup/AuthorizationMethod/AuthMethods/email",
component: TestedComponent,
args: {
order: 5,
},
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
-const type: KnownAuthMethods = 'email'
+const type: KnownAuthMethods = "email";
-export const Empty = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, {
- configured: []
-});
+export const Empty = createExample(
+ TestedComponent[type].setup,
+ reducerStatesExample.authEditing,
+ {
+ configured: [],
+ },
+);
-export const WithOneExample = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, {
- configured: [{
- challenge: 'qwe',
- type,
- instructions: 'Email to sebasjm@email.com ',
- remove: () => null
- }]
-});
+export const WithOneExample = createExample(
+ TestedComponent[type].setup,
+ reducerStatesExample.authEditing,
+ {
+ configured: [
+ {
+ challenge: "qwe",
+ type,
+ instructions: "Email to sebasjm@email.com ",
+ remove: () => null,
+ },
+ ],
+ },
+);
-export const WithMoreExamples = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, {
- configured: [{
- challenge: 'qwe',
- type,
- instructions: 'Email to sebasjm@email.com',
- remove: () => null
- },{
- challenge: 'qwe',
- type,
- instructions: 'Email to someone@sebasjm.com',
- remove: () => null
- }]
-});
+export const WithMoreExamples = createExample(
+ TestedComponent[type].setup,
+ reducerStatesExample.authEditing,
+ {
+ configured: [
+ {
+ challenge: "qwe",
+ type,
+ instructions: "Email to sebasjm@email.com",
+ remove: () => null,
+ },
+ {
+ challenge: "qwe",
+ type,
+ instructions: "Email to someone@sebasjm.com",
+ remove: () => null,
+ },
+ ],
+ },
+);
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSetup.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSetup.tsx
index 27a0685b2..61c66c8c8 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSetup.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSetup.tsx
@@ -1,57 +1,90 @@
-import {
- encodeCrock,
- stringToBytes
-} from "@gnu-taler/taler-util";
+import { encodeCrock, stringToBytes } from "@gnu-taler/taler-util";
import { h, VNode } from "preact";
import { useState } from "preact/hooks";
import { EmailInput } from "../../../components/fields/EmailInput";
import { AnastasisClientFrame } from "../index";
import { AuthMethodSetupProps } from "./index";
-const EMAIL_PATTERN = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
+const EMAIL_PATTERN = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
-export function AuthMethodEmailSetup({ cancel, addAuthMethod, configured }: AuthMethodSetupProps): VNode {
+export function AuthMethodEmailSetup({
+ cancel,
+ addAuthMethod,
+ configured,
+}: AuthMethodSetupProps): VNode {
const [email, setEmail] = useState("");
- const addEmailAuth = (): void => addAuthMethod({
- authentication_method: {
- type: "email",
- instructions: `Email to ${email}`,
- challenge: encodeCrock(stringToBytes(email)),
- },
- });
- const emailError = !EMAIL_PATTERN.test(email) ? 'Email address is not valid' : undefined
- const errors = !email ? 'Add your email' : emailError
+ const addEmailAuth = (): void =>
+ addAuthMethod({
+ authentication_method: {
+ type: "email",
+ instructions: `Email to ${email}`,
+ challenge: encodeCrock(stringToBytes(email)),
+ },
+ });
+ const emailError = !EMAIL_PATTERN.test(email)
+ ? "Email address is not valid"
+ : undefined;
+ const errors = !email ? "Add your email" : emailError;
return (
<AnastasisClientFrame hideNav title="Add email authentication">
<p>
For email authentication, you need to provide an email address. When
recovering your secret, you will need to enter the code you receive by
- email.
+ email. Add the uuid from the challenge
</p>
<div>
<EmailInput
label="Email address"
error={emailError}
placeholder="email@domain.com"
- bind={[email, setEmail]} />
+ bind={[email, setEmail]}
+ />
</div>
- {configured.length > 0 && <section class="section">
- <div class="block">
- Your emails:
- </div><div class="block">
- {configured.map((c, i) => {
- return <div key={i} class="box" style={{ display: 'flex', justifyContent: 'space-between' }}>
- <p style={{ marginBottom: 'auto', marginTop: 'auto' }}>{c.instructions}</p>
- <div><button class="button is-danger" onClick={c.remove} >Delete</button></div>
- </div>
- })}
- </div></section>}
+ {configured.length > 0 && (
+ <section class="section">
+ <div class="block">Your emails:</div>
+ <div class="block">
+ {configured.map((c, i) => {
+ return (
+ <div
+ key={i}
+ class="box"
+ style={{ display: "flex", justifyContent: "space-between" }}
+ >
+ <p style={{ marginBottom: "auto", marginTop: "auto" }}>
+ {c.instructions}
+ </p>
+ <div>
+ <button class="button is-danger" onClick={c.remove}>
+ Delete
+ </button>
+ </div>
+ </div>
+ );
+ })}
+ </div>
+ </section>
+ )}
<div>
- <div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
- <button class="button" onClick={cancel}>Cancel</button>
+ <div
+ style={{
+ marginTop: "2em",
+ display: "flex",
+ justifyContent: "space-between",
+ }}
+ >
+ <button class="button" onClick={cancel}>
+ Cancel
+ </button>
<span data-tooltip={errors}>
- <button class="button is-info" disabled={errors !== undefined} onClick={addEmailAuth}>Add</button>
+ <button
+ class="button is-info"
+ disabled={errors !== undefined}
+ onClick={addEmailAuth}
+ >
+ Add
+ </button>
</span>
</div>
</div>
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.stories.tsx
index 525cd2b07..6a8a2a347 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.stories.tsx
@@ -15,66 +15,76 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { ChallengeFeedbackStatus, ReducerState } from 'anastasis-core';
-import { createExample, reducerStatesExample } from '../../../utils';
-import { authMethods as TestedComponent, KnownAuthMethods } from './index';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { ChallengeFeedbackStatus, ReducerState } from "anastasis-core";
+import { createExample, reducerStatesExample } from "../../../utils";
+import { authMethods as TestedComponent, KnownAuthMethods } from "./index";
export default {
- title: 'Pages/recovery/SolveChallenge/AuthMethods/email',
+ title: "Pages/recovery/SolveChallenge/AuthMethods/email",
component: TestedComponent,
args: {
order: 5,
},
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
-const type: KnownAuthMethods = 'email'
+const type: KnownAuthMethods = "email";
-export const WithoutFeedback = createExample(TestedComponent[type].solve, {
- ...reducerStatesExample.challengeSolving,
- recovery_information: {
- challenges: [{
- cost: 'USD:1',
- instructions: 'does P equals NP?',
- type: 'question',
- uuid: 'uuid-1'
- }],
- policies: [],
+export const WithoutFeedback = createExample(
+ TestedComponent[type].solve,
+ {
+ ...reducerStatesExample.challengeSolving,
+ recovery_information: {
+ challenges: [
+ {
+ cost: "USD:1",
+ instructions: "does P equals NP?",
+ type: "question",
+ uuid: "uuid-1",
+ },
+ ],
+ policies: [],
+ },
+ selected_challenge_uuid: "uuid-1",
+ } as ReducerState,
+ {
+ id: "uuid-1",
},
- selected_challenge_uuid: 'uuid-1',
-} as ReducerState, {
- id: 'uuid-1',
-});
+);
-export const PaymentFeedback = createExample(TestedComponent[type].solve, {
- ...reducerStatesExample.challengeSolving,
- recovery_information: {
- challenges: [{
- cost: 'USD:1',
- instructions: 'does P equals NP?',
- type: 'question',
- uuid: 'uuid-1'
- }],
- policies: [],
+export const PaymentFeedback = createExample(
+ TestedComponent[type].solve,
+ {
+ ...reducerStatesExample.challengeSolving,
+ recovery_information: {
+ challenges: [
+ {
+ cost: "USD:1",
+ instructions: "does P equals NP?",
+ type: "question",
+ uuid: "uuid-1",
+ },
+ ],
+ policies: [],
+ },
+ selected_challenge_uuid: "uuid-1",
+ challenge_feedback: {
+ "uuid-1": {
+ state: ChallengeFeedbackStatus.Payment,
+ taler_pay_uri: "taler://pay/...",
+ provider: "https://localhost:8080/",
+ payment_secret: "3P4561HAMHRRYEYD6CM6J7TS5VTD5SR2K2EXJDZEFSX92XKHR4KG",
+ },
+ },
+ } as ReducerState,
+ {
+ id: "uuid-1",
},
- selected_challenge_uuid: 'uuid-1',
- challenge_feedback: {
- 'uuid-1': {
- state: ChallengeFeedbackStatus.Payment,
- taler_pay_uri: "taler://pay/...",
- provider: "https://localhost:8080/",
- payment_secret: "3P4561HAMHRRYEYD6CM6J7TS5VTD5SR2K2EXJDZEFSX92XKHR4KG"
- }
- }
-} as ReducerState, {
- id: 'uuid-1',
-});
-
+);
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.tsx
index bd4f43740..ff6c51d1c 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.tsx
@@ -44,8 +44,16 @@ export function AuthMethodEmailSolve({ id }: AuthMethodSolveProps): VNode {
return (
<AnastasisClientFrame hideNav title="Recovery problem">
<div>invalid state</div>
- <div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
- <button class="button" onClick={() => reducer.back()}>Back</button>
+ <div
+ style={{
+ marginTop: "2em",
+ display: "flex",
+ justifyContent: "space-between",
+ }}
+ >
+ <button class="button" onClick={() => reducer.back()}>
+ Back
+ </button>
</div>
</AnastasisClientFrame>
);
@@ -62,8 +70,7 @@ export function AuthMethodEmailSolve({ id }: AuthMethodSolveProps): VNode {
challenges[ch.uuid] = ch;
}
const selectedChallenge = challenges[selectedUuid];
- const feedback = challengeFeedback[selectedUuid]
-
+ const feedback = challengeFeedback[selectedUuid];
async function onNext(): Promise<void> {
return reducer?.transition("solve_challenge", { answer });
@@ -72,18 +79,19 @@ export function AuthMethodEmailSolve({ id }: AuthMethodSolveProps): VNode {
reducer?.back();
}
-
- const shouldHideConfirm = feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded
- || feedback?.state === ChallengeFeedbackStatus.Redirect
- || feedback?.state === ChallengeFeedbackStatus.Unsupported
- || feedback?.state === ChallengeFeedbackStatus.TruthUnknown
+ const shouldHideConfirm =
+ feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded ||
+ feedback?.state === ChallengeFeedbackStatus.Redirect ||
+ feedback?.state === ChallengeFeedbackStatus.Unsupported ||
+ feedback?.state === ChallengeFeedbackStatus.TruthUnknown;
return (
<AnastasisClientFrame hideNav title="Add email authentication">
<SolveOverviewFeedbackDisplay feedback={feedback} />
<p>
- An email has been sent to "<b>{selectedChallenge.instructions}</b>". Type the
- code below
+ An email has been sent to "<b>{selectedChallenge.instructions}</b>".
+ Type the code below.
+ <b>Here we need to add the code "{selectedUuid}"</b>
</p>
<TextInput label="Answer" grabFocus bind={[answer, setAnswer]} />
@@ -97,9 +105,11 @@ export function AuthMethodEmailSolve({ id }: AuthMethodSolveProps): VNode {
<button class="button" onClick={onCancel}>
Cancel
</button>
- {!shouldHideConfirm && <AsyncButton class="button is-info" onClick={onNext}>
- Confirm
- </AsyncButton>}
+ {!shouldHideConfirm && (
+ <AsyncButton class="button is-info" onClick={onNext}>
+ Confirm
+ </AsyncButton>
+ )}
</div>
</AnastasisClientFrame>
);
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSetup.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSetup.stories.tsx
index be0a04847..c521e18fd 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSetup.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSetup.stories.tsx
@@ -15,50 +15,66 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { createExample, reducerStatesExample } from '../../../utils';
-import { authMethods as TestedComponent, KnownAuthMethods } from './index';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { createExample, reducerStatesExample } from "../../../utils";
+import { authMethods as TestedComponent, KnownAuthMethods } from "./index";
export default {
- title: 'Pages/backup/AuthorizationMethod/AuthMethods/IBAN',
+ title: "Pages/backup/AuthorizationMethod/AuthMethods/IBAN",
component: TestedComponent,
args: {
order: 5,
},
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
-const type: KnownAuthMethods = 'iban'
+const type: KnownAuthMethods = "iban";
-export const Empty = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, {
- configured: []
-});
+export const Empty = createExample(
+ TestedComponent[type].setup,
+ reducerStatesExample.authEditing,
+ {
+ configured: [],
+ },
+);
-export const WithOneExample = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, {
- configured: [{
- challenge: 'qwe',
- type,
- instructions: 'Wire transfer from QWEASD123123 with holder Sebastian',
- remove: () => null
- }]
-});
-export const WithMoreExamples = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, {
- configured: [{
- challenge: 'qwe',
- type,
- instructions: 'Wire transfer from QWEASD123123 with holder Javier',
- remove: () => null
- },{
- challenge: 'qwe',
- type,
- instructions: 'Wire transfer from QWEASD123123 with holder Sebastian',
- remove: () => null
- }]
-},);
+export const WithOneExample = createExample(
+ TestedComponent[type].setup,
+ reducerStatesExample.authEditing,
+ {
+ configured: [
+ {
+ challenge: "qwe",
+ type,
+ instructions: "Wire transfer from QWEASD123123 with holder Sebastian",
+ remove: () => null,
+ },
+ ],
+ },
+);
+export const WithMoreExamples = createExample(
+ TestedComponent[type].setup,
+ reducerStatesExample.authEditing,
+ {
+ configured: [
+ {
+ challenge: "qwe",
+ type,
+ instructions: "Wire transfer from QWEASD123123 with holder Javier",
+ remove: () => null,
+ },
+ {
+ challenge: "qwe",
+ type,
+ instructions: "Wire transfer from QWEASD123123 with holder Sebastian",
+ remove: () => null,
+ },
+ ],
+ },
+);
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSetup.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSetup.tsx
index 87969ab27..dee550e5b 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSetup.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSetup.tsx
@@ -1,7 +1,7 @@
import {
canonicalJson,
encodeCrock,
- stringToBytes
+ stringToBytes,
} from "@gnu-taler/taler-util";
import { h, VNode } from "preact";
import { useState } from "preact/hooks";
@@ -9,56 +9,98 @@ import { AuthMethodSetupProps } from ".";
import { TextInput } from "../../../components/fields/TextInput";
import { AnastasisClientFrame } from "../index";
-export function AuthMethodIbanSetup({ addAuthMethod, cancel, configured }: AuthMethodSetupProps): VNode {
+export function AuthMethodIbanSetup({
+ addAuthMethod,
+ cancel,
+ configured,
+}: AuthMethodSetupProps): VNode {
const [name, setName] = useState("");
const [account, setAccount] = useState("");
- const addIbanAuth = (): void => addAuthMethod({
- authentication_method: {
- type: "iban",
- instructions: `Wire transfer from ${account} with holder ${name}`,
- challenge: encodeCrock(stringToBytes(canonicalJson({
- name, account
- }))),
- },
- });
- const errors = !name ? 'Add an account name' : (
- !account ? 'Add an account IBAN number' : undefined
- )
+ const addIbanAuth = (): void =>
+ addAuthMethod({
+ authentication_method: {
+ type: "iban",
+ instructions: `Wire transfer from ${account} with holder ${name}`,
+ challenge: encodeCrock(
+ stringToBytes(
+ canonicalJson({
+ name,
+ account,
+ }),
+ ),
+ ),
+ },
+ });
+ const errors = !name
+ ? "Add an account name"
+ : !account
+ ? "Add an account IBAN number"
+ : undefined;
return (
<AnastasisClientFrame hideNav title="Add bank transfer authentication">
<p>
- For bank transfer authentication, you need to provide a bank
- account (account holder name and IBAN). When recovering your
- secret, you will be asked to pay the recovery fee via bank
- transfer from the account you provided here.
+ For bank transfer authentication, you need to provide a bank account
+ (account holder name and IBAN). When recovering your secret, you will be
+ asked to pay the recovery fee via bank transfer from the account you
+ provided here.
</p>
<div>
<TextInput
label="Bank account holder name"
grabFocus
placeholder="John Smith"
- bind={[name, setName]} />
+ bind={[name, setName]}
+ />
<TextInput
label="IBAN"
placeholder="DE91100000000123456789"
- bind={[account, setAccount]} />
+ bind={[account, setAccount]}
+ />
</div>
- {configured.length > 0 && <section class="section">
- <div class="block">
- Your bank accounts:
- </div><div class="block">
- {configured.map((c, i) => {
- return <div key={i} class="box" style={{ display: 'flex', justifyContent: 'space-between' }}>
- <p style={{ marginBottom: 'auto', marginTop: 'auto' }}>{c.instructions}</p>
- <div><button class="button is-danger" onClick={c.remove} >Delete</button></div>
- </div>
- })}
- </div></section>}
+ {configured.length > 0 && (
+ <section class="section">
+ <div class="block">Your bank accounts:</div>
+ <div class="block">
+ {configured.map((c, i) => {
+ return (
+ <div
+ key={i}
+ class="box"
+ style={{ display: "flex", justifyContent: "space-between" }}
+ >
+ <p style={{ marginBottom: "auto", marginTop: "auto" }}>
+ {c.instructions}
+ </p>
+ <div>
+ <button class="button is-danger" onClick={c.remove}>
+ Delete
+ </button>
+ </div>
+ </div>
+ );
+ })}
+ </div>
+ </section>
+ )}
<div>
- <div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
- <button class="button" onClick={cancel}>Cancel</button>
+ <div
+ style={{
+ marginTop: "2em",
+ display: "flex",
+ justifyContent: "space-between",
+ }}
+ >
+ <button class="button" onClick={cancel}>
+ Cancel
+ </button>
<span data-tooltip={errors}>
- <button class="button is-info" disabled={errors !== undefined} onClick={addIbanAuth}>Add</button>
+ <button
+ class="button is-info"
+ disabled={errors !== undefined}
+ onClick={addIbanAuth}
+ >
+ Add
+ </button>
</span>
</div>
</div>
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSolve.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSolve.stories.tsx
index df73a9214..cbbc253e9 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSolve.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSolve.stories.tsx
@@ -15,42 +15,46 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { ChallengeFeedbackStatus, ReducerState } from 'anastasis-core';
-import { createExample, reducerStatesExample } from '../../../utils';
-import { authMethods as TestedComponent, KnownAuthMethods } from './index';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { ChallengeFeedbackStatus, ReducerState } from "anastasis-core";
+import { createExample, reducerStatesExample } from "../../../utils";
+import { authMethods as TestedComponent, KnownAuthMethods } from "./index";
export default {
- title: 'Pages/recovery/SolveChallenge/AuthMethods/Iban',
+ title: "Pages/recovery/SolveChallenge/AuthMethods/Iban",
component: TestedComponent,
args: {
order: 5,
},
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
-const type: KnownAuthMethods = 'iban'
-
-export const WithoutFeedback = createExample(TestedComponent[type].solve, {
- ...reducerStatesExample.challengeSolving,
- recovery_information: {
- challenges: [{
- cost: 'USD:1',
- instructions: 'does P equals NP?',
- type: 'question',
- uuid: 'uuid-1'
- }],
- policies: [],
+const type: KnownAuthMethods = "iban";
+
+export const WithoutFeedback = createExample(
+ TestedComponent[type].solve,
+ {
+ ...reducerStatesExample.challengeSolving,
+ recovery_information: {
+ challenges: [
+ {
+ cost: "USD:1",
+ instructions: "does P equals NP?",
+ type: "question",
+ uuid: "uuid-1",
+ },
+ ],
+ policies: [],
+ },
+ selected_challenge_uuid: "uuid-1",
+ } as ReducerState,
+ {
+ id: "uuid-1",
},
- selected_challenge_uuid: 'uuid-1',
-} as ReducerState, {
- id: 'uuid-1',
-});
-
+);
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSolve.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSolve.tsx
index 1e4353da6..46cf0502c 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSolve.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSolve.tsx
@@ -44,8 +44,16 @@ export function AuthMethodIbanSolve({ id }: AuthMethodSolveProps): VNode {
return (
<AnastasisClientFrame hideNav title="Recovery problem">
<div>invalid state</div>
- <div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
- <button class="button" onClick={() => reducer.back()}>Back</button>
+ <div
+ style={{
+ marginTop: "2em",
+ display: "flex",
+ justifyContent: "space-between",
+ }}
+ >
+ <button class="button" onClick={() => reducer.back()}>
+ Back
+ </button>
</div>
</AnastasisClientFrame>
);
@@ -62,8 +70,7 @@ export function AuthMethodIbanSolve({ id }: AuthMethodSolveProps): VNode {
challenges[ch.uuid] = ch;
}
const selectedChallenge = challenges[selectedUuid];
- const feedback = challengeFeedback[selectedUuid]
-
+ const feedback = challengeFeedback[selectedUuid];
async function onNext(): Promise<void> {
return reducer?.transition("solve_challenge", { answer });
@@ -72,19 +79,17 @@ export function AuthMethodIbanSolve({ id }: AuthMethodSolveProps): VNode {
reducer?.back();
}
-
- const shouldHideConfirm = feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded
- || feedback?.state === ChallengeFeedbackStatus.Redirect
- || feedback?.state === ChallengeFeedbackStatus.Unsupported
- || feedback?.state === ChallengeFeedbackStatus.TruthUnknown
+ const shouldHideConfirm =
+ feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded ||
+ feedback?.state === ChallengeFeedbackStatus.Redirect ||
+ feedback?.state === ChallengeFeedbackStatus.Unsupported ||
+ feedback?.state === ChallengeFeedbackStatus.TruthUnknown;
return (
<AnastasisClientFrame hideNav title="Add email authentication">
<SolveOverviewFeedbackDisplay feedback={feedback} />
- <p>
- Send a wire transfer to the address
- </p>
- <TextInput label="Answer" grabFocus bind={[answer, setAnswer]} />
+ <p>Send a wire transfer to the address,</p>
+ <button class="button">Check</button>
<div
style={{
@@ -96,9 +101,11 @@ export function AuthMethodIbanSolve({ id }: AuthMethodSolveProps): VNode {
<button class="button" onClick={onCancel}>
Cancel
</button>
- {!shouldHideConfirm && <AsyncButton class="button is-info" onClick={onNext}>
- Confirm
- </AsyncButton>}
+ {!shouldHideConfirm && (
+ <AsyncButton class="button is-info" onClick={onNext}>
+ Confirm
+ </AsyncButton>
+ )}
</div>
</AnastasisClientFrame>
);
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSetup.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSetup.stories.tsx
index adc83d6fe..2977586ac 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSetup.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSetup.stories.tsx
@@ -16,51 +16,67 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { createExample, reducerStatesExample } from '../../../utils';
-import { authMethods as TestedComponent, KnownAuthMethods } from './index';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { createExample, reducerStatesExample } from "../../../utils";
+import { authMethods as TestedComponent, KnownAuthMethods } from "./index";
export default {
- title: 'Pages/backup/AuthorizationMethod/AuthMethods/Post',
+ title: "Pages/backup/AuthorizationMethod/AuthMethods/Post",
component: TestedComponent,
args: {
order: 5,
},
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
-const type: KnownAuthMethods = 'post'
+const type: KnownAuthMethods = "post";
-export const Empty = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, {
- configured: []
-});
+export const Empty = createExample(
+ TestedComponent[type].setup,
+ reducerStatesExample.authEditing,
+ {
+ configured: [],
+ },
+);
-export const WithOneExample = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, {
- configured: [{
- challenge: 'qwe',
- type,
- instructions: 'Letter to address in postal code QWE456',
- remove: () => null
- }]
-});
+export const WithOneExample = createExample(
+ TestedComponent[type].setup,
+ reducerStatesExample.authEditing,
+ {
+ configured: [
+ {
+ challenge: "qwe",
+ type,
+ instructions: "Letter to address in postal code QWE456",
+ remove: () => null,
+ },
+ ],
+ },
+);
-export const WithMoreExamples = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, {
- configured: [{
- challenge: 'qwe',
- type,
- instructions: 'Letter to address in postal code QWE456',
- remove: () => null
- },{
- challenge: 'qwe',
- type,
- instructions: 'Letter to address in postal code ABC123',
- remove: () => null
- }]
-});
+export const WithMoreExamples = createExample(
+ TestedComponent[type].setup,
+ reducerStatesExample.authEditing,
+ {
+ configured: [
+ {
+ challenge: "qwe",
+ type,
+ instructions: "Letter to address in postal code QWE456",
+ remove: () => null,
+ },
+ {
+ challenge: "qwe",
+ type,
+ instructions: "Letter to address in postal code ABC123",
+ remove: () => null,
+ },
+ ],
+ },
+);
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSetup.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSetup.tsx
index 692421d74..6c8d36bcf 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSetup.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSetup.tsx
@@ -1,6 +1,7 @@
import {
- canonicalJson, encodeCrock,
- stringToBytes
+ canonicalJson,
+ encodeCrock,
+ stringToBytes,
} from "@gnu-taler/taler-util";
import { h, VNode } from "preact";
import { useState } from "preact/hooks";
@@ -8,7 +9,11 @@ import { AnastasisClientFrame } from "..";
import { TextInput } from "../../../components/fields/TextInput";
import { AuthMethodSetupProps } from "./index";
-export function AuthMethodPostSetup({ addAuthMethod, cancel, configured }: AuthMethodSetupProps): VNode {
+export function AuthMethodPostSetup({
+ addAuthMethod,
+ cancel,
+ configured,
+}: AuthMethodSetupProps): VNode {
const [fullName, setFullName] = useState("");
const [street, setStreet] = useState("");
const [city, setCity] = useState("");
@@ -32,68 +37,83 @@ export function AuthMethodPostSetup({ addAuthMethod, cancel, configured }: AuthM
});
};
- const errors = !fullName ? 'The full name is missing' : (
- !street ? 'The street is missing' : (
- !city ? 'The city is missing' : (
- !postcode ? 'The postcode is missing' : (
- !country ? 'The country is missing' : undefined
- )
- )
- )
- )
+ const errors = !fullName
+ ? "The full name is missing"
+ : !street
+ ? "The street is missing"
+ : !city
+ ? "The city is missing"
+ : !postcode
+ ? "The postcode is missing"
+ : !country
+ ? "The country is missing"
+ : undefined;
return (
<AnastasisClientFrame hideNav title="Add postal authentication">
<p>
- For postal letter authentication, you need to provide a postal
- address. When recovering your secret, you will be asked to enter a
- code that you will receive in a letter to that address.
+ For postal letter authentication, you need to provide a postal address.
+ When recovering your secret, you will be asked to enter a code that you
+ will receive in a letter to that address.
</p>
<div>
- <TextInput
- grabFocus
- label="Full Name"
- bind={[fullName, setFullName]}
- />
+ <TextInput grabFocus label="Full Name" bind={[fullName, setFullName]} />
</div>
<div>
- <TextInput
- label="Street"
- bind={[street, setStreet]}
- />
+ <TextInput label="Street" bind={[street, setStreet]} />
</div>
<div>
- <TextInput
- label="City" bind={[city, setCity]}
- />
+ <TextInput label="City" bind={[city, setCity]} />
</div>
<div>
- <TextInput
- label="Postal Code" bind={[postcode, setPostcode]}
- />
+ <TextInput label="Postal Code" bind={[postcode, setPostcode]} />
</div>
<div>
- <TextInput
- label="Country"
- bind={[country, setCountry]}
- />
+ <TextInput label="Country" bind={[country, setCountry]} />
</div>
- {configured.length > 0 && <section class="section">
- <div class="block">
- Your postal code:
- </div><div class="block">
- {configured.map((c, i) => {
- return <div key={i} class="box" style={{ display: 'flex', justifyContent: 'space-between' }}>
- <p style={{ marginBottom: 'auto', marginTop: 'auto' }}>{c.instructions}</p>
- <div><button class="button is-danger" onClick={c.remove} >Delete</button></div>
- </div>
- })}
- </div>
- </section>}
- <div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
- <button class="button" onClick={cancel}>Cancel</button>
+ {configured.length > 0 && (
+ <section class="section">
+ <div class="block">Your postal code:</div>
+ <div class="block">
+ {configured.map((c, i) => {
+ return (
+ <div
+ key={i}
+ class="box"
+ style={{ display: "flex", justifyContent: "space-between" }}
+ >
+ <p style={{ marginBottom: "auto", marginTop: "auto" }}>
+ {c.instructions}
+ </p>
+ <div>
+ <button class="button is-danger" onClick={c.remove}>
+ Delete
+ </button>
+ </div>
+ </div>
+ );
+ })}
+ </div>
+ </section>
+ )}
+ <div
+ style={{
+ marginTop: "2em",
+ display: "flex",
+ justifyContent: "space-between",
+ }}
+ >
+ <button class="button" onClick={cancel}>
+ Cancel
+ </button>
<span data-tooltip={errors}>
- <button class="button is-info" disabled={errors !== undefined} onClick={addPostAuth}>Add</button>
+ <button
+ class="button is-info"
+ disabled={errors !== undefined}
+ onClick={addPostAuth}
+ >
+ Add
+ </button>
</span>
</div>
</AnastasisClientFrame>
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.stories.tsx
index 99451090b..3b67ee884 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.stories.tsx
@@ -15,42 +15,46 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { ChallengeFeedbackStatus, ReducerState } from 'anastasis-core';
-import { createExample, reducerStatesExample } from '../../../utils';
-import { authMethods as TestedComponent, KnownAuthMethods } from './index';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { ChallengeFeedbackStatus, ReducerState } from "anastasis-core";
+import { createExample, reducerStatesExample } from "../../../utils";
+import { authMethods as TestedComponent, KnownAuthMethods } from "./index";
export default {
- title: 'Pages/recovery/SolveChallenge/AuthMethods/post',
+ title: "Pages/recovery/SolveChallenge/AuthMethods/post",
component: TestedComponent,
args: {
order: 5,
},
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
-const type: KnownAuthMethods = 'post'
-
-export const WithoutFeedback = createExample(TestedComponent[type].solve, {
- ...reducerStatesExample.challengeSolving,
- recovery_information: {
- challenges: [{
- cost: 'USD:1',
- instructions: 'does P equals NP?',
- type: 'question',
- uuid: 'uuid-1'
- }],
- policies: [],
+const type: KnownAuthMethods = "post";
+
+export const WithoutFeedback = createExample(
+ TestedComponent[type].solve,
+ {
+ ...reducerStatesExample.challengeSolving,
+ recovery_information: {
+ challenges: [
+ {
+ cost: "USD:1",
+ instructions: "does P equals NP?",
+ type: "question",
+ uuid: "uuid-1",
+ },
+ ],
+ policies: [],
+ },
+ selected_challenge_uuid: "uuid-1",
+ } as ReducerState,
+ {
+ id: "uuid-1",
},
- selected_challenge_uuid: 'uuid-1',
-} as ReducerState, {
- id: 'uuid-1',
-});
-
+);
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.tsx
index 7e3c45abe..ee001ebe9 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.tsx
@@ -44,8 +44,16 @@ export function AuthMethodPostSolve({ id }: AuthMethodSolveProps): VNode {
return (
<AnastasisClientFrame hideNav title="Recovery problem">
<div>invalid state</div>
- <div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
- <button class="button" onClick={() => reducer.back()}>Back</button>
+ <div
+ style={{
+ marginTop: "2em",
+ display: "flex",
+ justifyContent: "space-between",
+ }}
+ >
+ <button class="button" onClick={() => reducer.back()}>
+ Back
+ </button>
</div>
</AnastasisClientFrame>
);
@@ -62,8 +70,7 @@ export function AuthMethodPostSolve({ id }: AuthMethodSolveProps): VNode {
challenges[ch.uuid] = ch;
}
const selectedChallenge = challenges[selectedUuid];
- const feedback = challengeFeedback[selectedUuid]
-
+ const feedback = challengeFeedback[selectedUuid];
async function onNext(): Promise<void> {
return reducer?.transition("solve_challenge", { answer });
@@ -72,18 +79,16 @@ export function AuthMethodPostSolve({ id }: AuthMethodSolveProps): VNode {
reducer?.back();
}
-
- const shouldHideConfirm = feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded
- || feedback?.state === ChallengeFeedbackStatus.Redirect
- || feedback?.state === ChallengeFeedbackStatus.Unsupported
- || feedback?.state === ChallengeFeedbackStatus.TruthUnknown
+ const shouldHideConfirm =
+ feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded ||
+ feedback?.state === ChallengeFeedbackStatus.Redirect ||
+ feedback?.state === ChallengeFeedbackStatus.Unsupported ||
+ feedback?.state === ChallengeFeedbackStatus.TruthUnknown;
return (
<AnastasisClientFrame hideNav title="Add email authentication">
<SolveOverviewFeedbackDisplay feedback={feedback} />
- <p>
- Wait for the answer
- </p>
+ <p>Wait for the answer</p>
<TextInput label="Answer" grabFocus bind={[answer, setAnswer]} />
<div
@@ -96,9 +101,11 @@ export function AuthMethodPostSolve({ id }: AuthMethodSolveProps): VNode {
<button class="button" onClick={onCancel}>
Cancel
</button>
- {!shouldHideConfirm && <AsyncButton class="button is-info" onClick={onNext}>
- Confirm
- </AsyncButton>}
+ {!shouldHideConfirm && (
+ <AsyncButton class="button is-info" onClick={onNext}>
+ Confirm
+ </AsyncButton>
+ )}
</div>
</AnastasisClientFrame>
);
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSetup.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSetup.stories.tsx
index 0c3ee2b77..991301cbf 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSetup.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSetup.stories.tsx
@@ -16,51 +16,69 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { createExample, reducerStatesExample } from '../../../utils';
-import { authMethods as TestedComponent, KnownAuthMethods } from './index';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { createExample, reducerStatesExample } from "../../../utils";
+import { authMethods as TestedComponent, KnownAuthMethods } from "./index";
export default {
- title: 'Pages/backup/AuthorizationMethod/AuthMethods/Question',
+ title: "Pages/backup/AuthorizationMethod/AuthMethods/Question",
component: TestedComponent,
args: {
order: 5,
},
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
-const type: KnownAuthMethods = 'question'
+const type: KnownAuthMethods = "question";
-export const Empty = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, {
- configured: []
-});
+export const Empty = createExample(
+ TestedComponent[type].setup,
+ reducerStatesExample.authEditing,
+ {
+ configured: [],
+ },
+);
-export const WithOneExample = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, {
- configured: [{
- challenge: 'qwe',
- type,
- instructions: 'Is integer factorization polynomial? (non-quantum computer)',
- remove: () => null
- }]
-});
+export const WithOneExample = createExample(
+ TestedComponent[type].setup,
+ reducerStatesExample.authEditing,
+ {
+ configured: [
+ {
+ challenge: "qwe",
+ type,
+ instructions:
+ "Is integer factorization polynomial? (non-quantum computer)",
+ remove: () => null,
+ },
+ ],
+ },
+);
-export const WithMoreExamples = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, {
- configured: [{
- challenge: 'qwe',
- type,
- instructions: 'Does P equal NP?',
- remove: () => null
- },{
- challenge: 'asd',
- type,
- instructions: 'Are continuous groups automatically differential groups?',
- remove: () => null
- }]
-});
+export const WithMoreExamples = createExample(
+ TestedComponent[type].setup,
+ reducerStatesExample.authEditing,
+ {
+ configured: [
+ {
+ challenge: "qwe",
+ type,
+ instructions: "Does P equal NP?",
+ remove: () => null,
+ },
+ {
+ challenge: "asd",
+ type,
+ instructions:
+ "Are continuous groups automatically differential groups?",
+ remove: () => null,
+ },
+ ],
+ },
+);
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSetup.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSetup.tsx
index 780bfcb82..0a14021dd 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSetup.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSetup.tsx
@@ -1,27 +1,31 @@
-import {
- encodeCrock,
- stringToBytes
-} from "@gnu-taler/taler-util";
+import { encodeCrock, stringToBytes } from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact";
import { useState } from "preact/hooks";
import { AuthMethodSetupProps } from "./index";
import { AnastasisClientFrame } from "../index";
import { TextInput } from "../../../components/fields/TextInput";
-export function AuthMethodQuestionSetup({ cancel, addAuthMethod, configured }: AuthMethodSetupProps): VNode {
+export function AuthMethodQuestionSetup({
+ cancel,
+ addAuthMethod,
+ configured,
+}: AuthMethodSetupProps): VNode {
const [questionText, setQuestionText] = useState("");
const [answerText, setAnswerText] = useState("");
- const addQuestionAuth = (): void => addAuthMethod({
- authentication_method: {
- type: "question",
- instructions: questionText,
- challenge: encodeCrock(stringToBytes(answerText)),
- },
- });
+ const addQuestionAuth = (): void =>
+ addAuthMethod({
+ authentication_method: {
+ type: "question",
+ instructions: questionText,
+ challenge: encodeCrock(stringToBytes(answerText)),
+ },
+ });
- const errors = !questionText ? "Add your security question" : (
- !answerText ? 'Add the answer to your question' : undefined
- )
+ const errors = !questionText
+ ? "Add your security question"
+ : !answerText
+ ? "Add the answer to your question"
+ : undefined;
return (
<AnastasisClientFrame hideNav title="Add Security Question">
<div>
@@ -36,7 +40,8 @@ export function AuthMethodQuestionSetup({ cancel, addAuthMethod, configured }: A
label="Security question"
grabFocus
placeholder="Your question"
- bind={[questionText, setQuestionText]} />
+ bind={[questionText, setQuestionText]}
+ />
</div>
<div>
<TextInput
@@ -46,25 +51,53 @@ export function AuthMethodQuestionSetup({ cancel, addAuthMethod, configured }: A
/>
</div>
- <div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
- <button class="button" onClick={cancel}>Cancel</button>
+ <div
+ style={{
+ marginTop: "2em",
+ display: "flex",
+ justifyContent: "space-between",
+ }}
+ >
+ <button class="button" onClick={cancel}>
+ Cancel
+ </button>
<span data-tooltip={errors}>
- <button class="button is-info" disabled={errors !== undefined} onClick={addQuestionAuth}>Add</button>
+ <button
+ class="button is-info"
+ disabled={errors !== undefined}
+ onClick={addQuestionAuth}
+ >
+ Add
+ </button>
</span>
</div>
- {configured.length > 0 && <section class="section">
- <div class="block">
- Your security questions:
- </div><div class="block">
- {configured.map((c, i) => {
- return <div key={i} class="box" style={{ display: 'flex', justifyContent: 'space-between' }}>
- <p style={{ marginBottom: 'auto', marginTop: 'auto' }}>{c.instructions}</p>
- <div><button class="button is-danger" onClick={c.remove} >Delete</button></div>
- </div>
- })}
- </div></section>}
+ {configured.length > 0 && (
+ <section class="section">
+ <div class="block">Your security questions:</div>
+ <div class="block">
+ {configured.map((c, i) => {
+ return (
+ <div
+ key={i}
+ class="box"
+ style={{ display: "flex", justifyContent: "space-between" }}
+ >
+ <p style={{ marginBottom: "auto", marginTop: "auto" }}>
+ {c.instructions}
+ </p>
+ <div>
+ <button class="button is-danger" onClick={c.remove}>
+ Delete
+ </button>
+ </div>
+ </div>
+ );
+ })}
+ </div>
+ </section>
+ )}
</div>
- </AnastasisClientFrame >
+ </AnastasisClientFrame>
);
}
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.stories.tsx
index f0ec92d4d..1fa9fd6ec 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.stories.tsx
@@ -15,186 +15,205 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { ChallengeFeedbackStatus, ReducerState } from 'anastasis-core';
-import { createExample, reducerStatesExample } from '../../../utils';
-import { authMethods as TestedComponent, KnownAuthMethods } from './index';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { ChallengeFeedbackStatus, ReducerState } from "anastasis-core";
+import { createExample, reducerStatesExample } from "../../../utils";
+import { authMethods as TestedComponent, KnownAuthMethods } from "./index";
export default {
- title: 'Pages/recovery/SolveChallenge/AuthMethods/question',
+ title: "Pages/recovery/SolveChallenge/AuthMethods/question",
component: TestedComponent,
args: {
order: 5,
},
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
-const type: KnownAuthMethods = 'question'
+const type: KnownAuthMethods = "question";
-export const WithoutFeedback = createExample(TestedComponent[type].solve, {
- ...reducerStatesExample.challengeSolving,
- recovery_information: {
- challenges: [{
- cost: 'USD:1',
- instructions: 'does P equals NP?',
- type: 'question',
- uuid: 'uuid-1'
- }],
- policies: [],
+export const WithoutFeedback = createExample(
+ TestedComponent[type].solve,
+ {
+ ...reducerStatesExample.challengeSolving,
+ recovery_information: {
+ challenges: [
+ {
+ cost: "USD:1",
+ instructions: "does P equals NP?",
+ type: "question",
+ uuid: "uuid-1",
+ },
+ ],
+ policies: [],
+ },
+ selected_challenge_uuid: "uuid-1",
+ } as ReducerState,
+ {
+ id: "uuid-1",
},
- selected_challenge_uuid: 'uuid-1',
-} as ReducerState, {
- id: 'uuid-1',
-});
+);
export const MessageFeedback = createExample(TestedComponent[type].solve, {
...reducerStatesExample.challengeSolving,
recovery_information: {
- challenges: [{
- cost: 'USD:1',
- instructions: 'does P equals NP?',
- type: 'question',
- uuid: 'ASDASDSAD!1'
- }],
+ challenges: [
+ {
+ cost: "USD:1",
+ instructions: "does P equals NP?",
+ type: "question",
+ uuid: "ASDASDSAD!1",
+ },
+ ],
policies: [],
},
- selected_challenge_uuid: 'ASDASDSAD!1',
+ selected_challenge_uuid: "ASDASDSAD!1",
challenge_feedback: {
- 'ASDASDSAD!1': {
+ "ASDASDSAD!1": {
state: ChallengeFeedbackStatus.Message,
- message: 'Challenge should be solved'
- }
- }
-
-} as ReducerState);
-
-export const ServerFailureFeedback = createExample(TestedComponent[type].solve, {
- ...reducerStatesExample.challengeSolving,
- recovery_information: {
- challenges: [{
- cost: 'USD:1',
- instructions: 'does P equals NP?',
- type: 'question',
- uuid: 'ASDASDSAD!1'
- }],
- policies: [],
+ message: "Challenge should be solved",
+ },
},
- 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 ServerFailureFeedback = createExample(
+ TestedComponent[type].solve,
+ {
+ ...reducerStatesExample.challengeSolving,
+ recovery_information: {
+ challenges: [
+ {
+ cost: "USD:1",
+ instructions: "does P equals NP?",
+ type: "question",
+ uuid: "ASDASDSAD!1",
+ },
+ ],
+ policies: [],
+ },
+ 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 RedirectFeedback = createExample(TestedComponent[type].solve, {
...reducerStatesExample.challengeSolving,
recovery_information: {
- challenges: [{
- cost: 'USD:1',
- instructions: 'does P equals NP?',
- type: 'question',
- uuid: 'ASDASDSAD!1'
- }],
+ challenges: [
+ {
+ cost: "USD:1",
+ instructions: "does P equals NP?",
+ type: "question",
+ uuid: "ASDASDSAD!1",
+ },
+ ],
policies: [],
},
- selected_challenge_uuid: 'ASDASDSAD!1',
+ selected_challenge_uuid: "ASDASDSAD!1",
challenge_feedback: {
- 'ASDASDSAD!1': {
+ "ASDASDSAD!1": {
state: ChallengeFeedbackStatus.Redirect,
http_status: 302,
- redirect_url: 'http://video.taler.net'
- }
- }
-
-} as ReducerState);
-
-export const MessageRateLimitExceededFeedback = createExample(TestedComponent[type].solve, {
- ...reducerStatesExample.challengeSolving,
- recovery_information: {
- challenges: [{
- cost: 'USD:1',
- instructions: 'does P equals NP?',
- type: 'question',
- uuid: 'ASDASDSAD!1'
- }],
- policies: [],
+ redirect_url: "http://video.taler.net",
+ },
},
- selected_challenge_uuid: 'ASDASDSAD!1',
- challenge_feedback: {
- 'ASDASDSAD!1': {
- state: ChallengeFeedbackStatus.RateLimitExceeded,
- }
- }
-
} as ReducerState);
+export const MessageRateLimitExceededFeedback = createExample(
+ TestedComponent[type].solve,
+ {
+ ...reducerStatesExample.challengeSolving,
+ recovery_information: {
+ challenges: [
+ {
+ cost: "USD:1",
+ instructions: "does P equals NP?",
+ type: "question",
+ uuid: "ASDASDSAD!1",
+ },
+ ],
+ policies: [],
+ },
+ selected_challenge_uuid: "ASDASDSAD!1",
+ challenge_feedback: {
+ "ASDASDSAD!1": {
+ state: ChallengeFeedbackStatus.RateLimitExceeded,
+ },
+ },
+ } as ReducerState,
+);
+
export const UnsupportedFeedback = createExample(TestedComponent[type].solve, {
...reducerStatesExample.challengeSolving,
recovery_information: {
- challenges: [{
- cost: 'USD:1',
- instructions: 'does P equals NP?',
- type: 'question',
- uuid: 'ASDASDSAD!1'
- }],
+ challenges: [
+ {
+ cost: "USD:1",
+ instructions: "does P equals NP?",
+ type: "question",
+ uuid: "ASDASDSAD!1",
+ },
+ ],
policies: [],
},
- selected_challenge_uuid: 'ASDASDSAD!1',
+ selected_challenge_uuid: "ASDASDSAD!1",
challenge_feedback: {
- 'ASDASDSAD!1': {
+ "ASDASDSAD!1": {
state: ChallengeFeedbackStatus.Unsupported,
http_status: 500,
- unsupported_method: 'Question'
- }
- }
-
+ unsupported_method: "Question",
+ },
+ },
} as ReducerState);
export const TruthUnknownFeedback = createExample(TestedComponent[type].solve, {
...reducerStatesExample.challengeSolving,
recovery_information: {
- challenges: [{
- cost: 'USD:1',
- instructions: 'does P equals NP?',
- type: 'question',
- uuid: 'ASDASDSAD!1'
- }],
+ challenges: [
+ {
+ cost: "USD:1",
+ instructions: "does P equals NP?",
+ type: "question",
+ uuid: "ASDASDSAD!1",
+ },
+ ],
policies: [],
},
- selected_challenge_uuid: 'ASDASDSAD!1',
+ selected_challenge_uuid: "ASDASDSAD!1",
challenge_feedback: {
- 'ASDASDSAD!1': {
+ "ASDASDSAD!1": {
state: ChallengeFeedbackStatus.TruthUnknown,
- }
- }
-
+ },
+ },
} as ReducerState);
export const AuthIbanFeedback = createExample(TestedComponent[type].solve, {
...reducerStatesExample.challengeSolving,
recovery_information: {
- challenges: [{
- cost: 'USD:1',
- instructions: 'does P equals NP?',
- type: 'question',
- uuid: 'ASDASDSAD!1'
- }],
+ challenges: [
+ {
+ cost: "USD:1",
+ instructions: "does P equals NP?",
+ type: "question",
+ uuid: "ASDASDSAD!1",
+ },
+ ],
policies: [],
},
- selected_challenge_uuid: 'ASDASDSAD!1',
+ selected_challenge_uuid: "ASDASDSAD!1",
challenge_feedback: {
- 'ASDASDSAD!1': {
+ "ASDASDSAD!1": {
state: ChallengeFeedbackStatus.AuthIban,
challenge_amount: "EUR:1",
credit_iban: "DE12345789000",
@@ -210,30 +229,30 @@ export const AuthIbanFeedback = createExample(TestedComponent[type].solve, {
wire_transfer_subject: "foo",
},
method: "iban",
- }
- }
-
+ },
+ },
} as ReducerState);
export const PaymentFeedback = createExample(TestedComponent[type].solve, {
...reducerStatesExample.challengeSolving,
recovery_information: {
- challenges: [{
- cost: 'USD:1',
- instructions: 'does P equals NP?',
- type: 'question',
- uuid: 'ASDASDSAD!1'
- }],
+ challenges: [
+ {
+ cost: "USD:1",
+ instructions: "does P equals NP?",
+ type: "question",
+ uuid: "ASDASDSAD!1",
+ },
+ ],
policies: [],
},
- selected_challenge_uuid: 'ASDASDSAD!1',
+ selected_challenge_uuid: "ASDASDSAD!1",
challenge_feedback: {
- 'ASDASDSAD!1': {
+ "ASDASDSAD!1": {
state: ChallengeFeedbackStatus.Payment,
- taler_pay_uri : "taler://pay/...",
- provider : "https://localhost:8080/",
- payment_secret : "3P4561HAMHRRYEYD6CM6J7TS5VTD5SR2K2EXJDZEFSX92XKHR4KG"
- }
- }
+ taler_pay_uri: "taler://pay/...",
+ provider: "https://localhost:8080/",
+ payment_secret: "3P4561HAMHRRYEYD6CM6J7TS5VTD5SR2K2EXJDZEFSX92XKHR4KG",
+ },
+ },
} as ReducerState);
-
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.tsx
index ee1c0028f..222789507 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.tsx
@@ -44,8 +44,16 @@ export function AuthMethodQuestionSolve({ id }: AuthMethodSolveProps): VNode {
return (
<AnastasisClientFrame hideNav title="Recovery problem">
<div>invalid state</div>
- <div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
- <button class="button" onClick={() => reducer.back()}>Back</button>
+ <div
+ style={{
+ marginTop: "2em",
+ display: "flex",
+ justifyContent: "space-between",
+ }}
+ >
+ <button class="button" onClick={() => reducer.back()}>
+ Back
+ </button>
</div>
</AnastasisClientFrame>
);
@@ -62,8 +70,7 @@ export function AuthMethodQuestionSolve({ id }: AuthMethodSolveProps): VNode {
challenges[ch.uuid] = ch;
}
const selectedChallenge = challenges[selectedUuid];
- const feedback = challengeFeedback[selectedUuid]
-
+ const feedback = challengeFeedback[selectedUuid];
async function onNext(): Promise<void> {
return reducer?.transition("solve_challenge", { answer });
@@ -72,18 +79,16 @@ export function AuthMethodQuestionSolve({ id }: AuthMethodSolveProps): VNode {
reducer?.back();
}
-
- const shouldHideConfirm = feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded
- || feedback?.state === ChallengeFeedbackStatus.Redirect
- || feedback?.state === ChallengeFeedbackStatus.Unsupported
- || feedback?.state === ChallengeFeedbackStatus.TruthUnknown
+ const shouldHideConfirm =
+ feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded ||
+ feedback?.state === ChallengeFeedbackStatus.Redirect ||
+ feedback?.state === ChallengeFeedbackStatus.Unsupported ||
+ feedback?.state === ChallengeFeedbackStatus.TruthUnknown;
return (
<AnastasisClientFrame hideNav title="Add email authentication">
<SolveOverviewFeedbackDisplay feedback={feedback} />
- <p>
- Answer the question please
- </p>
+ <p>Answer the question please</p>
<TextInput label="Answer" grabFocus bind={[answer, setAnswer]} />
<div
@@ -96,9 +101,11 @@ export function AuthMethodQuestionSolve({ id }: AuthMethodSolveProps): VNode {
<button class="button" onClick={onCancel}>
Cancel
</button>
- {!shouldHideConfirm && <AsyncButton class="button is-info" onClick={onNext}>
- Confirm
- </AsyncButton>}
+ {!shouldHideConfirm && (
+ <AsyncButton class="button is-info" onClick={onNext}>
+ Confirm
+ </AsyncButton>
+ )}
</div>
</AnastasisClientFrame>
);
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSetup.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSetup.stories.tsx
index da2087ce1..3a44c7ad0 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSetup.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSetup.stories.tsx
@@ -16,51 +16,67 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { createExample, reducerStatesExample } from '../../../utils';
-import { authMethods as TestedComponent, KnownAuthMethods } from './index';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { createExample, reducerStatesExample } from "../../../utils";
+import { authMethods as TestedComponent, KnownAuthMethods } from "./index";
export default {
- title: 'Pages/backup/AuthorizationMethod/AuthMethods/Sms',
+ title: "Pages/backup/AuthorizationMethod/AuthMethods/Sms",
component: TestedComponent,
args: {
order: 5,
},
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
-const type: KnownAuthMethods = 'sms'
+const type: KnownAuthMethods = "sms";
-export const Empty = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, {
- configured: []
-});
+export const Empty = createExample(
+ TestedComponent[type].setup,
+ reducerStatesExample.authEditing,
+ {
+ configured: [],
+ },
+);
-export const WithOneExample = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, {
- configured: [{
- challenge: 'qwe',
- type,
- instructions: 'SMS to +11-1234-2345',
- remove: () => null
- }]
-});
+export const WithOneExample = createExample(
+ TestedComponent[type].setup,
+ reducerStatesExample.authEditing,
+ {
+ configured: [
+ {
+ challenge: "qwe",
+ type,
+ instructions: "SMS to +11-1234-2345",
+ remove: () => null,
+ },
+ ],
+ },
+);
-export const WithMoreExamples = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, {
- configured: [{
- challenge: 'qwe',
- type,
- instructions: 'SMS to +11-1234-2345',
- remove: () => null
- },{
- challenge: 'qwe',
- type,
- instructions: 'SMS to +11-5555-2345',
- remove: () => null
- }]
-});
+export const WithMoreExamples = createExample(
+ TestedComponent[type].setup,
+ reducerStatesExample.authEditing,
+ {
+ configured: [
+ {
+ challenge: "qwe",
+ type,
+ instructions: "SMS to +11-1234-2345",
+ remove: () => null,
+ },
+ {
+ challenge: "qwe",
+ type,
+ instructions: "SMS to +11-5555-2345",
+ remove: () => null,
+ },
+ ],
+ },
+);
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSetup.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSetup.tsx
index 9a0459d78..056b1b175 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSetup.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSetup.tsx
@@ -1,14 +1,15 @@
-import {
- encodeCrock,
- stringToBytes
-} from "@gnu-taler/taler-util";
+import { encodeCrock, stringToBytes } from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact";
import { useLayoutEffect, useRef, useState } from "preact/hooks";
import { AuthMethodSetupProps } from ".";
import { PhoneNumberInput } from "../../../components/fields/NumberInput";
import { AnastasisClientFrame } from "../index";
-export function AuthMethodSmsSetup({ addAuthMethod, cancel, configured }: AuthMethodSetupProps): VNode {
+export function AuthMethodSmsSetup({
+ addAuthMethod,
+ cancel,
+ configured,
+}: AuthMethodSetupProps): VNode {
const [mobileNumber, setMobileNumber] = useState("");
const addSmsAuth = (): void => {
addAuthMethod({
@@ -23,7 +24,7 @@ export function AuthMethodSmsSetup({ addAuthMethod, cancel, configured }: AuthMe
useLayoutEffect(() => {
inputRef.current?.focus();
}, []);
- const errors = !mobileNumber ? 'Add a mobile number' : undefined
+ const errors = !mobileNumber ? "Add a mobile number" : undefined;
return (
<AnastasisClientFrame hideNav title="Add SMS authentication">
<div>
@@ -37,23 +38,52 @@ export function AuthMethodSmsSetup({ addAuthMethod, cancel, configured }: AuthMe
label="Mobile number"
placeholder="Your mobile number"
grabFocus
- bind={[mobileNumber, setMobileNumber]} />
+ bind={[mobileNumber, setMobileNumber]}
+ />
</div>
- {configured.length > 0 && <section class="section">
- <div class="block">
- Your mobile numbers:
- </div><div class="block">
- {configured.map((c, i) => {
- return <div key={i} class="box" style={{ display: 'flex', justifyContent: 'space-between' }}>
- <p style={{ marginTop: 'auto', marginBottom: 'auto' }}>{c.instructions}</p>
- <div><button class="button is-danger" onClick={c.remove}>Delete</button></div>
- </div>
- })}
- </div></section>}
- <div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
- <button class="button" onClick={cancel}>Cancel</button>
+ {configured.length > 0 && (
+ <section class="section">
+ <div class="block">Your mobile numbers:</div>
+ <div class="block">
+ {configured.map((c, i) => {
+ return (
+ <div
+ key={i}
+ class="box"
+ style={{ display: "flex", justifyContent: "space-between" }}
+ >
+ <p style={{ marginTop: "auto", marginBottom: "auto" }}>
+ {c.instructions}
+ </p>
+ <div>
+ <button class="button is-danger" onClick={c.remove}>
+ Delete
+ </button>
+ </div>
+ </div>
+ );
+ })}
+ </div>
+ </section>
+ )}
+ <div
+ style={{
+ marginTop: "2em",
+ display: "flex",
+ justifyContent: "space-between",
+ }}
+ >
+ <button class="button" onClick={cancel}>
+ Cancel
+ </button>
<span data-tooltip={errors}>
- <button class="button is-info" disabled={errors !== undefined} onClick={addSmsAuth}>Add</button>
+ <button
+ class="button is-info"
+ disabled={errors !== undefined}
+ onClick={addSmsAuth}
+ >
+ Add
+ </button>
</span>
</div>
</div>
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSolve.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSolve.stories.tsx
index 76e769303..3dc3adb2b 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSolve.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSolve.stories.tsx
@@ -15,42 +15,46 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { ChallengeFeedbackStatus, ReducerState } from 'anastasis-core';
-import { createExample, reducerStatesExample } from '../../../utils';
-import { authMethods as TestedComponent, KnownAuthMethods } from './index';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { ChallengeFeedbackStatus, ReducerState } from "anastasis-core";
+import { createExample, reducerStatesExample } from "../../../utils";
+import { authMethods as TestedComponent, KnownAuthMethods } from "./index";
export default {
- title: 'Pages/recovery/SolveChallenge/AuthMethods/sms',
+ title: "Pages/recovery/SolveChallenge/AuthMethods/sms",
component: TestedComponent,
args: {
order: 5,
},
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
-const type: KnownAuthMethods = 'sms'
-
-export const WithoutFeedback = createExample(TestedComponent[type].solve, {
- ...reducerStatesExample.challengeSolving,
- recovery_information: {
- challenges: [{
- cost: 'USD:1',
- instructions: 'does P equals NP?',
- type: 'question',
- uuid: 'uuid-1'
- }],
- policies: [],
+const type: KnownAuthMethods = "sms";
+
+export const WithoutFeedback = createExample(
+ TestedComponent[type].solve,
+ {
+ ...reducerStatesExample.challengeSolving,
+ recovery_information: {
+ challenges: [
+ {
+ cost: "USD:1",
+ instructions: "does P equals NP?",
+ type: "question",
+ uuid: "uuid-1",
+ },
+ ],
+ policies: [],
+ },
+ selected_challenge_uuid: "uuid-1",
+ } as ReducerState,
+ {
+ id: "uuid-1",
},
- selected_challenge_uuid: 'uuid-1',
-} as ReducerState, {
- id: 'uuid-1',
-});
-
+);
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSolve.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSolve.tsx
index ce7159bd0..8ee4d600a 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSolve.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSolve.tsx
@@ -44,8 +44,16 @@ export function AuthMethodSmsSolve({ id }: AuthMethodSolveProps): VNode {
return (
<AnastasisClientFrame hideNav title="Recovery problem">
<div>invalid state</div>
- <div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
- <button class="button" onClick={() => reducer.back()}>Back</button>
+ <div
+ style={{
+ marginTop: "2em",
+ display: "flex",
+ justifyContent: "space-between",
+ }}
+ >
+ <button class="button" onClick={() => reducer.back()}>
+ Back
+ </button>
</div>
</AnastasisClientFrame>
);
@@ -62,8 +70,7 @@ export function AuthMethodSmsSolve({ id }: AuthMethodSolveProps): VNode {
challenges[ch.uuid] = ch;
}
const selectedChallenge = challenges[selectedUuid];
- const feedback = challengeFeedback[selectedUuid]
-
+ const feedback = challengeFeedback[selectedUuid];
async function onNext(): Promise<void> {
return reducer?.transition("solve_challenge", { answer });
@@ -72,18 +79,18 @@ export function AuthMethodSmsSolve({ id }: AuthMethodSolveProps): VNode {
reducer?.back();
}
-
- const shouldHideConfirm = feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded
- || feedback?.state === ChallengeFeedbackStatus.Redirect
- || feedback?.state === ChallengeFeedbackStatus.Unsupported
- || feedback?.state === ChallengeFeedbackStatus.TruthUnknown
+ const shouldHideConfirm =
+ feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded ||
+ feedback?.state === ChallengeFeedbackStatus.Redirect ||
+ feedback?.state === ChallengeFeedbackStatus.Unsupported ||
+ feedback?.state === ChallengeFeedbackStatus.TruthUnknown;
return (
<AnastasisClientFrame hideNav title="Add email authentication">
<SolveOverviewFeedbackDisplay feedback={feedback} />
<p>
- An sms has been sent to "<b>{selectedChallenge.instructions}</b>". Type the code
- below
+ An sms has been sent to "<b>{selectedChallenge.instructions}</b>". Type
+ the code below
</p>
<TextInput label="Answer" grabFocus bind={[answer, setAnswer]} />
@@ -97,9 +104,11 @@ export function AuthMethodSmsSolve({ id }: AuthMethodSolveProps): VNode {
<button class="button" onClick={onCancel}>
Cancel
</button>
- {!shouldHideConfirm && <AsyncButton class="button is-info" onClick={onNext}>
- Confirm
- </AsyncButton>}
+ {!shouldHideConfirm && (
+ <AsyncButton class="button is-info" onClick={onNext}>
+ Confirm
+ </AsyncButton>
+ )}
</div>
</AnastasisClientFrame>
);
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSetup.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSetup.stories.tsx
index c0a52924c..bc4628828 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSetup.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSetup.stories.tsx
@@ -16,49 +16,65 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { createExample, reducerStatesExample } from '../../../utils';
-import { authMethods as TestedComponent, KnownAuthMethods } from './index';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { createExample, reducerStatesExample } from "../../../utils";
+import { authMethods as TestedComponent, KnownAuthMethods } from "./index";
export default {
- title: 'Pages/backup/AuthorizationMethod/AuthMethods/TOTP',
+ title: "Pages/backup/AuthorizationMethod/AuthMethods/TOTP",
component: TestedComponent,
args: {
order: 5,
},
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
-const type: KnownAuthMethods = 'totp'
+const type: KnownAuthMethods = "totp";
-export const Empty = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, {
- configured: []
-});
-export const WithOneExample = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, {
- configured: [{
- challenge: 'qwe',
- type,
- instructions: 'Enter 8 digits code for "Anastasis"',
- remove: () => null
- }]
-});
-export const WithMoreExample = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, {
- configured: [{
- challenge: 'qwe',
- type,
- instructions: 'Enter 8 digits code for "Anastasis1"',
- remove: () => null
- },{
- challenge: 'qwe',
- type,
- instructions: 'Enter 8 digits code for "Anastasis2"',
- remove: () => null
- }]
-});
+export const Empty = createExample(
+ TestedComponent[type].setup,
+ reducerStatesExample.authEditing,
+ {
+ configured: [],
+ },
+);
+export const WithOneExample = createExample(
+ TestedComponent[type].setup,
+ reducerStatesExample.authEditing,
+ {
+ configured: [
+ {
+ challenge: "qwe",
+ type,
+ instructions: 'Enter 8 digits code for "Anastasis"',
+ remove: () => null,
+ },
+ ],
+ },
+);
+export const WithMoreExample = createExample(
+ TestedComponent[type].setup,
+ reducerStatesExample.authEditing,
+ {
+ configured: [
+ {
+ challenge: "qwe",
+ type,
+ instructions: 'Enter 8 digits code for "Anastasis1"',
+ remove: () => null,
+ },
+ {
+ challenge: "qwe",
+ type,
+ instructions: 'Enter 8 digits code for "Anastasis2"',
+ remove: () => null,
+ },
+ ],
+ },
+);
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSetup.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSetup.tsx
index a8ac499b2..1451aadc8 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSetup.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSetup.tsx
@@ -1,7 +1,4 @@
-import {
- encodeCrock,
- stringToBytes
-} from "@gnu-taler/taler-util";
+import { encodeCrock, stringToBytes } from "@gnu-taler/taler-util";
import { h, VNode } from "preact";
import { useMemo, useState } from "preact/hooks";
import { AuthMethodSetupProps } from "./index";
@@ -10,30 +7,37 @@ import { TextInput } from "../../../components/fields/TextInput";
import { QR } from "../../../components/QR";
import { base32enc, computeTOTPandCheck } from "./totp";
-export function AuthMethodTotpSetup({ addAuthMethod, cancel, configured }: AuthMethodSetupProps): VNode {
+export function AuthMethodTotpSetup({
+ addAuthMethod,
+ cancel,
+ configured,
+}: AuthMethodSetupProps): VNode {
const [name, setName] = useState("anastasis");
const [test, setTest] = useState("");
- const digits = 8
+ const digits = 8;
const secretKey = useMemo(() => {
- const array = new Uint8Array(32)
- return window.crypto.getRandomValues(array)
- }, [])
+ const array = new Uint8Array(32);
+ return window.crypto.getRandomValues(array);
+ }, []);
const secret32 = base32enc(secretKey);
- const totpURL = `otpauth://totp/${name}?digits=${digits}&secret=${secret32}`
+ const totpURL = `otpauth://totp/${name}?digits=${digits}&secret=${secret32}`;
- const addTotpAuth = (): void => addAuthMethod({
- authentication_method: {
- type: "totp",
- instructions: `Enter ${digits} digits code for "${name}"`,
- challenge: encodeCrock(stringToBytes(totpURL)),
- },
- });
+ const addTotpAuth = (): void =>
+ addAuthMethod({
+ authentication_method: {
+ type: "totp",
+ instructions: `Enter ${digits} digits code for "${name}"`,
+ challenge: encodeCrock(stringToBytes(totpURL)),
+ },
+ });
const testCodeMatches = computeTOTPandCheck(secretKey, 8, parseInt(test, 10));
- const errors = !name ? 'The TOTP name is missing' : (
- !testCodeMatches ? 'The test code doesnt match' : undefined
- );
+ const errors = !name
+ ? "The TOTP name is missing"
+ : !testCodeMatches
+ ? "The test code doesnt match"
+ : undefined;
return (
<AnastasisClientFrame hideNav title="Add TOTP authentication">
<p>
@@ -42,10 +46,7 @@ export function AuthMethodTotpSetup({ addAuthMethod, cancel, configured }: AuthM
with your TOTP App to import the TOTP secret into your TOTP App.
</p>
<div class="block">
- <TextInput
- label="TOTP Name"
- grabFocus
- bind={[name, setName]} />
+ <TextInput label="TOTP Name" grabFocus bind={[name, setName]} />
</div>
<div style={{ height: 300 }}>
<QR text={totpURL} />
@@ -53,25 +54,51 @@ export function AuthMethodTotpSetup({ addAuthMethod, cancel, configured }: AuthM
<p>
After scanning the code with your TOTP App, test it in the input below.
</p>
- <TextInput
- label="Test code"
- bind={[test, setTest]} />
- {configured.length > 0 && <section class="section">
- <div class="block">
- Your TOTP numbers:
- </div><div class="block">
- {configured.map((c, i) => {
- return <div key={i} class="box" style={{ display: 'flex', justifyContent: 'space-between' }}>
- <p style={{ marginTop: 'auto', marginBottom: 'auto' }}>{c.instructions}</p>
- <div><button class="button is-danger" onClick={c.remove}>Delete</button></div>
- </div>
- })}
- </div></section>}
+ <TextInput label="Test code" bind={[test, setTest]} />
+ {configured.length > 0 && (
+ <section class="section">
+ <div class="block">Your TOTP numbers:</div>
+ <div class="block">
+ {configured.map((c, i) => {
+ return (
+ <div
+ key={i}
+ class="box"
+ style={{ display: "flex", justifyContent: "space-between" }}
+ >
+ <p style={{ marginTop: "auto", marginBottom: "auto" }}>
+ {c.instructions}
+ </p>
+ <div>
+ <button class="button is-danger" onClick={c.remove}>
+ Delete
+ </button>
+ </div>
+ </div>
+ );
+ })}
+ </div>
+ </section>
+ )}
<div>
- <div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
- <button class="button" onClick={cancel}>Cancel</button>
+ <div
+ style={{
+ marginTop: "2em",
+ display: "flex",
+ justifyContent: "space-between",
+ }}
+ >
+ <button class="button" onClick={cancel}>
+ Cancel
+ </button>
<span data-tooltip={errors}>
- <button class="button is-info" disabled={errors !== undefined} onClick={addTotpAuth}>Add</button>
+ <button
+ class="button is-info"
+ disabled={errors !== undefined}
+ onClick={addTotpAuth}
+ >
+ Add
+ </button>
</span>
</div>
</div>
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.stories.tsx
index a301931b2..8743c5a73 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.stories.tsx
@@ -15,42 +15,46 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { ChallengeFeedbackStatus, ReducerState } from 'anastasis-core';
-import { createExample, reducerStatesExample } from '../../../utils';
-import { authMethods as TestedComponent, KnownAuthMethods } from './index';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { ChallengeFeedbackStatus, ReducerState } from "anastasis-core";
+import { createExample, reducerStatesExample } from "../../../utils";
+import { authMethods as TestedComponent, KnownAuthMethods } from "./index";
export default {
- title: 'Pages/recovery/SolveChallenge/AuthMethods/totp',
+ title: "Pages/recovery/SolveChallenge/AuthMethods/totp",
component: TestedComponent,
args: {
order: 5,
},
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
-const type: KnownAuthMethods = 'totp'
-
-export const WithoutFeedback = createExample(TestedComponent[type].solve, {
- ...reducerStatesExample.challengeSolving,
- recovery_information: {
- challenges: [{
- cost: 'USD:1',
- instructions: 'does P equals NP?',
- type: 'question',
- uuid: 'uuid-1'
- }],
- policies: [],
+const type: KnownAuthMethods = "totp";
+
+export const WithoutFeedback = createExample(
+ TestedComponent[type].solve,
+ {
+ ...reducerStatesExample.challengeSolving,
+ recovery_information: {
+ challenges: [
+ {
+ cost: "USD:1",
+ instructions: "does P equals NP?",
+ type: "question",
+ uuid: "uuid-1",
+ },
+ ],
+ policies: [],
+ },
+ selected_challenge_uuid: "uuid-1",
+ } as ReducerState,
+ {
+ id: "uuid-1",
},
- selected_challenge_uuid: 'uuid-1',
-} as ReducerState, {
- id: 'uuid-1',
-});
-
+);
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.tsx
index 30fc44f0e..98c2e51df 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.tsx
@@ -44,8 +44,16 @@ export function AuthMethodTotpSolve({ id }: AuthMethodSolveProps): VNode {
return (
<AnastasisClientFrame hideNav title="Recovery problem">
<div>invalid state</div>
- <div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
- <button class="button" onClick={() => reducer.back()}>Back</button>
+ <div
+ style={{
+ marginTop: "2em",
+ display: "flex",
+ justifyContent: "space-between",
+ }}
+ >
+ <button class="button" onClick={() => reducer.back()}>
+ Back
+ </button>
</div>
</AnastasisClientFrame>
);
@@ -62,8 +70,7 @@ export function AuthMethodTotpSolve({ id }: AuthMethodSolveProps): VNode {
challenges[ch.uuid] = ch;
}
const selectedChallenge = challenges[selectedUuid];
- const feedback = challengeFeedback[selectedUuid]
-
+ const feedback = challengeFeedback[selectedUuid];
async function onNext(): Promise<void> {
return reducer?.transition("solve_challenge", { answer });
@@ -72,18 +79,16 @@ export function AuthMethodTotpSolve({ id }: AuthMethodSolveProps): VNode {
reducer?.back();
}
-
- const shouldHideConfirm = feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded
- || feedback?.state === ChallengeFeedbackStatus.Redirect
- || feedback?.state === ChallengeFeedbackStatus.Unsupported
- || feedback?.state === ChallengeFeedbackStatus.TruthUnknown
+ const shouldHideConfirm =
+ feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded ||
+ feedback?.state === ChallengeFeedbackStatus.Redirect ||
+ feedback?.state === ChallengeFeedbackStatus.Unsupported ||
+ feedback?.state === ChallengeFeedbackStatus.TruthUnknown;
return (
<AnastasisClientFrame hideNav title="Add email authentication">
<SolveOverviewFeedbackDisplay feedback={feedback} />
- <p>
- enter the totp solution
- </p>
+ <p>enter the totp solution</p>
<TextInput label="Answer" grabFocus bind={[answer, setAnswer]} />
<div
@@ -96,9 +101,11 @@ export function AuthMethodTotpSolve({ id }: AuthMethodSolveProps): VNode {
<button class="button" onClick={onCancel}>
Cancel
</button>
- {!shouldHideConfirm && <AsyncButton class="button is-info" onClick={onNext}>
- Confirm
- </AsyncButton>}
+ {!shouldHideConfirm && (
+ <AsyncButton class="button is-info" onClick={onNext}>
+ Confirm
+ </AsyncButton>
+ )}
</div>
</AnastasisClientFrame>
);
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.stories.tsx
index 52e897c60..4aad0a097 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.stories.tsx
@@ -16,51 +16,68 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
-import { createExample, reducerStatesExample } from '../../../utils';
-import { authMethods as TestedComponent, KnownAuthMethods } from './index';
-import logoImage from '../../../assets/logo.jpeg'
+import { createExample, reducerStatesExample } from "../../../utils";
+import { authMethods as TestedComponent, KnownAuthMethods } from "./index";
+import logoImage from "../../../assets/logo.jpeg";
export default {
- title: 'Pages/backup/AuthorizationMethod/AuthMethods/Video',
+ title: "Pages/backup/AuthorizationMethod/AuthMethods/Video",
component: TestedComponent,
args: {
order: 5,
},
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
-const type: KnownAuthMethods = 'video'
+const type: KnownAuthMethods = "video";
-export const Empty = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, {
- configured: []
-});
+export const Empty = createExample(
+ TestedComponent[type].setup,
+ reducerStatesExample.authEditing,
+ {
+ configured: [],
+ },
+);
-export const WithOneExample = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, {
- configured: [{
- challenge: 'qwe',
- type,
- instructions: logoImage,
- remove: () => null
- }]
-});
+export const WithOneExample = createExample(
+ TestedComponent[type].setup,
+ reducerStatesExample.authEditing,
+ {
+ configured: [
+ {
+ challenge: "qwe",
+ type,
+ instructions: logoImage,
+ remove: () => null,
+ },
+ ],
+ },
+);
-export const WithMoreExamples = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, {
- configured: [{
- challenge: 'qwe',
- type,
- instructions: logoImage,
- remove: () => null
- },{
- challenge: 'qwe',
- type,
- instructions: logoImage,
- remove: () => null
- }]
-});
+export const WithMoreExamples = createExample(
+ TestedComponent[type].setup,
+ reducerStatesExample.authEditing,
+ {
+ configured: [
+ {
+ challenge: "qwe",
+ type,
+ instructions: logoImage,
+ remove: () => null,
+ },
+ {
+ challenge: "qwe",
+ type,
+ instructions: logoImage,
+ remove: () => null,
+ },
+ ],
+ },
+);
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.tsx
index 22abe4a49..672b23500 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.tsx
@@ -1,53 +1,86 @@
-import {
- encodeCrock,
- stringToBytes
-} from "@gnu-taler/taler-util";
+import { encodeCrock, stringToBytes } from "@gnu-taler/taler-util";
import { h, VNode } from "preact";
import { useState } from "preact/hooks";
import { ImageInput } from "../../../components/fields/ImageInput";
import { AuthMethodSetupProps } from "./index";
import { AnastasisClientFrame } from "../index";
-export function AuthMethodVideoSetup({cancel, addAuthMethod, configured}: AuthMethodSetupProps): VNode {
+export function AuthMethodVideoSetup({
+ cancel,
+ addAuthMethod,
+ configured,
+}: AuthMethodSetupProps): VNode {
const [image, setImage] = useState("");
const addVideoAuth = (): void => {
addAuthMethod({
authentication_method: {
type: "video",
- instructions: 'Join a video call',
+ instructions: "Join a video call",
challenge: encodeCrock(stringToBytes(image)),
},
- })
+ });
};
return (
<AnastasisClientFrame hideNav title="Add video authentication">
<p>
- For video identification, you need to provide a passport-style
- photograph. When recovering your secret, you will be asked to join a
- video call. During that call, a human will use the photograph to
- verify your identity.
+ For video identification, you need to provide a passport-style
+ photograph. When recovering your secret, you will be asked to join a
+ video call. During that call, a human will use the photograph to verify
+ your identity.
</p>
- <div style={{textAlign:'center'}}>
+ <div style={{ textAlign: "center" }}>
<ImageInput
label="Choose photograph"
grabFocus
- bind={[image, setImage]} />
+ bind={[image, setImage]}
+ />
</div>
- {configured.length > 0 && <section class="section">
+ {configured.length > 0 && (
+ <section class="section">
+ <div class="block">Your photographs:</div>
<div class="block">
- Your photographs:
- </div><div class="block">
{configured.map((c, i) => {
- return <div key={i} class="box" style={{ display: 'flex', justifyContent: 'space-between' }}>
- <img style={{ marginTop: 'auto', marginBottom: 'auto', width: 100, height:100, border: 'solid 1px black' }} src={c.instructions} />
- <div style={{marginTop: 'auto', marginBottom: 'auto'}}><button class="button is-danger" onClick={c.remove}>Delete</button></div>
- </div>
+ return (
+ <div
+ key={i}
+ class="box"
+ style={{ display: "flex", justifyContent: "space-between" }}
+ >
+ <img
+ style={{
+ marginTop: "auto",
+ marginBottom: "auto",
+ width: 100,
+ height: 100,
+ border: "solid 1px black",
+ }}
+ src={c.instructions}
+ />
+ <div style={{ marginTop: "auto", marginBottom: "auto" }}>
+ <button class="button is-danger" onClick={c.remove}>
+ Delete
+ </button>
+ </div>
+ </div>
+ );
})}
- </div></section>}
+ </div>
+ </section>
+ )}
<div>
- <div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
- <button class="button" onClick={cancel}>Cancel</button>
- <button class="button is-info" onClick={addVideoAuth}>Add</button>
+ <div
+ style={{
+ marginTop: "2em",
+ display: "flex",
+ justifyContent: "space-between",
+ }}
+ >
+ <button class="button" onClick={cancel}>
+ Cancel
+ </button>
+ <button class="button is-info" onClick={addVideoAuth}>
+ Add
+ </button>
</div>
</div>
</AnastasisClientFrame>
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.stories.tsx
index 5c4976b87..7c5511c5a 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.stories.tsx
@@ -15,42 +15,46 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { ChallengeFeedbackStatus, ReducerState } from 'anastasis-core';
-import { createExample, reducerStatesExample } from '../../../utils';
-import { authMethods as TestedComponent, KnownAuthMethods } from './index';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { ChallengeFeedbackStatus, ReducerState } from "anastasis-core";
+import { createExample, reducerStatesExample } from "../../../utils";
+import { authMethods as TestedComponent, KnownAuthMethods } from "./index";
export default {
- title: 'Pages/recovery/SolveChallenge/AuthMethods/video',
+ title: "Pages/recovery/SolveChallenge/AuthMethods/video",
component: TestedComponent,
args: {
order: 5,
},
argTypes: {
- onUpdate: { action: 'onUpdate' },
- onBack: { action: 'onBack' },
+ onUpdate: { action: "onUpdate" },
+ onBack: { action: "onBack" },
},
};
-const type: KnownAuthMethods = 'video'
-
-export const WithoutFeedback = createExample(TestedComponent[type].solve, {
- ...reducerStatesExample.challengeSolving,
- recovery_information: {
- challenges: [{
- cost: 'USD:1',
- instructions: 'does P equals NP?',
- type: 'question',
- uuid: 'uuid-1'
- }],
- policies: [],
+const type: KnownAuthMethods = "video";
+
+export const WithoutFeedback = createExample(
+ TestedComponent[type].solve,
+ {
+ ...reducerStatesExample.challengeSolving,
+ recovery_information: {
+ challenges: [
+ {
+ cost: "USD:1",
+ instructions: "does P equals NP?",
+ type: "question",
+ uuid: "uuid-1",
+ },
+ ],
+ policies: [],
+ },
+ selected_challenge_uuid: "uuid-1",
+ } as ReducerState,
+ {
+ id: "uuid-1",
},
- selected_challenge_uuid: 'uuid-1',
-} as ReducerState, {
- id: 'uuid-1',
-});
-
+);
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.tsx
index 79401028a..efadb9a9a 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.tsx
@@ -44,8 +44,16 @@ export function AuthMethodVideoSolve({ id }: AuthMethodSolveProps): VNode {
return (
<AnastasisClientFrame hideNav title="Recovery problem">
<div>invalid state</div>
- <div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
- <button class="button" onClick={() => reducer.back()}>Back</button>
+ <div
+ style={{
+ marginTop: "2em",
+ display: "flex",
+ justifyContent: "space-between",
+ }}
+ >
+ <button class="button" onClick={() => reducer.back()}>
+ Back
+ </button>
</div>
</AnastasisClientFrame>
);
@@ -62,8 +70,7 @@ export function AuthMethodVideoSolve({ id }: AuthMethodSolveProps): VNode {
challenges[ch.uuid] = ch;
}
const selectedChallenge = challenges[selectedUuid];
- const feedback = challengeFeedback[selectedUuid]
-
+ const feedback = challengeFeedback[selectedUuid];
async function onNext(): Promise<void> {
return reducer?.transition("solve_challenge", { answer });
@@ -72,18 +79,16 @@ export function AuthMethodVideoSolve({ id }: AuthMethodSolveProps): VNode {
reducer?.back();
}
-
- const shouldHideConfirm = feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded
- || feedback?.state === ChallengeFeedbackStatus.Redirect
- || feedback?.state === ChallengeFeedbackStatus.Unsupported
- || feedback?.state === ChallengeFeedbackStatus.TruthUnknown
+ const shouldHideConfirm =
+ feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded ||
+ feedback?.state === ChallengeFeedbackStatus.Redirect ||
+ feedback?.state === ChallengeFeedbackStatus.Unsupported ||
+ feedback?.state === ChallengeFeedbackStatus.TruthUnknown;
return (
<AnastasisClientFrame hideNav title="Add email authentication">
<SolveOverviewFeedbackDisplay feedback={feedback} />
- <p>
- You are gonna be called to check your identity
- </p>
+ <p>You are gonna be called to check your identity</p>
<TextInput label="Answer" grabFocus bind={[answer, setAnswer]} />
<div
@@ -96,9 +101,11 @@ export function AuthMethodVideoSolve({ id }: AuthMethodSolveProps): VNode {
<button class="button" onClick={onCancel}>
Cancel
</button>
- {!shouldHideConfirm && <AsyncButton class="button is-info" onClick={onNext}>
- Confirm
- </AsyncButton>}
+ {!shouldHideConfirm && (
+ <AsyncButton class="button is-info" onClick={onNext}>
+ Confirm
+ </AsyncButton>
+ )}
</div>
</AnastasisClientFrame>
);
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/index.tsx b/packages/anastasis-webui/src/pages/home/authMethod/index.tsx
index 8b0126ce7..b4f649488 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/index.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/index.tsx
@@ -1,9 +1,9 @@
import { AuthMethod } from "anastasis-core";
import { h, VNode } from "preact";
-import postalIcon from '../../../assets/icons/auth_method/postal.svg';
-import questionIcon from '../../../assets/icons/auth_method/question.svg';
-import smsIcon from '../../../assets/icons/auth_method/sms.svg';
-import videoIcon from '../../../assets/icons/auth_method/video.svg';
+import postalIcon from "../../../assets/icons/auth_method/postal.svg";
+import questionIcon from "../../../assets/icons/auth_method/question.svg";
+import smsIcon from "../../../assets/icons/auth_method/sms.svg";
+import videoIcon from "../../../assets/icons/auth_method/video.svg";
import { AuthMethodEmailSetup as EmailSetup } from "./AuthMethodEmailSetup";
import { AuthMethodEmailSolve as EmailSolve } from "./AuthMethodEmailSolve";
import { AuthMethodIbanSetup as IbanSetup } from "./AuthMethodIbanSetup";
@@ -20,8 +20,7 @@ import { AuthMethodSmsSolve as SmsSolve } from "./AuthMethodSmsSolve";
import { AuthMethodTotpSolve as TotpSolve } from "./AuthMethodTotpSolve";
import { AuthMethodVideoSolve as VideoSolve } from "./AuthMethodVideoSolve";
-
-export type AuthMethodWithRemove = AuthMethod & { remove: () => void }
+export type AuthMethodWithRemove = AuthMethod & { remove: () => void };
export interface AuthMethodSetupProps {
method: string;
@@ -43,10 +42,18 @@ interface AuthMethodConfiguration {
}
// export type KnownAuthMethods = "sms" | "email" | "post" | "question" | "video" | "totp" | "iban";
-const ALL_METHODS = ['sms', 'email', 'post', 'question', 'video' , 'totp', 'iban'] as const;
-export type KnownAuthMethods = (typeof ALL_METHODS)[number];
+const ALL_METHODS = [
+ "sms",
+ "email",
+ "post",
+ "question",
+ "video",
+ "totp",
+ "iban",
+] as const;
+export type KnownAuthMethods = typeof ALL_METHODS[number];
export function isKnownAuthMethods(value: string): value is KnownAuthMethods {
- return ALL_METHODS.includes(value as KnownAuthMethods)
+ return ALL_METHODS.includes(value as KnownAuthMethods);
}
type KnowMethodConfig = {
@@ -96,5 +103,5 @@ export const authMethods: KnowMethodConfig = {
setup: VideoSetup,
solve: VideoSolve,
skip: true,
- }
-} \ No newline at end of file
+ },
+};
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/totp.ts b/packages/anastasis-webui/src/pages/home/authMethod/totp.ts
index 0bc3feaf8..c2288671c 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/totp.ts
+++ b/packages/anastasis-webui/src/pages/home/authMethod/totp.ts
@@ -1,54 +1,61 @@
/* eslint-disable @typescript-eslint/camelcase */
-import jssha from 'jssha'
+import jssha from "jssha";
-const SEARCH_RANGE = 16
-const timeStep = 30
+const SEARCH_RANGE = 16;
+const timeStep = 30;
-export function computeTOTPandCheck(secretKey: Uint8Array, digits: number, code: number): boolean {
- const now = new Date().getTime()
+export function computeTOTPandCheck(
+ secretKey: Uint8Array,
+ digits: number,
+ code: number,
+): boolean {
+ const now = new Date().getTime();
const epoch = Math.floor(Math.round(now / 1000.0) / timeStep);
for (let ms = -SEARCH_RANGE; ms < SEARCH_RANGE; ms++) {
const movingFactor = (epoch + ms).toString(16).padStart(16, "0");
- const hmacSha = new jssha('SHA-1', 'HEX', { hmacKey: { value: secretKey, format: 'UINT8ARRAY' } });
+ const hmacSha = new jssha("SHA-1", "HEX", {
+ hmacKey: { value: secretKey, format: "UINT8ARRAY" },
+ });
hmacSha.update(movingFactor);
- const hmac_text = hmacSha.getHMAC('UINT8ARRAY');
+ const hmac_text = hmacSha.getHMAC("UINT8ARRAY");
- const offset = (hmac_text[hmac_text.length - 1] & 0xf)
+ const offset = hmac_text[hmac_text.length - 1] & 0xf;
- const otp = ((
- (hmac_text[offset + 0] << 24) +
- (hmac_text[offset + 1] << 16) +
- (hmac_text[offset + 2] << 8) +
- (hmac_text[offset + 3])
- ) & 0x7fffffff) % Math.pow(10, digits)
+ const otp =
+ (((hmac_text[offset + 0] << 24) +
+ (hmac_text[offset + 1] << 16) +
+ (hmac_text[offset + 2] << 8) +
+ hmac_text[offset + 3]) &
+ 0x7fffffff) %
+ Math.pow(10, digits);
- if (otp == code) return true
+ if (otp == code) return true;
}
- return false
+ return false;
}
-const encTable__ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567".split('')
+const encTable__ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567".split("");
export function base32enc(buffer: Uint8Array): string {
- let rpos = 0
- let bits = 0
- let vbit = 0
+ let rpos = 0;
+ let bits = 0;
+ let vbit = 0;
- let result = ""
- while ((rpos < buffer.length) || (vbit > 0)) {
- if ((rpos < buffer.length) && (vbit < 5)) {
+ let result = "";
+ while (rpos < buffer.length || vbit > 0) {
+ if (rpos < buffer.length && vbit < 5) {
bits = (bits << 8) | buffer[rpos++];
vbit += 8;
}
if (vbit < 5) {
- bits <<= (5 - vbit);
+ bits <<= 5 - vbit;
vbit = 5;
}
result += encTable__[(bits >> (vbit - 5)) & 31];
vbit -= 5;
}
- return result
+ return result;
}
// const array = new Uint8Array(256)