This commit is contained in:
Sebastian 2022-01-24 16:47:37 -03:00
parent 171d070a83
commit 1374b37d26
No known key found for this signature in database
GPG Key ID: BE4FF68352439FC1
9 changed files with 133 additions and 25 deletions

View File

@ -39,15 +39,15 @@ export const Backup = createExample(TestedComponent, {
...reducerStatesExample.backupAttributeEditing,
required_attributes: [
{
name: "first name",
label: "first",
name: "full_name",
label: "Full name",
type: "string",
uuid: "asdasdsa1",
widget: "wid",
},
{
name: "last name",
label: "second",
name: "birthplace",
label: "Birthplace",
type: "string",
uuid: "asdasdsa2",
widget: "wid",
@ -66,15 +66,15 @@ export const Recovery = createExample(TestedComponent, {
...reducerStatesExample.recoveryAttributeEditing,
required_attributes: [
{
name: "first",
label: "first",
name: "full_name",
label: "Full name",
type: "string",
uuid: "asdasdsa1",
widget: "wid",
},
{
name: "pepe",
label: "second",
name: "birthplace",
label: "Birthplace",
type: "string",
uuid: "asdasdsa2",
widget: "wid",

View File

@ -1,6 +1,6 @@
import { UserAttributeSpec, validators } from "@gnu-taler/anastasis-core";
import { isAfter, parse } from "date-fns";
import { h, VNode } from "preact";
import { Fragment, h, VNode } from "preact";
import { useState } from "preact/hooks";
import { DateInput } from "../../components/fields/DateInput";
import { PhoneNumberInput } from "../../components/fields/NumberInput";
@ -122,7 +122,7 @@ for (let i = 0; i < 100; i++) {
}
function AttributeEntryField(props: AttributeEntryFieldProps): VNode {
return (
<div>
<div style={{ marginTop: 16 }}>
{props.spec.type === "date" && (
<DateInput
grabFocus={props.isFirst}
@ -151,6 +151,17 @@ function AttributeEntryField(props: AttributeEntryFieldProps): VNode {
bind={[props.value, props.setValue]}
/>
)}
{props.spec.type === "string" && (
<div>
This field is case-sensitive. You must enter exactly the same value
during recovery.
</div>
)}
{props.spec.name === "full_name" && (
<div>
If possible, use "LASTNAME, Firstname(s)" without abbreviations.
</div>
)}
<div class="block">
This stays private
<span class="icon is-right">

View File

@ -75,11 +75,15 @@ export function SecretEditorScreen(): VNode {
<div class="block">
<TextInput
label="Secret name:"
tooltip="The secret name allows you to identify your secret when restoring it. It is a label that you can choose freely."
tooltip="This allows you to uniquely identify a secret if you have made multiple back ups. The value entered here will NOT be protected by the authentication checks!"
grabFocus
onConfirm={goNextIfNoErrors}
bind={[secretName, setSecretName]}
/>
<div>
Names should be unique, so that you can easily identify your secret
later.
</div>
</div>
<div class="block">
<TextInput

View File

@ -12,7 +12,28 @@ import { SolveOverviewFeedbackDisplay } from "../SolveScreen";
import { AuthMethodSolveProps } from "./index";
export function AuthMethodEmailSolve({ id }: AuthMethodSolveProps): VNode {
const [answer, setAnswer] = useState("A-");
const [answer, _setAnswer] = useState("A-");
function setAnswer(str: string): void {
//A-12345-678-1234-5678
const unformatted = str
.replace(/^A-/, "")
.replace(/-/g, "")
.toLocaleUpperCase();
let result = `A-${unformatted.substring(0, 5)}`;
if (unformatted.length > 5) {
result += `-${unformatted.substring(5, 8)}`;
}
if (unformatted.length > 8) {
result += `-${unformatted.substring(8, 12)}`;
}
if (unformatted.length > 12) {
result += `-${unformatted.substring(12, 16)}`;
}
_setAnswer(result);
}
const [expanded, setExpanded] = useState(false);
const reducer = useAnastasisContext();
@ -77,7 +98,9 @@ export function AuthMethodEmailSolve({ id }: AuthMethodSolveProps): VNode {
const feedback = challengeFeedback[selectedUuid];
async function onNext(): Promise<void> {
return reducer?.transition("solve_challenge", { answer });
return reducer?.transition("solve_challenge", {
answer: `A-${answer.replace(/^A-/, "").replace(/-/g, "").trim()}`,
});
}
function onCancel(): void {
reducer?.back();
@ -127,7 +150,7 @@ export function AuthMethodEmailSolve({ id }: AuthMethodSolveProps): VNode {
grabFocus
onConfirm={onNext}
bind={[answer, setAnswer]}
placeholder="A-1234567812345678"
placeholder="A-12345-678-1234-5678"
/>
<div

View File

@ -12,7 +12,28 @@ import { SolveOverviewFeedbackDisplay } from "../SolveScreen";
import { AuthMethodSolveProps } from "./index";
export function AuthMethodPostSolve({ id }: AuthMethodSolveProps): VNode {
const [answer, setAnswer] = useState("A-");
const [answer, _setAnswer] = useState("A-");
function setAnswer(str: string): void {
//A-12345-678-1234-5678
const unformatted = str
.replace(/^A-/, "")
.replace(/-/g, "")
.toLocaleUpperCase();
let result = `A-${unformatted.substring(0, 5)}`;
if (unformatted.length > 5) {
result += `-${unformatted.substring(5, 8)}`;
}
if (unformatted.length > 8) {
result += `-${unformatted.substring(8, 12)}`;
}
if (unformatted.length > 12) {
result += `-${unformatted.substring(12, 16)}`;
}
_setAnswer(result);
}
const reducer = useAnastasisContext();
if (!reducer) {
@ -76,7 +97,9 @@ export function AuthMethodPostSolve({ id }: AuthMethodSolveProps): VNode {
const feedback = challengeFeedback[selectedUuid];
async function onNext(): Promise<void> {
return reducer?.transition("solve_challenge", { answer });
return reducer?.transition("solve_challenge", {
answer: `A-${answer.replace(/^A-/, "").replace(/-/g, "").trim()}`,
});
}
function onCancel(): void {
reducer?.back();
@ -96,6 +119,7 @@ export function AuthMethodPostSolve({ id }: AuthMethodSolveProps): VNode {
onConfirm={onNext}
label="Answer"
grabFocus
placeholder="A-12345-678-1234-5678"
bind={[answer, setAnswer]}
/>

View File

@ -5,12 +5,18 @@ import { AuthMethodSetupProps } from ".";
import { PhoneNumberInput } from "../../../components/fields/NumberInput";
import { AnastasisClientFrame } from "../index";
const REGEX_JUST_NUMBERS = /^\+[0-9 ]*$/;
function isJustNumbers(str: string): boolean {
return REGEX_JUST_NUMBERS.test(str);
}
export function AuthMethodSmsSetup({
addAuthMethod,
cancel,
configured,
}: AuthMethodSetupProps): VNode {
const [mobileNumber, setMobileNumber] = useState("");
const [mobileNumber, setMobileNumber] = useState("+");
const addSmsAuth = (): void => {
addAuthMethod({
authentication_method: {
@ -24,7 +30,13 @@ export function AuthMethodSmsSetup({
useLayoutEffect(() => {
inputRef.current?.focus();
}, []);
const errors = !mobileNumber ? "Add a mobile number" : undefined;
const errors = !mobileNumber
? "Add a mobile number"
: !mobileNumber.startsWith("+")
? "Mobile number should start with '+'"
: !isJustNumbers(mobileNumber)
? "Mobile number can't have other than numbers"
: undefined;
function goNextIfNoErrors(): void {
if (!errors) addSmsAuth();
}
@ -41,9 +53,13 @@ export function AuthMethodSmsSetup({
label="Mobile number"
placeholder="Your mobile number"
onConfirm={goNextIfNoErrors}
error={errors}
grabFocus
bind={[mobileNumber, setMobileNumber]}
/>
<div>
Enter mobile number including +CC international dialing prefix.
</div>
</div>
{configured.length > 0 && (
<section class="section">

View File

@ -50,14 +50,15 @@ export const WithoutFeedback = createExample(
cost: "USD:1",
instructions: "SMS to +54 11 2233 4455",
type: "question",
uuid: "uuid-1",
uuid: "AHCC4ZJ3Z1AF8TWBKGVGEKCQ3R7HXHJ51MJ45NHNZMHYZTKJ9NW0",
},
],
policies: [],
},
selected_challenge_uuid: "uuid-1",
selected_challenge_uuid:
"AHCC4ZJ3Z1AF8TWBKGVGEKCQ3R7HXHJ51MJ45NHNZMHYZTKJ9NW0",
} as ReducerState,
{
id: "uuid-1",
id: "AHCC4ZJ3Z1AF8TWBKGVGEKCQ3R7HXHJ51MJ45NHNZMHYZTKJ9NW0",
},
);

View File

@ -12,7 +12,28 @@ import { SolveOverviewFeedbackDisplay } from "../SolveScreen";
import { AuthMethodSolveProps } from "./index";
export function AuthMethodSmsSolve({ id }: AuthMethodSolveProps): VNode {
const [answer, setAnswer] = useState("A-");
const [answer, _setAnswer] = useState("A-");
function setAnswer(str: string): void {
//A-12345-678-1234-5678
const unformatted = str
.replace(/^A-/, "")
.replace(/-/g, "")
.toLocaleUpperCase();
let result = `A-${unformatted.substring(0, 5)}`;
if (unformatted.length > 5) {
result += `-${unformatted.substring(5, 8)}`;
}
if (unformatted.length > 8) {
result += `-${unformatted.substring(8, 12)}`;
}
if (unformatted.length > 12) {
result += `-${unformatted.substring(12, 16)}`;
}
_setAnswer(result);
}
const [expanded, setExpanded] = useState(false);
const reducer = useAnastasisContext();
@ -77,7 +98,9 @@ export function AuthMethodSmsSolve({ id }: AuthMethodSolveProps): VNode {
const feedback = challengeFeedback[selectedUuid];
async function onNext(): Promise<void> {
return reducer?.transition("solve_challenge", { answer });
return reducer?.transition("solve_challenge", {
answer: `A-${answer.replace(/^A-/, "").replace(/-/g, "").trim()}`,
});
}
function onCancel(): void {
reducer?.back();
@ -127,7 +150,7 @@ export function AuthMethodSmsSolve({ id }: AuthMethodSolveProps): VNode {
grabFocus
onConfirm={onNext}
bind={[answer, setAnswer]}
placeholder="A-1234567812345678"
placeholder="A-12345-678-1234-5678"
/>
<div

View File

@ -55,13 +55,19 @@ export function AuthMethodTotpSetup({
<QR text={totpURL} />
</div>
<p>
After scanning the code with your TOTP App, test it in the input below.
Confirm that your TOTP App works by entering the current 8-digit TOTP
code here:
</p>
<TextInput
label="Test code"
onConfirm={goNextIfNoErrors}
bind={[test, setTest]}
/>
<div>
We note that Google's implementation of TOTP is incomplete and will not
work. We recommend using FreeOTP+.
</div>
{configured.length > 0 && (
<section class="section">
<div class="block">Your TOTP numbers:</div>