Add call verification

This commit is contained in:
binwiederhier 2023-05-16 22:27:48 -04:00
parent 496d6e74b0
commit 2c81773d01
11 changed files with 93 additions and 74 deletions

View file

@ -188,17 +188,20 @@
"account_basics_password_dialog_button_submit": "Change password",
"account_basics_password_dialog_current_password_incorrect": "Password incorrect",
"account_basics_phone_numbers_title": "Phone numbers",
"account_basics_phone_numbers_dialog_description": "To use the call notification feature, you need to add and verify at least one phone number. Adding it will send a verification SMS to your phone.",
"account_basics_phone_numbers_dialog_description": "To use the call notification feature, you need to add and verify at least one phone number. Verification can be done via SMS or a phone call.",
"account_basics_phone_numbers_description": "For phone call notifications",
"account_basics_phone_numbers_no_phone_numbers_yet": "No phone numbers yet",
"account_basics_phone_numbers_copied_to_clipboard": "Phone number copied to clipboard",
"account_basics_phone_numbers_dialog_title": "Add phone number",
"account_basics_phone_numbers_dialog_number_label": "Phone number",
"account_basics_phone_numbers_dialog_number_placeholder": "e.g. +1222333444",
"account_basics_phone_numbers_dialog_send_verification_button": "Send verification",
"account_basics_phone_numbers_dialog_verify_button_sms": "Send SMS",
"account_basics_phone_numbers_dialog_verify_button_call": "Call me",
"account_basics_phone_numbers_dialog_code_label": "Verification code",
"account_basics_phone_numbers_dialog_code_placeholder": "e.g. 123456",
"account_basics_phone_numbers_dialog_check_verification_button": "Confirm code",
"account_basics_phone_numbers_dialog_channel_sms": "SMS",
"account_basics_phone_numbers_dialog_channel_call": "Call",
"account_usage_title": "Usage",
"account_usage_of_limit": "of {{limit}}",
"account_usage_unlimited": "Unlimited",

View file

@ -299,14 +299,15 @@ class AccountApi {
return await response.json(); // May throw SyntaxError
}
async verifyPhoneNumber(phoneNumber) {
async verifyPhoneNumber(phoneNumber, channel) {
const url = accountPhoneVerifyUrl(config.base_url);
console.log(`[AccountApi] Sending phone verification ${url}`);
await fetchOrThrow(url, {
method: "PUT",
headers: withBearerAuth({}, session.token()),
body: JSON.stringify({
number: phoneNumber
number: phoneNumber,
channel: channel
})
});
}

View file

@ -1,13 +1,13 @@
import * as React from 'react';
import {useContext, useState} from 'react';
import {
Alert,
Alert, ButtonGroup,
CardActions,
CardContent, Chip,
FormControl,
FormControl, FormControlLabel, InputLabel,
LinearProgress,
Link,
Portal,
Portal, Radio, RadioGroup,
Select,
Snackbar,
Stack,
@ -47,12 +47,14 @@ import {AccountContext} from "./App";
import DialogFooter from "./DialogFooter";
import {Paragraph} from "./styles";
import CloseIcon from "@mui/icons-material/Close";
import {ContentCopy, Public} from "@mui/icons-material";
import {Check, ContentCopy, DeleteForever, Public} from "@mui/icons-material";
import MenuItem from "@mui/material/MenuItem";
import DialogContentText from "@mui/material/DialogContentText";
import {IncorrectPasswordError, UnauthorizedError} from "../app/errors";
import {ProChip} from "./SubscriptionPopup";
import AddIcon from "@mui/icons-material/Add";
import ListItemIcon from "@mui/material/ListItemIcon";
import ListItemText from "@mui/material/ListItemText";
const Account = () => {
if (!session.exists()) {
@ -408,6 +410,7 @@ const AddPhoneNumberDialog = (props) => {
const { t } = useTranslation();
const [error, setError] = useState("");
const [phoneNumber, setPhoneNumber] = useState("");
const [channel, setChannel] = useState("sms");
const [code, setCode] = useState("");
const [sending, setSending] = useState(false);
const [verificationCodeSent, setVerificationCodeSent] = useState(false);
@ -432,7 +435,7 @@ const AddPhoneNumberDialog = (props) => {
const verifyPhone = async () => {
try {
setSending(true);
await accountApi.verifyPhoneNumber(phoneNumber);
await accountApi.verifyPhoneNumber(phoneNumber, channel);
setVerificationCodeSent(true);
} catch (e) {
console.log(`[Account] Error sending verification`, e);
@ -471,18 +474,26 @@ const AddPhoneNumberDialog = (props) => {
{t("account_basics_phone_numbers_dialog_description")}
</DialogContentText>
{!verificationCodeSent &&
<TextField
margin="dense"
label={t("account_basics_phone_numbers_dialog_number_label")}
aria-label={t("account_basics_phone_numbers_dialog_number_label")}
placeholder={t("account_basics_phone_numbers_dialog_number_placeholder")}
type="tel"
value={phoneNumber}
onChange={ev => setPhoneNumber(ev.target.value)}
fullWidth
inputProps={{ inputMode: 'tel', pattern: '\+[0-9]*' }}
variant="standard"
/>
<div style={{display: "flex"}}>
<TextField
margin="dense"
label={t("account_basics_phone_numbers_dialog_number_label")}
aria-label={t("account_basics_phone_numbers_dialog_number_label")}
placeholder={t("account_basics_phone_numbers_dialog_number_placeholder")}
type="tel"
value={phoneNumber}
onChange={ev => setPhoneNumber(ev.target.value)}
inputProps={{ inputMode: 'tel', pattern: '\+[0-9]*' }}
variant="standard"
sx={{ flexGrow: 1 }}
/>
<FormControl sx={{ flexWrap: "nowrap" }}>
<RadioGroup row sx={{ flexGrow: 1, marginTop: "8px", marginLeft: "5px" }}>
<FormControlLabel value="sms" control={<Radio checked={channel === "sms"} onChange={(e) => setChannel(e.target.value)} />} label={t("account_basics_phone_numbers_dialog_channel_sms")} />
<FormControlLabel value="call" control={<Radio checked={channel === "call"} onChange={(e) => setChannel(e.target.value)} />} label={t("account_basics_phone_numbers_dialog_channel_call")} sx={{ marginRight: 0 }} />
</RadioGroup>
</FormControl>
</div>
}
{verificationCodeSent &&
<TextField
@ -502,7 +513,9 @@ const AddPhoneNumberDialog = (props) => {
<DialogFooter status={error}>
<Button onClick={handleCancel}>{verificationCodeSent ? t("common_back") : t("common_cancel")}</Button>
<Button onClick={handleDialogSubmit} disabled={sending || !/^\+\d+$/.test(phoneNumber)}>
{verificationCodeSent ?t("account_basics_phone_numbers_dialog_check_verification_button") : t("account_basics_phone_numbers_dialog_send_verification_button")}
{!verificationCodeSent && channel === "sms" && t("account_basics_phone_numbers_dialog_verify_button_sms")}
{!verificationCodeSent && channel === "call" && t("account_basics_phone_numbers_dialog_verify_button_call")}
{verificationCodeSent && t("account_basics_phone_numbers_dialog_check_verification_button")}
</Button>
</DialogFooter>
</Dialog>