summaryrefslogtreecommitdiff
path: root/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx')
-rw-r--r--packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx165
1 files changed, 137 insertions, 28 deletions
diff --git a/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx b/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx
index b360ccaf0..3755dac9c 100644
--- a/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx
@@ -1,51 +1,160 @@
-/* eslint-disable @typescript-eslint/camelcase */
+/*
+ This file is part of GNU Anastasis
+ (C) 2021-2022 Anastasis SARL
+
+ GNU Anastasis is free software; you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ GNU Anastasis; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+import { AuthenticationProviderStatusOk } from "@gnu-taler/anastasis-core";
import { h, VNode } from "preact";
-import { useAnastasisContext } from "../../context/anastasis";
-import { AnastasisClientFrame } from "./index";
+import { useState } from "preact/hooks";
+import { useAnastasisContext } from "../../context/anastasis.js";
+import { authMethods, KnownAuthMethods } from "./authMethod/index.js";
+import { EditPoliciesScreen } from "./EditPoliciesScreen.js";
+import { AnastasisClientFrame } from "./index.js";
export function ReviewPoliciesScreen(): VNode {
- 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_type !== "backup") {
+ return <div>invalid state</div>;
}
- const authMethods = reducer.currentReducerState.authentication_methods ?? [];
+
+ const configuredAuthMethods =
+ reducer.currentReducerState.authentication_methods ?? [];
const policies = reducer.currentReducerState.policies ?? [];
+ const providers = reducer.currentReducerState.authentication_providers ?? {};
+
+ if (editingPolicy !== undefined) {
+ return (
+ <EditPoliciesScreen
+ index={editingPolicy}
+ cancel={() => setEditingPolicy(undefined)}
+ confirm={async (newMethods) => {
+ await reducer.transition("update_policy", {
+ policy_index: editingPolicy,
+ policy: newMethods,
+ });
+ setEditingPolicy(undefined);
+ }}
+ />
+ );
+ }
+
+ const errors = policies.length < 1 ? "Need more policies" : undefined;
return (
- <AnastasisClientFrame title="Backup: Review Recovery Policies">
+ <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">
+ <button
+ class="button is-success"
+ style={{ marginLeft: 10 }}
+ onClick={() => setEditingPolicy(policies.length)}
+ >
+ Add new policy
+ </button>
+ </div>
{policies.map((p, policy_index) => {
const methods = p.methods
- .map(x => authMethods[x.authentication_method] && ({ ...authMethods[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="policy">
- <h3>
- Policy #{policy_index + 1}: {policyName}
- </h3>
- Required Authentications:
- {!methods.length && <p>
- No auth method found
- </p>}
- <ul>
+ <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.map((m, i) => {
+ const p = providers[
+ m.provider
+ ] as AuthenticationProviderStatusOk;
return (
- <li key={i}>
- {m.type} ({m.instructions}) at provider {m.provider}
- </li>
+ <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} target="_blank" rel="noreferrer">
+ {p.business_name}
+ </a>
+ </span>
+ </p>
);
})}
- </ul>
- <div>
+ </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
- onClick={() => reducer.transition("delete_policy", { policy_index })}
+ class="button is-danger block"
+ onClick={() =>
+ reducer.transition("delete_policy", { policy_index })
+ }
>
- Delete Policy
+ Delete
</button>
</div>
</div>