diff --git a/packages/anastasis-webui/src/hooks/use-anastasis-reducer.ts b/packages/anastasis-webui/src/hooks/use-anastasis-reducer.ts
index d578d1418..6ca0ccfae 100644
--- a/packages/anastasis-webui/src/hooks/use-anastasis-reducer.ts
+++ b/packages/anastasis-webui/src/hooks/use-anastasis-reducer.ts
@@ -46,6 +46,7 @@ export interface ReducerStateRecovery {
continents: any;
countries: any;
+ required_attributes: any;
}
export interface ReducerStateError {
@@ -74,6 +75,7 @@ export enum BackupStates {
export enum RecoveryStates {
ContinentSelecting = "CONTINENT_SELECTING",
CountrySelecting = "COUNTRY_SELECTING",
+ UserAttributesCollecting = "USER_ATTRIBUTES_COLLECTING",
}
const reducerBaseUrl = "http://localhost:5000/";
diff --git a/packages/anastasis-webui/src/routes/home/index.tsx b/packages/anastasis-webui/src/routes/home/index.tsx
index f61897682..f0b630851 100644
--- a/packages/anastasis-webui/src/routes/home/index.tsx
+++ b/packages/anastasis-webui/src/routes/home/index.tsx
@@ -1,10 +1,15 @@
-import { encodeCrock, stringToBytes } from "@gnu-taler/taler-util";
+import {
+ canonicalJson,
+ encodeCrock,
+ stringToBytes,
+} from "@gnu-taler/taler-util";
import { FunctionalComponent, h } from "preact";
import { useState } from "preact/hooks";
import {
AnastasisReducerApi,
AuthMethod,
BackupStates,
+ RecoveryStates,
ReducerStateBackup,
ReducerStateRecovery,
useAnastasisReducer,
@@ -94,14 +99,23 @@ const Home: FunctionalComponent = () => {
}
console.log("state", reducer.currentReducerState);
- if (reducerState.backup_state === BackupStates.ContinentSelecting) {
+ if (
+ reducerState.backup_state === BackupStates.ContinentSelecting ||
+ reducerState.recovery_state === RecoveryStates.ContinentSelecting
+ ) {
return ;
}
- if (reducerState.backup_state === BackupStates.CountrySelecting) {
+ if (
+ reducerState.backup_state === BackupStates.CountrySelecting ||
+ reducerState.recovery_state === RecoveryStates.CountrySelecting
+ ) {
return ;
}
- if (reducerState.backup_state === BackupStates.UserAttributesCollecting) {
- return ;
+ if (
+ reducerState.backup_state === BackupStates.UserAttributesCollecting ||
+ reducerState.recovery_state === RecoveryStates.UserAttributesCollecting
+ ) {
+ return ;
}
if (reducerState.backup_state === BackupStates.AuthenticationsEditing) {
return (
@@ -305,6 +319,15 @@ interface AuthMethodSetupProps {
function AuthMethodSmsSetup(props: AuthMethodSetupProps) {
const [mobileNumber, setMobileNumber] = useState("");
+ const addSmsAuth = () => {
+ props.addAuthMethod({
+ authentication_method: {
+ type: "sms",
+ instructions: `SMS to ${mobileNumber}`,
+ challenge: encodeCrock(stringToBytes(mobileNumber)),
+ },
+ });
+ };
return (
Add {props.method} authentication
@@ -325,19 +348,7 @@ function AuthMethodSmsSetup(props: AuthMethodSetupProps) {
props.cancel()}>Cancel
-
- props.addAuthMethod({
- authentication_method: {
- type: "sms",
- instructions: `SMS to ${mobileNumber}`,
- challenge: "E1QPPS8A",
- },
- })
- }
- >
- Add
-
+ addSmsAuth()}>Add
@@ -400,6 +411,150 @@ function AuthMethodQuestionSetup(props: AuthMethodSetupProps) {
);
}
+function AuthMethodEmailSetup(props: AuthMethodSetupProps) {
+ const [email, setEmail] = useState("");
+ return (
+
+
Add {props.method} authentication
+
+
+ For email authentication, you need to provid an email address. When
+ recovering your secret, you need to enter the code you will receive by
+ email.
+
+
+
+ Email address
+ setEmail((e.target as any).value)}
+ type="text"
+ />
+
+
+
+ props.cancel()}>Cancel
+
+ props.addAuthMethod({
+ authentication_method: {
+ type: "email",
+ instructions: `Email to ${email}`,
+ challenge: encodeCrock(stringToBytes(email)),
+ },
+ })
+ }
+ >
+ Add
+
+
+
+
+ );
+}
+
+function AuthMethodPostSetup(props: AuthMethodSetupProps) {
+ const [fullName, setFullName] = useState("");
+ const [street, setStreet] = useState("");
+ const [city, setCity] = useState("");
+ const [postcode, setPostcode] = useState("");
+ const [country, setCountry] = useState("");
+ return (
+
+
Add {props.method} authentication
+
+
+ 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.
+
+
+
+ Full Name
+ setFullName((e.target as any).value)}
+ type="text"
+ />
+
+
+
+
+ Street
+ setStreet((e.target as any).value)}
+ type="text"
+ />
+
+
+
+
+ City
+ setCity((e.target as any).value)}
+ type="text"
+ />
+
+
+
+
+ Postal Code
+ setPostcode((e.target as any).value)}
+ type="text"
+ />
+
+
+
+
+ Country
+ setCountry((e.target as any).value)}
+ type="text"
+ />
+
+
+
+ props.cancel()}>Cancel
+
+ props.addAuthMethod({
+ authentication_method: {
+ type: "email",
+ instructions: `Letter to address in postal code ${postcode}`,
+ challenge: encodeCrock(
+ stringToBytes(
+ canonicalJson({
+ full_name: fullName,
+ street,
+ city,
+ postcode,
+ country,
+ }),
+ ),
+ ),
+ },
+ })
+ }
+ >
+ Add
+
+
+
+
+ );
+}
+
function AuthMethodNotImplemented(props: AuthMethodSetupProps) {
return (
@@ -452,7 +607,23 @@ function AuthenticationEditor(props: AuthenticationEditorProps) {
+ );
+ case "email":
+ return (
+
+ );
+ case "post":
+ return (
+
);
default:
@@ -525,11 +696,11 @@ function AuthenticationEditor(props: AuthenticationEditorProps) {
export interface AttributeEntryProps {
reducer: AnastasisReducerApi;
- backupState: ReducerStateBackup;
+ reducerState: ReducerStateRecovery | ReducerStateBackup;
}
function AttributeEntry(props: AttributeEntryProps) {
- const { reducer, backupState } = props;
+ const { reducer, reducerState: backupState } = props;
const [attrs, setAttrs] = useState
>({});
return (