anastasis-webui: more auth types
This commit is contained in:
parent
aba71d0782
commit
9d6967dbab
@ -46,6 +46,7 @@ export interface ReducerStateRecovery {
|
|||||||
|
|
||||||
continents: any;
|
continents: any;
|
||||||
countries: any;
|
countries: any;
|
||||||
|
required_attributes: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ReducerStateError {
|
export interface ReducerStateError {
|
||||||
@ -74,6 +75,7 @@ export enum BackupStates {
|
|||||||
export enum RecoveryStates {
|
export enum RecoveryStates {
|
||||||
ContinentSelecting = "CONTINENT_SELECTING",
|
ContinentSelecting = "CONTINENT_SELECTING",
|
||||||
CountrySelecting = "COUNTRY_SELECTING",
|
CountrySelecting = "COUNTRY_SELECTING",
|
||||||
|
UserAttributesCollecting = "USER_ATTRIBUTES_COLLECTING",
|
||||||
}
|
}
|
||||||
|
|
||||||
const reducerBaseUrl = "http://localhost:5000/";
|
const reducerBaseUrl = "http://localhost:5000/";
|
||||||
|
@ -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 { FunctionalComponent, h } from "preact";
|
||||||
import { useState } from "preact/hooks";
|
import { useState } from "preact/hooks";
|
||||||
import {
|
import {
|
||||||
AnastasisReducerApi,
|
AnastasisReducerApi,
|
||||||
AuthMethod,
|
AuthMethod,
|
||||||
BackupStates,
|
BackupStates,
|
||||||
|
RecoveryStates,
|
||||||
ReducerStateBackup,
|
ReducerStateBackup,
|
||||||
ReducerStateRecovery,
|
ReducerStateRecovery,
|
||||||
useAnastasisReducer,
|
useAnastasisReducer,
|
||||||
@ -94,14 +99,23 @@ const Home: FunctionalComponent = () => {
|
|||||||
}
|
}
|
||||||
console.log("state", reducer.currentReducerState);
|
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} />;
|
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} />;
|
return <CountrySelection reducer={reducer} reducerState={reducerState} />;
|
||||||
}
|
}
|
||||||
if (reducerState.backup_state === BackupStates.UserAttributesCollecting) {
|
if (
|
||||||
return <AttributeEntry reducer={reducer} backupState={reducerState} />;
|
reducerState.backup_state === BackupStates.UserAttributesCollecting ||
|
||||||
|
reducerState.recovery_state === RecoveryStates.UserAttributesCollecting
|
||||||
|
) {
|
||||||
|
return <AttributeEntry reducer={reducer} reducerState={reducerState} />;
|
||||||
}
|
}
|
||||||
if (reducerState.backup_state === BackupStates.AuthenticationsEditing) {
|
if (reducerState.backup_state === BackupStates.AuthenticationsEditing) {
|
||||||
return (
|
return (
|
||||||
@ -305,6 +319,15 @@ interface AuthMethodSetupProps {
|
|||||||
|
|
||||||
function AuthMethodSmsSetup(props: AuthMethodSetupProps) {
|
function AuthMethodSmsSetup(props: AuthMethodSetupProps) {
|
||||||
const [mobileNumber, setMobileNumber] = useState("");
|
const [mobileNumber, setMobileNumber] = useState("");
|
||||||
|
const addSmsAuth = () => {
|
||||||
|
props.addAuthMethod({
|
||||||
|
authentication_method: {
|
||||||
|
type: "sms",
|
||||||
|
instructions: `SMS to ${mobileNumber}`,
|
||||||
|
challenge: encodeCrock(stringToBytes(mobileNumber)),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div class={style.home}>
|
<div class={style.home}>
|
||||||
<h1>Add {props.method} authentication</h1>
|
<h1>Add {props.method} authentication</h1>
|
||||||
@ -325,19 +348,7 @@ function AuthMethodSmsSetup(props: AuthMethodSetupProps) {
|
|||||||
</label>
|
</label>
|
||||||
<div>
|
<div>
|
||||||
<button onClick={() => props.cancel()}>Cancel</button>
|
<button onClick={() => props.cancel()}>Cancel</button>
|
||||||
<button
|
<button onClick={() => addSmsAuth()}>Add</button>
|
||||||
onClick={() =>
|
|
||||||
props.addAuthMethod({
|
|
||||||
authentication_method: {
|
|
||||||
type: "sms",
|
|
||||||
instructions: `SMS to ${mobileNumber}`,
|
|
||||||
challenge: "E1QPPS8A",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
>
|
|
||||||
Add
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</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) {
|
function AuthMethodNotImplemented(props: AuthMethodSetupProps) {
|
||||||
return (
|
return (
|
||||||
<div class={style.home}>
|
<div class={style.home}>
|
||||||
@ -452,7 +607,23 @@ function AuthenticationEditor(props: AuthenticationEditorProps) {
|
|||||||
<AuthMethodQuestionSetup
|
<AuthMethodQuestionSetup
|
||||||
cancel={cancel}
|
cancel={cancel}
|
||||||
addAuthMethod={addMethod}
|
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:
|
default:
|
||||||
@ -525,11 +696,11 @@ function AuthenticationEditor(props: AuthenticationEditorProps) {
|
|||||||
|
|
||||||
export interface AttributeEntryProps {
|
export interface AttributeEntryProps {
|
||||||
reducer: AnastasisReducerApi;
|
reducer: AnastasisReducerApi;
|
||||||
backupState: ReducerStateBackup;
|
reducerState: ReducerStateRecovery | ReducerStateBackup;
|
||||||
}
|
}
|
||||||
|
|
||||||
function AttributeEntry(props: AttributeEntryProps) {
|
function AttributeEntry(props: AttributeEntryProps) {
|
||||||
const { reducer, backupState } = props;
|
const { reducer, reducerState: backupState } = props;
|
||||||
const [attrs, setAttrs] = useState<Record<string, string>>({});
|
const [attrs, setAttrs] = useState<Record<string, string>>({});
|
||||||
return (
|
return (
|
||||||
<div class={style.home}>
|
<div class={style.home}>
|
||||||
|
Loading…
Reference in New Issue
Block a user