aboutsummaryrefslogtreecommitdiff
path: root/packages/anastasis-webui
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2021-10-13 11:35:24 +0200
committerFlorian Dold <florian@dold.me>2021-10-13 11:35:24 +0200
commit9d6967dbab45c973470bb0f930a551c1f387f9d1 (patch)
treea57d009f9d4951a7ab984002f7ee32070bc8ed04 /packages/anastasis-webui
parentaba71d07826e5396b1387eccd61093e2ac454b8c (diff)
anastasis-webui: more auth types
Diffstat (limited to 'packages/anastasis-webui')
-rw-r--r--packages/anastasis-webui/src/hooks/use-anastasis-reducer.ts2
-rw-r--r--packages/anastasis-webui/src/routes/home/index.tsx213
2 files changed, 194 insertions, 21 deletions
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 <ContinentSelection reducer={reducer} reducerState={reducerState} />;
}
- if (reducerState.backup_state === BackupStates.CountrySelecting) {
+ if (
+ reducerState.backup_state === BackupStates.CountrySelecting ||
+ reducerState.recovery_state === RecoveryStates.CountrySelecting
+ ) {
return <CountrySelection reducer={reducer} reducerState={reducerState} />;
}
- if (reducerState.backup_state === BackupStates.UserAttributesCollecting) {
- return <AttributeEntry reducer={reducer} backupState={reducerState} />;
+ if (
+ reducerState.backup_state === BackupStates.UserAttributesCollecting ||
+ reducerState.recovery_state === RecoveryStates.UserAttributesCollecting
+ ) {
+ return <AttributeEntry reducer={reducer} reducerState={reducerState} />;
}
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 (
<div class={style.home}>
<h1>Add {props.method} authentication</h1>
@@ -325,19 +348,7 @@ function AuthMethodSmsSetup(props: AuthMethodSetupProps) {
</label>
<div>
<button onClick={() => props.cancel()}>Cancel</button>
- <button
- onClick={() =>
- props.addAuthMethod({
- authentication_method: {
- type: "sms",
- instructions: `SMS to ${mobileNumber}`,
- challenge: "E1QPPS8A",
- },
- })
- }
- >
- Add
- </button>
+ <button onClick={() => addSmsAuth()}>Add</button>
</div>
</div>
</div>
@@ -400,6 +411,150 @@ function AuthMethodQuestionSetup(props: AuthMethodSetupProps) {
);
}
+function AuthMethodEmailSetup(props: AuthMethodSetupProps) {
+ const [email, setEmail] = useState("");
+ return (
+ <div class={style.home}>
+ <h1>Add {props.method} authentication</h1>
+ <div>
+ <p>
+ 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.
+ </p>
+ <div>
+ <label>
+ Email address
+ <input
+ value={email}
+ autoFocus
+ onChange={(e) => setEmail((e.target as any).value)}
+ type="text"
+ />
+ </label>
+ </div>
+ <div>
+ <button onClick={() => props.cancel()}>Cancel</button>
+ <button
+ onClick={() =>
+ props.addAuthMethod({
+ authentication_method: {
+ type: "email",
+ instructions: `Email to ${email}`,
+ challenge: encodeCrock(stringToBytes(email)),
+ },
+ })
+ }
+ >
+ Add
+ </button>
+ </div>
+ </div>
+ </div>
+ );
+}
+
+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 (
+ <div class={style.home}>
+ <h1>Add {props.method} authentication</h1>
+ <div>
+ <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.
+ </p>
+ <div>
+ <label>
+ Full Name
+ <input
+ value={fullName}
+ autoFocus
+ onChange={(e) => setFullName((e.target as any).value)}
+ type="text"
+ />
+ </label>
+ </div>
+ <div>
+ <label>
+ Street
+ <input
+ value={street}
+ autoFocus
+ onChange={(e) => setStreet((e.target as any).value)}
+ type="text"
+ />
+ </label>
+ </div>
+ <div>
+ <label>
+ City
+ <input
+ value={city}
+ autoFocus
+ onChange={(e) => setCity((e.target as any).value)}
+ type="text"
+ />
+ </label>
+ </div>
+ <div>
+ <label>
+ Postal Code
+ <input
+ value={postcode}
+ autoFocus
+ onChange={(e) => setPostcode((e.target as any).value)}
+ type="text"
+ />
+ </label>
+ </div>
+ <div>
+ <label>
+ Country
+ <input
+ value={country}
+ autoFocus
+ onChange={(e) => setCountry((e.target as any).value)}
+ type="text"
+ />
+ </label>
+ </div>
+ <div>
+ <button onClick={() => props.cancel()}>Cancel</button>
+ <button
+ onClick={() =>
+ 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
+ </button>
+ </div>
+ </div>
+ </div>
+ );
+}
+
function AuthMethodNotImplemented(props: AuthMethodSetupProps) {
return (
<div class={style.home}>
@@ -452,7 +607,23 @@ function AuthenticationEditor(props: AuthenticationEditorProps) {
<AuthMethodQuestionSetup
cancel={cancel}
addAuthMethod={addMethod}
- method="sms"
+ method="question"
+ />
+ );
+ case "email":
+ return (
+ <AuthMethodEmailSetup
+ cancel={cancel}
+ addAuthMethod={addMethod}
+ method="email"
+ />
+ );
+ case "post":
+ return (
+ <AuthMethodPostSetup
+ cancel={cancel}
+ addAuthMethod={addMethod}
+ method="post"
/>
);
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<Record<string, string>>({});
return (
<div class={style.home}>