fix(app): add masking of phones to settings
This commit is contained in:
parent
a129b162b7
commit
2db53689a1
@ -37,6 +37,7 @@ const AccountSecurityTab: React.FC = observer(() => {
|
||||
const {t} = useLingui();
|
||||
const user = UserStore.currentUser;
|
||||
const [showMaskedEmail, setShowMaskedEmail] = useState(false);
|
||||
const [showMaskedPhone, setShowMaskedPhone] = useState(false);
|
||||
const [passkeys, setPasskeys] = useState<Array<UserActionCreators.WebAuthnCredential>>([]);
|
||||
const [loadingPasskeys, setLoadingPasskeys] = useState(false);
|
||||
const [enablingSmsMfa, setEnablingSmsMfa] = useState(false);
|
||||
@ -100,9 +101,11 @@ const AccountSecurityTab: React.FC = observer(() => {
|
||||
loadingPasskeys={loadingPasskeys}
|
||||
enablingSmsMfa={enablingSmsMfa}
|
||||
disablingSmsMfa={disablingSmsMfa}
|
||||
showMaskedPhone={showMaskedPhone}
|
||||
loadPasskeys={loadPasskeys}
|
||||
setEnablingSmsMfa={setEnablingSmsMfa}
|
||||
setDisablingSmsMfa={setDisablingSmsMfa}
|
||||
setShowMaskedPhone={setShowMaskedPhone}
|
||||
/>
|
||||
</SettingsSection>
|
||||
|
||||
|
||||
@ -36,6 +36,7 @@ export const AccountSecurityInlineTab = observer(() => {
|
||||
const {t} = useLingui();
|
||||
const user = UserStore.currentUser;
|
||||
const [showMaskedEmail, setShowMaskedEmail] = useState(false);
|
||||
const [showMaskedPhone, setShowMaskedPhone] = useState(false);
|
||||
const [passkeys, setPasskeys] = useState<Array<UserActionCreators.WebAuthnCredential>>([]);
|
||||
const [loadingPasskeys, setLoadingPasskeys] = useState(false);
|
||||
const [enablingSmsMfa, setEnablingSmsMfa] = useState(false);
|
||||
@ -89,9 +90,11 @@ export const AccountSecurityInlineTab = observer(() => {
|
||||
loadingPasskeys={loadingPasskeys}
|
||||
enablingSmsMfa={enablingSmsMfa}
|
||||
disablingSmsMfa={disablingSmsMfa}
|
||||
showMaskedPhone={showMaskedPhone}
|
||||
loadPasskeys={loadPasskeys}
|
||||
setEnablingSmsMfa={setEnablingSmsMfa}
|
||||
setDisablingSmsMfa={setDisablingSmsMfa}
|
||||
setShowMaskedPhone={setShowMaskedPhone}
|
||||
/>
|
||||
</SettingsSection>
|
||||
<SettingsSection id="danger_zone" title={t`Danger Zone`}>
|
||||
|
||||
@ -97,6 +97,48 @@
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.phoneRow {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.phoneRow {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.phoneText {
|
||||
color: var(--text-primary-muted);
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.phoneTextSelectable {
|
||||
user-select: text;
|
||||
-webkit-user-select: text;
|
||||
}
|
||||
|
||||
.toggleButton {
|
||||
margin-top: 0.1em;
|
||||
text-align: left;
|
||||
color: var(--text-link);
|
||||
font-size: 0.875rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.toggleButton:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.toggleButton {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.claimButton {
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
@ -41,6 +41,15 @@ import type React from 'react';
|
||||
|
||||
const logger = new Logger('SecurityTab');
|
||||
|
||||
const maskPhone = (phone: string): string => {
|
||||
if (phone.length <= 4) {
|
||||
return phone.replace(/./g, '*');
|
||||
}
|
||||
const lastTwo = phone.slice(-2);
|
||||
const masked = phone.slice(0, -2).replace(/\d/g, '*');
|
||||
return `${masked}${lastTwo}`;
|
||||
};
|
||||
|
||||
interface SecurityTabProps {
|
||||
user: UserRecord;
|
||||
isClaimed: boolean;
|
||||
@ -51,9 +60,11 @@ interface SecurityTabProps {
|
||||
loadingPasskeys: boolean;
|
||||
enablingSmsMfa: boolean;
|
||||
disablingSmsMfa: boolean;
|
||||
showMaskedPhone: boolean;
|
||||
loadPasskeys: () => Promise<void>;
|
||||
setEnablingSmsMfa: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
setDisablingSmsMfa: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
setShowMaskedPhone: (show: boolean) => void;
|
||||
}
|
||||
|
||||
export const SecurityTabContent: React.FC<SecurityTabProps> = observer(
|
||||
@ -67,9 +78,11 @@ export const SecurityTabContent: React.FC<SecurityTabProps> = observer(
|
||||
loadingPasskeys,
|
||||
enablingSmsMfa,
|
||||
disablingSmsMfa,
|
||||
showMaskedPhone,
|
||||
loadPasskeys,
|
||||
setEnablingSmsMfa,
|
||||
setDisablingSmsMfa,
|
||||
setShowMaskedPhone,
|
||||
}) => {
|
||||
const {t, i18n} = useLingui();
|
||||
|
||||
@ -344,13 +357,24 @@ export const SecurityTabContent: React.FC<SecurityTabProps> = observer(
|
||||
<div className={styles.label}>
|
||||
<Trans>Phone Number</Trans>
|
||||
</div>
|
||||
<div className={styles.description}>
|
||||
{user.phone ? (
|
||||
<Trans>Phone number added: {user.phone}</Trans>
|
||||
) : (
|
||||
{user.phone ? (
|
||||
<div className={styles.phoneRow}>
|
||||
<span className={`${styles.phoneText} ${showMaskedPhone ? styles.phoneTextSelectable : ''}`}>
|
||||
{showMaskedPhone ? user.phone : maskPhone(user.phone)}
|
||||
</span>
|
||||
<button
|
||||
type="button"
|
||||
className={styles.toggleButton}
|
||||
onClick={() => setShowMaskedPhone(!showMaskedPhone)}
|
||||
>
|
||||
{showMaskedPhone ? t`Hide` : t`Reveal`}
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
<div className={styles.description}>
|
||||
<Trans>Add a phone number to enable SMS two-factor authentication</Trans>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{user.phone ? (
|
||||
<Button
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user