refactor: Improve i18n for settings 2fa

This commit is contained in:
Myzel394 2023-03-05 10:04:39 +01:00
parent 2b6364478b
commit 47053cdb50
No known key found for this signature in database
GPG Key ID: 79CC92F37B3E1A2B
6 changed files with 56 additions and 27 deletions

View File

@ -9,7 +9,10 @@
},
"2faCode": {
"label": "Code",
"placeholder": "123456"
"placeholder": "123456",
"errors": {
"shouldOnlyBeDigits": "The code should only contain digits."
}
},
"recoveryCode": {
"label": "Recovery Code"

View File

@ -0,0 +1,33 @@
{
"title": "Two-Factor-Authentication",
"alreadyEnabled": "You have successfully enabled 2FA!",
"setup": {
"description": "Enable 2FA to add an extra layer of security to your account. Each time you log in, you will need to enter a code generated from your authenticator app. This makes it harder for an attacker to hack into your account as they would need to have access to your phone.",
"setupLabel": "Enable 2FA",
"continueActionLabel": "Enable 2FA",
"codeExpired": "The verification time for your current Two-Factor-Authentication code has expired. A new code has been generated.",
"recoveryCodes": {
"title": "Note down your recovery codes",
"description": "These codes are used to recover your account if you lose access to your authenticator app. Note them down and store them in a safe place. You will not be able to view them again. Do not store them in your password manager. IF YOU LOSE YOUR RECOVERY CODES, YOU WILL LOSE ACCESS TO YOUR ACCOUNT. WE WILL NOT BE ABLE TO HELP YOU.",
"continueActionLabel": "I have noted down my recovery codes"
},
"success": "You have successfully enabled 2FA!"
},
"delete": {
"label": "Disable 2FA",
"steps": {
"askType": {
"code": "I have my 2FA code",
"recoveryCode": "I have a recovery code"
},
"askCode": {
"label": "Code"
},
"askRecoveryCode": {
"label": "Recovery Code"
}
},
"submit": "Disable 2FA",
"success": "You have successfully disabled 2FA!"
}
}

View File

@ -90,10 +90,6 @@
}
},
"SettingsRoute": {
"forms": {
"aliasPreferences": {
}
},
"2fa": {
"title": "Two-Factor-Authentication",
"alreadyEnabled": "You have successfully enabled 2FA!",

View File

@ -18,7 +18,7 @@ export interface Setup2FAProps {
}
export default function Setup2FA({onSuccess}: Setup2FAProps): ReactElement {
const {t} = useTranslation()
const {t} = useTranslation("settings-2fa")
const {showError} = useErrorSuccessSnacks()
const {
@ -33,9 +33,7 @@ export default function Setup2FA({onSuccess}: Setup2FAProps): ReactElement {
return (
<Grid container spacing={4} direction="column">
<Grid item>
<Typography variant="body1">
{t("routes.SettingsRoute.2fa.setup.description")}
</Typography>
<Typography variant="body1">{t("setup.description")}</Typography>
</Grid>
<Grid item alignSelf="center">
{secret ? (
@ -55,7 +53,7 @@ export default function Setup2FA({onSuccess}: Setup2FAProps): ReactElement {
variant="contained"
startIcon={<BsShieldLockFill />}
>
{t("routes.SettingsRoute.2fa.setup.setupLabel")}
{t("setup.setupLabel")}
</LoadingButton>
)}
</Grid>

View File

@ -41,7 +41,7 @@ export default function Settings2FARoute({
onRecreateRequired,
secret,
}: VerifyOTPFormProps): ReactElement {
const {t} = useTranslation()
const {t} = useTranslation(["settings-2fa", "common"])
const {showSuccess, showError} = useErrorSuccessSnacks()
const user = useUser()
const theme = useTheme()
@ -52,16 +52,19 @@ export default function Settings2FARoute({
code: yup
.string()
.required()
.matches(
/^[0-9]+$/,
t("fields.2faCode.errors.shouldOnlyBeDigits", {ns: "common"}) as string,
)
.length(6)
.matches(/^[0-9]+$/, t("routes.SettingsRoute.2fa.setup.code.onlyDigits").toString())
.label(t("routes.SettingsRoute.2fa.setup.code.label")),
.label(t("fields.2faCode.label", {ns: "common"})),
})
const {mutateAsync} = useMutation<void, AxiosError, Verify2FASetupData>(verify2FASetup, {
onSuccess: () => setShowRecoveryCodes(true),
onError: error => {
if (error.response?.status === 409 || error.response?.status === 410) {
showError(t("routes.SettingsRoute.2fa.setup.expired").toString())
showError(t("setup.codeExpired").toString())
onRecreateRequired()
} else {
showError(error)
@ -107,7 +110,7 @@ export default function Settings2FARoute({
error={!!formik.errors.code}
helperText={formik.errors.code}
name="code"
label={t("routes.SettingsRoute.2fa.setup.code.label")}
label={t("fields.2faCode.label", {ns: "common"})}
disabled={formik.isSubmitting}
InputProps={{
startAdornment: (
@ -125,7 +128,7 @@ export default function Settings2FARoute({
variant="contained"
loading={formik.isSubmitting}
>
{t("routes.SettingsRoute.2fa.setup.submit")}
{t("setup.continueActionLabel")}
</LoadingButton>
</Grid>
</Grid>
@ -133,7 +136,7 @@ export default function Settings2FARoute({
</Grid>
</form>
<Dialog open={showRecoveryCodes}>
<DialogTitle>{t("routes.SettingsRoute.2fa.setup.recoveryCodes.title")}</DialogTitle>
<DialogTitle>{t("setup.recoveryCodes.title")}</DialogTitle>
<DialogContent
sx={{
background: theme.palette.background.default,
@ -144,20 +147,18 @@ export default function Settings2FARoute({
<p key={code}>{code}</p>
))}
</code>
<Alert severity="warning">
{t("routes.SettingsRoute.2fa.setup.recoveryCodes.description")}
</Alert>
<Alert severity="warning">{t("setup.recoveryCodes.description")}</Alert>
</DialogContent>
<DialogActions>
<Button
variant="contained"
onClick={() => {
showSuccess(t("routes.SettingsRoute.2fa.setup.success"))
showSuccess(t("setup.success"))
setShowRecoveryCodes(false)
onSuccess()
}}
>
{t("routes.SettingsRoute.2fa.setup.recoveryCodes.submit")}
{t("setup.recoveryCodes.continueActionLabel")}
</Button>
</DialogActions>
</Dialog>

View File

@ -11,20 +11,18 @@ import Setup2FA from "~/route-widgets/Settings2FARoute/Setup2FA"
import getHas2FAEnabled from "~/apis/get-has-2fa-enabled"
export default function Settings2FARoute(): ReactElement {
const {t} = useTranslation()
const {t} = useTranslation("settings-2fa")
const queryKey = ["get_2fa_enabled"]
const query = useQuery<boolean, AxiosError>(queryKey, getHas2FAEnabled)
return (
<SimplePageBuilder.Page title={t("routes.SettingsRoute.2fa.title")}>
<SimplePageBuilder.Page title={t("title")}>
<QueryResult<boolean, AxiosError> query={query}>
{has2FAEnabled =>
has2FAEnabled ? (
<Grid container spacing={4} direction="column" alignItems="center">
<Grid item>
<Alert severity="success">
{t("routes.SettingsRoute.2fa.alreadyEnabled")}
</Alert>
<Alert severity="success">{t("alreadyEnabled")}</Alert>
</Grid>
<Grid item>
<Delete2FA onSuccess={query.refetch} />