2021-11-10 19:43:15 +01:00
|
|
|
import { AuthenticationProviderStatusOk } from "anastasis-core";
|
2021-10-19 15:56:52 +02:00
|
|
|
import { h, VNode } from "preact";
|
2021-11-03 21:30:11 +01:00
|
|
|
import { useState } from "preact/hooks";
|
2021-11-12 17:26:05 +01:00
|
|
|
import { AsyncButton } from "../../components/AsyncButton";
|
2021-10-22 06:31:46 +02:00
|
|
|
import { useAnastasisContext } from "../../context/anastasis";
|
2021-11-02 16:31:37 +01:00
|
|
|
import { authMethods, KnownAuthMethods } from "./authMethod";
|
2021-11-12 17:26:05 +01:00
|
|
|
import { ConfirmModal } from "./ConfirmModal";
|
2021-11-03 21:30:11 +01:00
|
|
|
import { EditPoliciesScreen } from "./EditPoliciesScreen";
|
|
|
|
import { AnastasisClientFrame } from "./index";
|
2021-10-22 06:31:46 +02:00
|
|
|
|
|
|
|
export function ReviewPoliciesScreen(): VNode {
|
2021-11-10 14:20:52 +01:00
|
|
|
const [editingPolicy, setEditingPolicy] = useState<number | undefined>();
|
2021-11-12 17:26:05 +01:00
|
|
|
const [confirmReset, setConfirmReset] = useState(false);
|
2021-11-10 14:20:52 +01:00
|
|
|
const reducer = useAnastasisContext();
|
2021-10-22 06:31:46 +02:00
|
|
|
if (!reducer) {
|
2021-11-10 14:20:52 +01:00
|
|
|
return <div>no reducer in context</div>;
|
2021-10-22 06:31:46 +02:00
|
|
|
}
|
2021-11-10 14:20:52 +01:00
|
|
|
if (
|
|
|
|
!reducer.currentReducerState ||
|
|
|
|
reducer.currentReducerState.backup_state === undefined
|
|
|
|
) {
|
|
|
|
return <div>invalid state</div>;
|
2021-10-22 06:31:46 +02:00
|
|
|
}
|
2021-11-03 21:30:11 +01:00
|
|
|
|
2021-11-10 14:20:52 +01:00
|
|
|
const configuredAuthMethods =
|
|
|
|
reducer.currentReducerState.authentication_methods ?? [];
|
2021-10-22 06:31:46 +02:00
|
|
|
const policies = reducer.currentReducerState.policies ?? [];
|
2021-10-19 15:56:52 +02:00
|
|
|
|
2021-11-12 17:26:05 +01:00
|
|
|
const providers = reducer.currentReducerState.authentication_providers ?? {};
|
|
|
|
|
2021-11-03 21:30:11 +01:00
|
|
|
if (editingPolicy !== undefined) {
|
|
|
|
return (
|
|
|
|
<EditPoliciesScreen
|
|
|
|
index={editingPolicy}
|
|
|
|
cancel={() => setEditingPolicy(undefined)}
|
2021-11-05 15:26:12 +01:00
|
|
|
confirm={async (newMethods) => {
|
|
|
|
await reducer.transition("update_policy", {
|
|
|
|
policy_index: editingPolicy,
|
|
|
|
policy: newMethods,
|
2021-11-03 21:30:11 +01:00
|
|
|
});
|
2021-11-10 14:20:52 +01:00
|
|
|
setEditingPolicy(undefined);
|
2021-11-03 21:30:11 +01:00
|
|
|
}}
|
|
|
|
/>
|
2021-11-10 14:20:52 +01:00
|
|
|
);
|
2021-11-03 21:30:11 +01:00
|
|
|
}
|
2021-11-12 17:26:05 +01:00
|
|
|
async function resetPolicies(): Promise<void> {
|
|
|
|
if (!reducer) return Promise.resolve();
|
|
|
|
return reducer.runTransaction(async (tx) => {
|
|
|
|
await tx.transition("back", {});
|
|
|
|
await tx.transition("next", {});
|
|
|
|
setConfirmReset(false);
|
|
|
|
});
|
|
|
|
}
|
2021-11-03 21:30:11 +01:00
|
|
|
|
2021-11-10 14:20:52 +01:00
|
|
|
const errors = policies.length < 1 ? "Need more policies" : undefined;
|
2021-10-19 15:56:52 +02:00
|
|
|
return (
|
2021-11-10 14:20:52 +01:00
|
|
|
<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>
|
|
|
|
)}
|
2021-11-12 17:26:05 +01:00
|
|
|
<div class="block">
|
|
|
|
<AsyncButton class="button" onClick={async () => setConfirmReset(true)}>
|
|
|
|
Reset policies
|
|
|
|
</AsyncButton>
|
2021-11-10 14:20:52 +01:00
|
|
|
<button
|
|
|
|
class="button is-success"
|
2021-11-12 17:26:05 +01:00
|
|
|
style={{ marginLeft: 10 }}
|
2021-11-10 15:40:56 +01:00
|
|
|
onClick={() => setEditingPolicy(policies.length)}
|
2021-11-10 14:20:52 +01:00
|
|
|
>
|
|
|
|
Add new policy
|
|
|
|
</button>
|
2021-11-03 21:30:11 +01:00
|
|
|
</div>
|
2021-10-22 06:31:46 +02:00
|
|
|
{policies.map((p, policy_index) => {
|
|
|
|
const methods = p.methods
|
2021-11-10 14:20:52 +01:00
|
|
|
.map(
|
|
|
|
(x) =>
|
|
|
|
configuredAuthMethods[x.authentication_method] && {
|
|
|
|
...configuredAuthMethods[x.authentication_method],
|
|
|
|
provider: x.provider,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
.filter((x) => !!x);
|
2021-10-22 06:31:46 +02:00
|
|
|
|
2021-11-10 14:20:52 +01:00
|
|
|
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;
|
|
|
|
}
|
2021-10-22 06:31:46 +02:00
|
|
|
|
2021-10-19 15:56:52 +02:00
|
|
|
return (
|
2021-11-10 14:20:52 +01:00
|
|
|
<div
|
|
|
|
key={policy_index}
|
|
|
|
class="box"
|
|
|
|
style={{ display: "flex", justifyContent: "space-between" }}
|
|
|
|
>
|
2021-11-01 20:10:49 +01:00
|
|
|
<div>
|
|
|
|
<h3 class="subtitle">
|
|
|
|
Policy #{policy_index + 1}: {policyName}
|
|
|
|
</h3>
|
2021-11-10 14:20:52 +01:00
|
|
|
{!methods.length && <p>No auth method found</p>}
|
2021-10-22 06:31:46 +02:00
|
|
|
{methods.map((m, i) => {
|
2021-11-12 17:26:05 +01:00
|
|
|
const p = providers[
|
|
|
|
m.provider
|
|
|
|
] as AuthenticationProviderStatusOk;
|
2021-10-19 15:56:52 +02:00
|
|
|
return (
|
2021-11-10 14:20:52 +01:00
|
|
|
<p
|
|
|
|
key={i}
|
|
|
|
class="block"
|
|
|
|
style={{ display: "flex", alignItems: "center" }}
|
|
|
|
>
|
2021-11-03 21:30:11 +01:00
|
|
|
<span class="icon">
|
|
|
|
{authMethods[m.type as KnownAuthMethods]?.icon}
|
|
|
|
</span>
|
|
|
|
<span>
|
2021-11-10 14:20:52 +01:00
|
|
|
{m.instructions} recovery provided by{" "}
|
2021-11-12 17:26:05 +01:00
|
|
|
<a href={m.provider} target="_blank" rel="noreferrer">
|
|
|
|
{p.business_name}
|
|
|
|
</a>
|
2021-11-03 21:30:11 +01:00
|
|
|
</span>
|
|
|
|
</p>
|
2021-10-19 15:56:52 +02:00
|
|
|
);
|
|
|
|
})}
|
|
|
|
</div>
|
2021-11-10 14:20:52 +01:00
|
|
|
<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>
|
2021-11-03 21:30:11 +01:00
|
|
|
</div>
|
2021-10-19 15:56:52 +02:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
})}
|
2021-11-12 17:26:05 +01:00
|
|
|
{confirmReset && (
|
|
|
|
<ConfirmModal
|
|
|
|
active
|
|
|
|
onCancel={() => setConfirmReset(false)}
|
|
|
|
description="Do you want to reset the policies to default state?"
|
|
|
|
label="Reset policies"
|
|
|
|
cancelLabel="Cancel"
|
|
|
|
onConfirm={resetPolicies}
|
|
|
|
>
|
|
|
|
<p>
|
|
|
|
All policies will be recalculated based on the authentication
|
|
|
|
providers configured and any change that you did will be lost
|
|
|
|
</p>
|
|
|
|
</ConfirmModal>
|
|
|
|
)}
|
2021-10-19 15:56:52 +02:00
|
|
|
</AnastasisClientFrame>
|
|
|
|
);
|
|
|
|
}
|