From 37bfbab45efef151d602118ef36e19ec13b2ba81 Mon Sep 17 00:00:00 2001 From: Srijon Saha Date: Tue, 30 Apr 2024 07:14:15 -0700 Subject: [PATCH] Support captchas in reset password flow (#2547) ### Changes Adds support for captchas in the reset password flow for classic login. ### References https://auth0team.atlassian.net/browse/IAMRISK-3340 ### Testing https://github.com/auth0/lock/assets/121056923/6d58e601-ba48-42df-8af2-3a23305f6d5c ### Checklist * [x] I have read the [Auth0 general contribution guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md) * [x] I have read the [Auth0 Code of Conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md) * [x] All code quality tools/guidelines have been run/followed * [x] All relevant assets have been compiled --------- Co-authored-by: Steve Hobbs --- package-lock.json | 2 +- package.json | 2 +- .../social_or_email_login_screen.test.js.snap | 2 +- ..._or_phone_number_login_screen.test.js.snap | 2 +- src/connection/captcha.js | 71 ++++++++++++++----- src/connection/database/actions.js | 36 +++++++--- src/connection/database/login_pane.jsx | 4 +- .../database/reset_password_pane.jsx | 9 +++ src/connection/enterprise/actions.js | 6 +- src/connection/enterprise/hrd_pane.jsx | 4 +- src/connection/passwordless/actions.js | 13 ++-- src/core/index.js | 12 +++- src/core/remote_data.js | 11 ++- src/core/web_api.js | 4 ++ src/core/web_api/p2_api.js | 4 ++ src/engine/classic/sign_up_pane.jsx | 4 +- .../social_or_email_login_screen.jsx | 4 +- .../social_or_phone_number_login_screen.jsx | 4 +- src/field/captcha/captcha_pane.jsx | 9 ++- src/i18n/af.js | 4 +- src/i18n/ar.js | 4 +- src/i18n/az.js | 4 +- src/i18n/bg.js | 4 +- src/i18n/ca.js | 4 +- src/i18n/cs.js | 4 +- src/i18n/da.js | 4 +- src/i18n/de.js | 6 +- src/i18n/el.js | 4 +- src/i18n/en.js | 4 +- src/i18n/es.js | 4 +- src/i18n/et.js | 4 +- src/i18n/fa.js | 4 +- src/i18n/fi.js | 4 +- src/i18n/fr.js | 4 +- src/i18n/he.js | 4 +- src/i18n/hr.js | 4 +- src/i18n/hu.js | 4 +- src/i18n/id.js | 5 +- src/i18n/it.js | 4 +- src/i18n/ja.js | 4 +- src/i18n/ko.js | 4 +- src/i18n/lt.js | 4 +- src/i18n/lv.js | 4 +- src/i18n/ms.js | 4 +- src/i18n/nb.js | 4 +- src/i18n/nl.js | 4 +- src/i18n/nn.js | 4 +- src/i18n/no.js | 4 +- src/i18n/pl.js | 4 +- src/i18n/pt-br.js | 4 +- src/i18n/pt.js | 4 +- src/i18n/ro.js | 4 +- src/i18n/ru.js | 4 +- src/i18n/sk.js | 4 +- src/i18n/sl.js | 4 +- src/i18n/sr.js | 4 +- src/i18n/sv.js | 4 +- src/i18n/tr.js | 4 +- src/i18n/ua.js | 4 +- src/i18n/uk.js | 4 +- src/i18n/vi.js | 4 +- src/i18n/zh-tw.js | 4 +- src/i18n/zh.js | 4 +- 63 files changed, 281 insertions(+), 101 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4073d0644..503c18b63 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "12.4.0", "license": "MIT", "dependencies": { - "auth0-js": "^9.23.3", + "auth0-js": "^9.26.0", "auth0-password-policies": "^1.0.2", "blueimp-md5": "^2.19.0", "classnames": "^2.3.2", diff --git a/package.json b/package.json index a07f87176..95830526e 100644 --- a/package.json +++ b/package.json @@ -121,7 +121,7 @@ "webpack-dev-server": "^4.11.1" }, "dependencies": { - "auth0-js": "^9.23.3", + "auth0-js": "^9.26.0", "auth0-password-policies": "^1.0.2", "blueimp-md5": "^2.19.0", "classnames": "^2.3.2", diff --git a/src/__tests__/engine/passwordless/__snapshots__/social_or_email_login_screen.test.js.snap b/src/__tests__/engine/passwordless/__snapshots__/social_or_email_login_screen.test.js.snap index 75e452409..b8c24cbd4 100644 --- a/src/__tests__/engine/passwordless/__snapshots__/social_or_email_login_screen.test.js.snap +++ b/src/__tests__/engine/passwordless/__snapshots__/social_or_email_login_screen.test.js.snap @@ -29,13 +29,13 @@ exports[`email passwordless renders a captcha 1`] = ` />
diff --git a/src/__tests__/engine/passwordless/__snapshots__/social_or_phone_number_login_screen.test.js.snap b/src/__tests__/engine/passwordless/__snapshots__/social_or_phone_number_login_screen.test.js.snap index 502e9ce08..d214f989b 100644 --- a/src/__tests__/engine/passwordless/__snapshots__/social_or_phone_number_login_screen.test.js.snap +++ b/src/__tests__/engine/passwordless/__snapshots__/social_or_phone_number_login_screen.test.js.snap @@ -21,13 +21,13 @@ exports[`sms passwordless renders a captcha 1`] = ` />
diff --git a/src/connection/captcha.js b/src/connection/captcha.js index f166ceb1a..3d9e74d9a 100644 --- a/src/connection/captcha.js +++ b/src/connection/captcha.js @@ -4,22 +4,45 @@ import * as i18n from '../i18n'; import { swap, updateEntity } from '../store/index'; import webApi from '../core/web_api'; +export const Flow = Object.freeze({ + DEFAULT: 'default', + PASSWORDLESS: 'passwordless', + PASSWORD_RESET: 'password_reset', +}); + +/** + * Return the captcha config object based on the type of flow. + * + * @param {Object} m model + * @param {Flow} flow Which flow the captcha is being rendered in + */ +export function getCaptchaConfig(m, flow) { + if (flow === Flow.PASSWORD_RESET) { + return l.passwordResetCaptcha(m); + } else if (flow === Flow.PASSWORDLESS) { + return l.passwordlessCaptcha(m); + } else { + return l.captcha(m); + } +} + /** * Display the error message of missing captcha in the header of lock. * * @param {Object} m model * @param {Number} id - * @param {Boolean} isPasswordless Whether the captcha is being rendered in a passwordless flow + * @param {Flow} flow Which flow the captcha is being rendered in */ -export function showMissingCaptcha(m, id, isPasswordless = false) { - const captchaConfig = isPasswordless ? l.passwordlessCaptcha(m) : l.captcha(m); +export function showMissingCaptcha(m, id, flow = Flow.DEFAULT) { + const captchaConfig = getCaptchaConfig(m, flow); const captchaError = ( captchaConfig.get('provider') === 'recaptcha_v2' || captchaConfig.get('provider') === 'recaptcha_enterprise' || captchaConfig.get('provider') === 'hcaptcha' || captchaConfig.get('provider') === 'auth0_v2' || - captchaConfig.get('provider') === 'friendly_captcha' + captchaConfig.get('provider') === 'friendly_captcha' || + captchaConfig.get('provider') === 'arkose' ) ? 'invalid_recaptcha' : 'invalid_captcha'; const errorMessage = i18n.html(m, ['error', 'login', captchaError]); @@ -37,20 +60,20 @@ export function showMissingCaptcha(m, id, isPasswordless = false) { * * @param {Object} m model * @param {Object} params - * @param {Boolean} isPasswordless Whether the captcha is being rendered in a passwordless flow + * @param {Flow} flow Which flow the captcha is being rendered in * @param {Object} fields * * @returns {Boolean} returns true if is required and missing the response from the user */ -export function setCaptchaParams(m, params, isPasswordless, fields) { - const captchaConfig = isPasswordless ? l.passwordlessCaptcha(m) : l.captcha(m); +export function setCaptchaParams(m, params, flow, fields) { + const captchaConfig = getCaptchaConfig(m, flow); const isCaptchaRequired = captchaConfig && captchaConfig.get('required'); if (!isCaptchaRequired) { return true; } const captcha = c.getFieldValue(m, 'captcha'); - //captcha required and missing + // captcha required and missing if (!captcha) { return false; } @@ -64,12 +87,21 @@ export function setCaptchaParams(m, params, isPasswordless, fields) { * Get a new challenge and display the new captcha image. * * @param {number} id The id of the Lock instance. - * @param {Boolean} isPasswordless Whether the captcha is being rendered in a passwordless flow. + * @param {Flow} flow Which flow the captcha is being rendered in. * @param {boolean} wasInvalid A boolean indicating if the previous captcha was invalid. * @param {Function} [next] A callback. */ -export function swapCaptcha(id, isPasswordless, wasInvalid, next) { - if (isPasswordless) { +export function swapCaptcha(id, flow, wasInvalid, next) { + if (flow === Flow.PASSWORD_RESET) { + return webApi.getPasswordResetChallenge(id, (err, newCaptcha) => { + if (!err && newCaptcha) { + swap(updateEntity, 'lock', id, l.setPasswordResetCaptcha, newCaptcha, wasInvalid); + } + if (next) { + next(); + } + }); + } else if (flow === Flow.PASSWORDLESS) { return webApi.getPasswordlessChallenge(id, (err, newCaptcha) => { if (!err && newCaptcha) { swap(updateEntity, 'lock', id, l.setPasswordlessCaptcha, newCaptcha, wasInvalid); @@ -78,13 +110,14 @@ export function swapCaptcha(id, isPasswordless, wasInvalid, next) { next(); } }); + } else { + return webApi.getChallenge(id, (err, newCaptcha) => { + if (!err && newCaptcha) { + swap(updateEntity, 'lock', id, l.setCaptcha, newCaptcha, wasInvalid); + } + if (next) { + next(); + } + }); } - return webApi.getChallenge(id, (err, newCaptcha) => { - if (!err && newCaptcha) { - swap(updateEntity, 'lock', id, l.setCaptcha, newCaptcha, wasInvalid); - } - if (next) { - next(); - } - }); } diff --git a/src/connection/database/actions.js b/src/connection/database/actions.js index 2d92a4deb..0e428bd03 100644 --- a/src/connection/database/actions.js +++ b/src/connection/database/actions.js @@ -19,7 +19,7 @@ import { } from './index'; import * as i18n from '../../i18n'; -import { setCaptchaParams, showMissingCaptcha, swapCaptcha } from '../captcha'; +import { Flow, setCaptchaParams, showMissingCaptcha, swapCaptcha } from '../captcha'; export function logIn(id, needsMFA = false) { const m = read(getEntity, 'lock', id); @@ -33,7 +33,7 @@ export function logIn(id, needsMFA = false) { }; const fields = [usernameField, 'password']; - const isCaptchaValid = setCaptchaParams(m, params, false, fields); + const isCaptchaValid = setCaptchaParams(m, params, Flow.DEFAULT, fields); if (!isCaptchaValid) { return showMissingCaptcha(m, id); @@ -53,7 +53,7 @@ export function logIn(id, needsMFA = false) { if (error) { const wasInvalid = error && error.code === 'invalid_captcha'; - return swapCaptcha(id, false, wasInvalid, next); + return swapCaptcha(id, Flow.DEFAULT, wasInvalid, next); } next(); @@ -88,7 +88,7 @@ export function signUp(id) { autoLogin: shouldAutoLogin(m) }; - const isCaptchaValid = setCaptchaParams(m, params, false, fields); + const isCaptchaValid = setCaptchaParams(m, params, Flow.DEFAULT, fields); if (!isCaptchaValid) { return showMissingCaptcha(m, id); } @@ -131,7 +131,7 @@ export function signUp(id) { const wasInvalidCaptcha = error && error.code === 'invalid_captcha'; - swapCaptcha(id, false, wasInvalidCaptcha, () => { + swapCaptcha(id, Flow.DEFAULT, wasInvalidCaptcha, () => { setTimeout(() => signUpError(id, error), 250); }); }; @@ -218,7 +218,7 @@ export function signUpError(id, error) { if (errorKey === 'invalid_captcha') { errorMessage = i18n.html(m, ['error', 'login', errorKey]); - return swapCaptcha(id, false, true, () => { + return swapCaptcha(id, Flow.DEFAULT, true, () => { swap(updateEntity, 'lock', id, l.setSubmitting, false, errorMessage); }); } @@ -244,7 +244,12 @@ export function resetPassword(id) { email: c.getFieldValue(m, 'email') }; - webApi.resetPassword(id, params, (error, ...args) => { + const isCaptchaValid = setCaptchaParams(m, params, Flow.PASSWORD_RESET, ['email']); + if (!isCaptchaValid) { + return showMissingCaptcha(m, id, Flow.PASSWORD_RESET); + } + + webApi.resetPassword(id, params, error => { if (error) { setTimeout(() => resetPasswordError(id, error), 250); } else { @@ -280,12 +285,23 @@ function resetPasswordSuccess(id) { function resetPasswordError(id, error) { const m = read(getEntity, 'lock', id); + let key = error.code; + + if (error.code === 'invalid_captcha') { + const captchaConfig = l.passwordResetCaptcha(m); + key = ( + captchaConfig.get('provider') === 'recaptcha_v2' || + captchaConfig.get('provider') === 'recaptcha_enterprise' + ) ? 'invalid_recaptcha' : 'invalid_captcha'; + } const errorMessage = - i18n.html(m, ['error', 'forgotPassword', error.code]) || + i18n.html(m, ['error', 'forgotPassword', key]) || i18n.html(m, ['error', 'forgotPassword', 'lock.fallback']); - - swap(updateEntity, 'lock', id, l.setSubmitting, false, errorMessage); + + swapCaptcha(id, Flow.PASSWORD_RESET, error.code === 'invalid_captcha', () => { + swap(updateEntity, 'lock', id, l.setSubmitting, false, errorMessage); + }); } export function showLoginActivity(id, fields = ['password']) { diff --git a/src/connection/database/login_pane.jsx b/src/connection/database/login_pane.jsx index c31f5369b..fc8b5b166 100644 --- a/src/connection/database/login_pane.jsx +++ b/src/connection/database/login_pane.jsx @@ -4,7 +4,7 @@ import EmailPane from '../../field/email/email_pane'; import UsernamePane from '../../field/username/username_pane'; import PasswordPane from '../../field/password/password_pane'; import { showResetPasswordActivity } from './actions'; -import { swapCaptcha } from '../captcha'; +import { Flow, swapCaptcha } from '../captcha'; import { hasScreen, forgotPasswordLink } from './index'; import * as l from '../../core/index'; import CaptchaPane from '../../field/captcha/captcha_pane'; @@ -64,7 +64,7 @@ export default class LoginPane extends React.Component { l.captcha(lock) && l.captcha(lock).get('required') && (isHRDDomain(lock, databaseUsernameValue(lock)) || !sso) ? ( - swapCaptcha(l.id(lock), false, false)} /> + swapCaptcha(l.id(lock), Flow.DEFAULT, false)} /> ) : null; const dontRememberPassword = diff --git a/src/connection/database/reset_password_pane.jsx b/src/connection/database/reset_password_pane.jsx index 7b5538d56..d85d79352 100644 --- a/src/connection/database/reset_password_pane.jsx +++ b/src/connection/database/reset_password_pane.jsx @@ -2,6 +2,8 @@ import PropTypes from 'prop-types'; import React from 'react'; import EmailPane from '../../field/email/email_pane'; import * as l from '../../core/index'; +import CaptchaPane from '../../field/captcha/captcha_pane'; +import { Flow, swapCaptcha } from '../../connection/captcha'; export default class ResetPasswordPane extends React.Component { static propTypes = { @@ -12,6 +14,12 @@ export default class ResetPasswordPane extends React.Component { render() { const { emailInputPlaceholder, header, i18n, lock } = this.props; + const captchaPane = + l.passwordResetCaptcha(lock) && + l.passwordResetCaptcha(lock).get('required') ? ( + swapCaptcha(l.id(lock), Flow.PASSWORD_RESET, false, null)} /> + ) : null; + return (
{header} @@ -21,6 +29,7 @@ export default class ResetPasswordPane extends React.Component { placeholder={emailInputPlaceholder} strictValidation={false} /> + {captchaPane}
); } diff --git a/src/connection/enterprise/actions.js b/src/connection/enterprise/actions.js index 8dbaa8daa..b880cc831 100644 --- a/src/connection/enterprise/actions.js +++ b/src/connection/enterprise/actions.js @@ -9,7 +9,7 @@ import { getFieldValue, hideInvalidFields } from '../../field/index'; import { emailLocalPart } from '../../field/email'; import { logIn as coreLogIn } from '../../core/actions'; import * as l from '../../core/index'; -import { setCaptchaParams, showMissingCaptcha, swapCaptcha } from '../captcha'; +import { Flow, setCaptchaParams, showMissingCaptcha, swapCaptcha } from '../captcha'; // TODO: enterprise connections should not depend on database // connections. However, we now allow a username input to contain also @@ -53,7 +53,7 @@ export function logIn(id) { return logInSSO(id, ssoConnection, params); } - const isCaptchaValid = setCaptchaParams(m, params, false, fields); + const isCaptchaValid = setCaptchaParams(m, params, Flow.DEFAULT, fields); if (!isCaptchaValid && !ssoConnection) { return showMissingCaptcha(m, id); @@ -85,7 +85,7 @@ function logInActiveFlow(id, params) { }, (id, error, fields, next) => { const wasCaptchaInvalid = error && error.code === 'invalid captcha'; - swapCaptcha(id, false, wasCaptchaInvalid, next); + swapCaptcha(id, Flow.DEFAULT, wasCaptchaInvalid, next); } ); } diff --git a/src/connection/enterprise/hrd_pane.jsx b/src/connection/enterprise/hrd_pane.jsx index e318cc558..a3fba442c 100644 --- a/src/connection/enterprise/hrd_pane.jsx +++ b/src/connection/enterprise/hrd_pane.jsx @@ -3,7 +3,7 @@ import React from 'react'; import UsernamePane from '../../field/username/username_pane'; import PasswordPane from '../../field/password/password_pane'; import CaptchaPane from '../../field/captcha/captcha_pane'; -import { swapCaptcha } from '../captcha'; +import { Flow, swapCaptcha } from '../captcha'; import * as l from '../../core/index'; export default class HRDPane extends React.Component { @@ -12,7 +12,7 @@ export default class HRDPane extends React.Component { const captchaPane = l.captcha(model) && l.captcha(model).get('required') ? ( - swapCaptcha(l.id(model), false, false)} /> + swapCaptcha(l.id(model), Flow.DEFAULT, false)} /> ) : null; return ( diff --git a/src/connection/passwordless/actions.js b/src/connection/passwordless/actions.js index 9c25598ed..89687ea01 100644 --- a/src/connection/passwordless/actions.js +++ b/src/connection/passwordless/actions.js @@ -16,7 +16,7 @@ import { } from './index'; import { phoneNumberWithDiallingCode } from '../../field/phone_number'; import * as i18n from '../../i18n'; -import { setCaptchaParams, showMissingCaptcha, swapCaptcha } from '../captcha'; +import { Flow, setCaptchaParams, showMissingCaptcha, swapCaptcha } from '../captcha'; function getErrorMessage(m, id, error) { let key = error.error; @@ -35,7 +35,8 @@ function getErrorMessage(m, id, error) { captchaConfig.get('provider') === 'recaptcha_enterprise' || captchaConfig.get('provider') === 'hcaptcha' || captchaConfig.get('provider') === 'auth0_v2' || - captchaConfig.get('provider') === 'friendly_captcha' + captchaConfig.get('provider') === 'friendly_captcha' || + captchaConfig.get('provider') === 'arkose' ) ? 'invalid_recaptcha' : 'invalid_captcha'; } @@ -47,7 +48,7 @@ function getErrorMessage(m, id, error) { function swapCaptchaAfterError(id, error){ const wasCaptchaInvalid = error && error.code === 'invalid_captcha'; - swapCaptcha(id, true, wasCaptchaInvalid); + swapCaptcha(id, Flow.PASSWORDLESS, wasCaptchaInvalid); } export function requestPasswordlessEmail(id) { @@ -102,7 +103,7 @@ function sendEmail(m, id, successFn, errorFn) { if (isSendLink(m) && !l.auth.params(m).isEmpty()) { params.authParams = l.auth.params(m).toJS(); } - const isCaptchaValid = setCaptchaParams(m, params, true, []); + const isCaptchaValid = setCaptchaParams(m, params, Flow.PASSWORDLESS, []); if (!isCaptchaValid) { return showMissingCaptcha(m, id, true); @@ -124,7 +125,7 @@ export function sendSMS(id) { phoneNumber: phoneNumberWithDiallingCode(m), send: send(m) }; - const isCaptchaValid = setCaptchaParams(m, params, true, []); + const isCaptchaValid = setCaptchaParams(m, params, Flow.PASSWORDLESS, []); if (!isCaptchaValid) { return showMissingCaptcha(m, id, true); } @@ -187,7 +188,7 @@ export function logIn(id) { export function restart(id) { swap(updateEntity, 'lock', id, restartPasswordless); - swapCaptcha(id, true, false); + swapCaptcha(id, Flow.PASSWORDLESS, false); } export function toggleTermsAcceptance(id) { diff --git a/src/core/index.js b/src/core/index.js index 03c0f5164..817cf9c91 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -426,6 +426,11 @@ export function setPasswordlessCaptcha(m, value, wasInvalid) { return set(m, 'passwordlessCaptcha', Immutable.fromJS(value)); } +export function setPasswordResetCaptcha(m, value, wasInvalid) { + m = captchaField.reset(m, wasInvalid); + return set(m, 'passwordResetCaptcha', Immutable.fromJS(value)); +} + export function captcha(m) { return get(m, 'captcha'); } @@ -434,6 +439,10 @@ export function passwordlessCaptcha(m) { return get(m, 'passwordlessCaptcha'); } +export function passwordResetCaptcha(m) { + return get(m, 'passwordResetCaptcha'); +} + export function prefill(m) { return get(m, 'prefill', {}); } @@ -585,7 +594,8 @@ export function loginErrorMessage(m, error, type) { currentCaptcha.get('provider') === 'recaptcha_enterprise' || currentCaptcha.get('provider') === 'hcaptcha' || currentCaptcha.get('provider') === 'auth0_v2' || - captchaConfig.get('provider') === 'friendly_captcha' + currentCaptcha.get('provider') === 'friendly_captcha' || + currentCaptcha.get('provider') === 'arkose' )) { code = 'invalid_recaptcha'; } diff --git a/src/core/remote_data.js b/src/core/remote_data.js index 6f2f20121..ef81e3319 100644 --- a/src/core/remote_data.js +++ b/src/core/remote_data.js @@ -6,7 +6,7 @@ import * as l from './index'; import { isADEnabled } from '../connection/enterprise'; // shouldn't depend on this import sync, { isSuccess } from '../sync'; import webApi from './web_api'; -import { setCaptcha, setPasswordlessCaptcha } from '../core/index'; +import { setCaptcha, setPasswordlessCaptcha, setPasswordResetCaptcha } from '../core/index'; export function syncRemoteData(m) { if (l.useTenantInfo(m)) { @@ -69,6 +69,15 @@ export function syncRemoteData(m) { successFn: setPasswordlessCaptcha }); + m = sync(m, 'passwordResetCaptcha', { + syncFn: (m, cb) => { + webApi.getPasswordResetChallenge(m.get('id'), (err, r) => { + cb(null, r); + }); + }, + successFn: setPasswordResetCaptcha + }); + return m; } diff --git a/src/core/web_api.js b/src/core/web_api.js index 7a4fbb14d..4000d7d7b 100644 --- a/src/core/web_api.js +++ b/src/core/web_api.js @@ -64,6 +64,10 @@ class Auth0WebAPI { return this.clients[lockID].getPasswordlessChallenge(callback); } + getPasswordResetChallenge(lockID, callback) { + return this.clients[lockID].getPasswordResetChallenge(callback); + } + getSSOData(lockID, ...args) { return this.clients[lockID].getSSOData(...args); } diff --git a/src/core/web_api/p2_api.js b/src/core/web_api/p2_api.js index ddb412b09..8cc5f1484 100644 --- a/src/core/web_api/p2_api.js +++ b/src/core/web_api/p2_api.js @@ -199,6 +199,10 @@ class Auth0APIClient { return this.client.client.passwordless.getChallenge(...params); } + getPasswordResetChallenge(...params) { + return this.client.client.dbConnection.getPasswordResetChallenge(...params); + } + getUserCountry(cb) { return this.client.client.getUserCountry(cb); } diff --git a/src/engine/classic/sign_up_pane.jsx b/src/engine/classic/sign_up_pane.jsx index 615141cbe..621afdd9e 100644 --- a/src/engine/classic/sign_up_pane.jsx +++ b/src/engine/classic/sign_up_pane.jsx @@ -12,7 +12,7 @@ import { } from '../../connection/database/index'; import CaptchaPane from '../../field/captcha/captcha_pane'; import * as l from '../../core/index'; -import { swapCaptcha } from '../../connection/captcha'; +import { Flow, swapCaptcha } from '../../connection/captcha'; import { isHRDDomain } from '../../connection/enterprise'; import { databaseUsernameValue } from '../../connection/database/index'; import { isSSOEnabled } from '../classic'; @@ -67,7 +67,7 @@ export default class SignUpPane extends React.Component { l.captcha(model) && l.captcha(model).get('required') && (isHRDDomain(model, databaseUsernameValue(model)) || !sso) ? ( - swapCaptcha(l.id(model), false, false)} /> + swapCaptcha(l.id(model), Flow.DEFAULT, false)} /> ) : null; const passwordPane = !onlyEmail && ( diff --git a/src/engine/passwordless/social_or_email_login_screen.jsx b/src/engine/passwordless/social_or_email_login_screen.jsx index 9fab6b03f..38a2127c8 100644 --- a/src/engine/passwordless/social_or_email_login_screen.jsx +++ b/src/engine/passwordless/social_or_email_login_screen.jsx @@ -3,7 +3,7 @@ import Screen from '../../core/screen'; import EmailPane from '../../field/email/email_pane'; import SocialButtonsPane from '../../field/social/social_buttons_pane'; import CaptchaPane from '../../field/captcha/captcha_pane'; -import { swapCaptcha } from '../../connection/captcha'; +import { Flow, swapCaptcha } from '../../connection/captcha'; import PaneSeparator from '../../core/pane_separator'; import { mustAcceptTerms, termsAccepted, showTerms } from '../../connection/passwordless/index'; import { toggleTermsAcceptance } from '../../connection/passwordless/actions'; @@ -49,7 +49,7 @@ const Component = ({ i18n, model }) => { const captchaPane = l.passwordlessCaptcha(model) && l.passwordlessCaptcha(model).get('required') ? ( - swapCaptcha(l.id(model), true, false)} /> + swapCaptcha(l.id(model), Flow.PASSWORDLESS, false)} /> ) : null; return ( diff --git a/src/engine/passwordless/social_or_phone_number_login_screen.jsx b/src/engine/passwordless/social_or_phone_number_login_screen.jsx index 1f4d6ad21..4b8b39e3a 100644 --- a/src/engine/passwordless/social_or_phone_number_login_screen.jsx +++ b/src/engine/passwordless/social_or_phone_number_login_screen.jsx @@ -4,7 +4,7 @@ import { sendSMS } from '../../connection/passwordless/actions'; import PhoneNumberPane from '../../field/phone-number/phone_number_pane'; import SocialButtonsPane from '../../field/social/social_buttons_pane'; import CaptchaPane from '../../field/captcha/captcha_pane'; -import { swapCaptcha } from '../../connection/captcha'; +import { Flow, swapCaptcha } from '../../connection/captcha'; import { renderSignedInConfirmation } from '../../core/signed_in_confirmation'; import PaneSeparator from '../../core/pane_separator'; import * as l from '../../core/index'; @@ -39,7 +39,7 @@ const Component = ({ i18n, model }) => { const captchaPane = l.passwordlessCaptcha(model) && l.passwordlessCaptcha(model).get('required') ? ( - swapCaptcha(l.id(model), true, false)} /> + swapCaptcha(l.id(model), Flow.PASSWORDLESS, false)} /> ) : null; const separator = social && phoneNumber ? : null; diff --git a/src/field/captcha/captcha_pane.jsx b/src/field/captcha/captcha_pane.jsx index 109871a3c..31b8cf29d 100644 --- a/src/field/captcha/captcha_pane.jsx +++ b/src/field/captcha/captcha_pane.jsx @@ -8,12 +8,13 @@ import { swap, updateEntity } from '../../store/index'; import * as captchaField from '../captcha'; import { getFieldValue, isFieldVisiblyInvalid } from '../index'; import { ThirdPartyCaptcha, isThirdPartyCaptcha } from './third_party_captcha'; +import { getCaptchaConfig } from '../../connection/captcha'; export default class CaptchaPane extends React.Component { render() { - const { i18n, lock, onReload, isPasswordless } = this.props; + const { i18n, lock, onReload, flow } = this.props; const lockId = l.id(lock); - const captcha = isPasswordless ? l.passwordlessCaptcha(lock) : l.captcha(lock); + const captcha = getCaptchaConfig(lock, flow); const value = getFieldValue(lock, 'captcha'); const isValid = !isFieldVisiblyInvalid(lock, 'captcha'); const provider = captcha.get('provider'); @@ -72,7 +73,9 @@ CaptchaPane.propTypes = { i18n: PropTypes.object.isRequired, lock: PropTypes.object.isRequired, error: PropTypes.bool, - onReload: PropTypes.func.isRequired + onReload: PropTypes.func.isRequired, + flow: PropTypes.string, + isPasswordReset: PropTypes.bool }; CaptchaPane.defaultProps = { diff --git a/src/i18n/af.js b/src/i18n/af.js index 90b09dc59..96f16ac02 100644 --- a/src/i18n/af.js +++ b/src/i18n/af.js @@ -7,7 +7,9 @@ export default { too_many_requests: 'Jammer, jy het limiet bereik. Probeer asseblief weer later.', 'lock.fallback': 'Jammer, iets het verkeerd gegaan terwyl jy wagwoord verander het.', enterprise_email: - "Jou e-pos se domein is deel van 'n Enterprise Identity provider. Om u wagwoord terug te stel, raadpleeg asseblief u sekuriteitsadministrateur." + "Jou e-pos se domein is deel van 'n Enterprise Identity provider. Om u wagwoord terug te stel, raadpleeg asseblief u sekuriteitsadministrateur.", + invalid_captcha: "Los die uitdagingsvraag om te verifieer dat u nie 'n robot is nie.", + invalid_recaptcha: "Kies die merkblokkie om te verifieer dat u nie 'n robot is nie." }, login: { blocked_user: 'Die gebruiker is geblok.', diff --git a/src/i18n/ar.js b/src/i18n/ar.js index a3c0283ea..a394cbe45 100644 --- a/src/i18n/ar.js +++ b/src/i18n/ar.js @@ -8,7 +8,9 @@ export default { 'لقد تجاوزت الحد المسموح لمحاولات تغيير كلمة المرور. رجاءً انتظر قبل إعادة المحاولة.', 'lock.fallback': 'المعذرة، حصل خطأ ما خلال طلب تغيير كلمة المرور.', enterprise_email: - 'نطاق بريدك الإلكتروني يتبع لمؤسسة، لإعادة تعيين كلمة المرور، رجاءً تواصل مع أحد مسؤولي النظام.' + 'نطاق بريدك الإلكتروني يتبع لمؤسسة، لإعادة تعيين كلمة المرور، رجاءً تواصل مع أحد مسؤولي النظام.', + invalid_captcha: 'حل سؤال التحدي للتحقق من أنك لست روبوت.', + invalid_recaptcha: 'حدد مربع الاختيار للتحقق من أنك لست روبوتًا.' }, login: { blocked_user: 'المستخدم محظور.', diff --git a/src/i18n/az.js b/src/i18n/az.js index 927368aa4..e6b9919c2 100644 --- a/src/i18n/az.js +++ b/src/i18n/az.js @@ -8,7 +8,9 @@ export default { 'Şifrəni dəyişdirməyə cəhdlərin sayında maksimal həddə çatmısınız. Xahiş edirik bir daha cəhd etmədən əvvəl gözləyin.', 'lock.fallback': 'Bağışlayın, şifrənizi dəyişdirmə sorğusu işlənərkən xəta baş verdi.', enterprise_email: - 'E-poçtunuzun sahəsi korporativ kimlik təminatçısının bir hissəsidir. Şifrənizi yenidən qurmaq üçün təhlükəsizlik administratorunuzla əlaqə saxlayın.' + 'E-poçtunuzun sahəsi korporativ kimlik təminatçısının bir hissəsidir. Şifrənizi yenidən qurmaq üçün təhlükəsizlik administratorunuzla əlaqə saxlayın.', + invalid_captcha: 'Daxil etdiyiniz mətn səhv idi.
Lütfən, yenidən cəhd edin.', + invalid_recaptcha: 'Robot olmadığınızı təsdiqləmək üçün onay qutusunu seçin.' }, login: { blocked_user: 'İstifadəçi bloklandı.', diff --git a/src/i18n/bg.js b/src/i18n/bg.js index 4bf899722..39430fd4f 100644 --- a/src/i18n/bg.js +++ b/src/i18n/bg.js @@ -8,7 +8,9 @@ export default { 'Достигнахте лимита на опити за смяна на паролата. Моля изчакайте преди да опитате отново.', 'lock.fallback': 'За съжаление, възникна грешка при опита за промяна на паролата.', enterprise_email: - 'Вашият имейл е част от служебн доставчик на идентичност. Моля свържете се с администратора по сигурността, за да смените паролата си.' + 'Вашият имейл е част от служебн доставчик на идентичност. Моля свържете се с администратора по сигурността, за да смените паролата си.', + invalid_captcha: 'Решете задачата, за да се уверим, че не сте робот.', + invalid_recaptcha: 'Поставете отметка, за да се уверим, че не сте робот.' }, login: { blocked_user: 'Потребителското име е блокирано.', diff --git a/src/i18n/ca.js b/src/i18n/ca.js index 6a530cb57..d779f8808 100644 --- a/src/i18n/ca.js +++ b/src/i18n/ca.js @@ -8,7 +8,9 @@ export default { "S'han exhaurit els intents per restablir la contrasenya. Espereu una estona i intenteu-ho de nou.", 'lock.fallback': 'Hi ha hagut un error en canviar la contrasenya.', enterprise_email: - "El domini del vostre correu electrònic forma part d'un proveïdor d'identitat empresarial. Per restablir la contrasenya, consulteu l'administrador de seguretat." + "El domini del vostre correu electrònic forma part d'un proveïdor d'identitat empresarial. Per restablir la contrasenya, consulteu l'administrador de seguretat.", + invalid_captcha: 'Resoleu la pregunta de desafiament per verificar que no sou un robot.', + invalid_recaptcha: 'Seleccioneu la casella de verificació per verificar que no sou un robot.' }, login: { blocked_user: "L'usuari està bloquejat.", diff --git a/src/i18n/cs.js b/src/i18n/cs.js index 2d65fe15d..163ea8284 100644 --- a/src/i18n/cs.js +++ b/src/i18n/cs.js @@ -8,7 +8,9 @@ export default { 'Dosáhli jste limitu počtu pokusů o změnu hesla. Před dalším pokusem prosím počkejte.', 'lock.fallback': 'Je nám líto, ale něco se pokazilo při žádosti o změnu hesla.', enterprise_email: - 'Doména vašeho e-mailu je součástí poskytovatele podnikové identity. Chcete-li obnovit heslo, obraťte se na svého správce zabezpečení.' + 'Doména vašeho e-mailu je součástí poskytovatele podnikové identity. Chcete-li obnovit heslo, obraťte se na svého správce zabezpečení.', + invalid_captcha: 'Vyřešte úlohu, abychom ověřili, že nejste robot.', + invalid_recaptcha: 'Zaškrtněte políčko, abychom ověřili, že nejste robot.' }, login: { blocked_user: 'Uživatel je blokován.', diff --git a/src/i18n/da.js b/src/i18n/da.js index 40ed20a12..f9f88947e 100644 --- a/src/i18n/da.js +++ b/src/i18n/da.js @@ -8,7 +8,9 @@ export default { 'Du har nået grænsen for forsøg på at skifte adgangskode. Vent venligst før du prøver igen.', 'lock.fallback': 'Vi beklager, men der skete en fejl i forespørgslen efter ny adgangskode.', enterprise_email: - 'Dit e-mail-domæne er en del af en Enterprise Identity-udbyder. For at nulstille dit kodeord, se venligst din sikkerhedsadministrator.' + 'Dit e-mail-domæne er en del af en Enterprise Identity-udbyder. For at nulstille dit kodeord, se venligst din sikkerhedsadministrator.', + invalid_captcha: 'Løs udfordringsspørgsmålet for at kontrollere, at du ikke er en robot.', + invalid_recaptcha: 'Marker afkrydsningsfeltet for at kontrollere, at du ikke er en robot.' }, login: { blocked_user: 'Denne bruger er blokeret.', diff --git a/src/i18n/de.js b/src/i18n/de.js index 15179443e..87c1c9858 100644 --- a/src/i18n/de.js +++ b/src/i18n/de.js @@ -6,7 +6,11 @@ export default { 'lock.fallback': 'Es tut uns leid, beim Zurücksetzen des Passworts ist ein Fehler aufgetreten.', enterprise_email: - 'Die Domain Ihrer E-Mail-Adresse ist Teil eines Enterprise Identity Providers. Um Ihr Passwort zurückzusetzen, wenden Sie sich bitte an Ihren Sicherheitsadministrator.' + 'Die Domain Ihrer E-Mail-Adresse ist Teil eines Enterprise Identity Providers. Um Ihr Passwort zurückzusetzen, wenden Sie sich bitte an Ihren Sicherheitsadministrator.', + invalid_captcha: + 'Lösen Sie die Herausforderungsfrage, um sicherzustellen, dass Sie kein Roboter sind.', + invalid_recaptcha: + 'Aktivieren Sie das Kontrollkästchen, um sicherzustellen, dass Sie kein Roboter sind.' }, login: { blocked_user: 'Der Benutzer wird blockiert.', diff --git a/src/i18n/el.js b/src/i18n/el.js index b90081763..4d0a69a0c 100644 --- a/src/i18n/el.js +++ b/src/i18n/el.js @@ -9,7 +9,9 @@ export default { 'lock.fallback': 'Λυπούμαστε, ανεπιτυχής έκβαση. Κάτι πήγε στραβά κατά την επεξεργασία του αιτήματος.', enterprise_email: - 'Το domain του email σας ανήκει σε επιχείρηση. Για να αντικαταστήσετε τον κωδικό πρόσβασής σας, ζητήστε το από τον υπεύθυνο διαχειριστή.' + 'Το domain του email σας ανήκει σε επιχείρηση. Για να αντικαταστήσετε τον κωδικό πρόσβασής σας, ζητήστε το από τον υπεύθυνο διαχειριστή.', + invalid_captcha: 'Λύστε την ερώτηση πρόκλησης για να επιβεβαιώσετε ότι δεν είστε ρομπότ.', + invalid_recaptcha: 'Επιλέξτε το πλαίσιο ελέγχου για να επαληθεύσετε ότι δεν είστε ρομπότ.' }, login: { blocked_user: 'Ο λογαριασμός σας δεν έχει πρόσβαση.', diff --git a/src/i18n/en.js b/src/i18n/en.js index 01819b618..c1a1c4607 100644 --- a/src/i18n/en.js +++ b/src/i18n/en.js @@ -5,7 +5,9 @@ export default { 'You have reached the limit on password change attempts. Please wait before trying again.', 'lock.fallback': "We're sorry, something went wrong when requesting the password change.", enterprise_email: - "Your email's domain is part of an Enterprise identity provider. To reset your password, please see your security administrator." + "Your email's domain is part of an Enterprise identity provider. To reset your password, please see your security administrator.", + invalid_captcha: 'Solve the challenge question to verify you are not a robot.', + invalid_recaptcha: 'Select the checkbox to verify you are not a robot.' }, login: { blocked_user: 'The user is blocked.', diff --git a/src/i18n/es.js b/src/i18n/es.js index 6b2a87619..8b2ec3f1c 100644 --- a/src/i18n/es.js +++ b/src/i18n/es.js @@ -5,7 +5,9 @@ export default { 'Se ha alcanzado el límite de intentos para restablecer su contraseña. Por favor, aguarde unos minutos.', 'lock.fallback': 'Ocurrió un error al restablecer su contraseña.', enterprise_email: - 'El dominio de su correo electrónico es parte de un proveedor de identidad Enterprise. Para restablecer su contraseña, consulte a su administrador de seguridad.' + 'El dominio de su correo electrónico es parte de un proveedor de identidad Enterprise. Para restablecer su contraseña, consulte a su administrador de seguridad.', + invalid_captcha: 'El texto ingresado es incorrecto.
Por favor, vuelva a intentarlo.', + invalid_recaptcha: 'Seleccione la casilla de verificación para verificar que no es un robot.' }, login: { blocked_user: 'El usuario se encuentra bloqueado.', diff --git a/src/i18n/et.js b/src/i18n/et.js index c2a3ce3fc..ebd910a5c 100644 --- a/src/i18n/et.js +++ b/src/i18n/et.js @@ -8,7 +8,9 @@ export default { 'Sa oled liiga palju kordi üritanud salasõna vahetada. Palun oota enne uuesti proovimist.', 'lock.fallback': 'Vabandame, midagi läks salasõna vahetamise sooviga valesti.', enterprise_email: - 'Teie e-posti domeen kuulub ettevõtte identiteedi pakkuja juurde. Parooli lähtestamiseks lugege oma turvameedet.' + 'Teie e-posti domeen kuulub ettevõtte identiteedi pakkuja juurde. Parooli lähtestamiseks lugege oma turvameedet.', + invalid_captcha: 'Lahendage väljakutseküsimus ja veenduge, et te pole robot.', + invalid_recaptcha: 'Valige märkeruut, et kontrollida, kas te pole robot.' }, login: { blocked_user: 'Kasutaja on blokeeritud.', diff --git a/src/i18n/fa.js b/src/i18n/fa.js index bf9fac7b9..5fde5d81a 100644 --- a/src/i18n/fa.js +++ b/src/i18n/fa.js @@ -8,7 +8,9 @@ export default { 'بیش از دفعات مجاز تغییر رمز عبور تلاش نموده اید ، لطفا کمی صبر کنید و دوباره تلاش کنید', 'lock.fallback': 'متاسفیم ، مشکلی در تغییر رمز عبور رخ داده است.', enterprise_email: - 'دامنه ایمیل شما بخشی از ارائهدهنده هویت سازمانی است. برای بازنشانی گذرواژه خود، لطفا به مدیر امنیتی خود مراجعه کنید.' + 'دامنه ایمیل شما بخشی از ارائهدهنده هویت سازمانی است. برای بازنشانی گذرواژه خود، لطفا به مدیر امنیتی خود مراجعه کنید.', + invalid_captcha: 'حل مسئله چالش برای تأیید اینکه ربات نیستید.', + invalid_recaptcha: 'کادر تأیید را انتخاب کنید تا تأیید کنید که روبات نیستید.' }, login: { blocked_user: 'کاربر مسدود شده است.', diff --git a/src/i18n/fi.js b/src/i18n/fi.js index 1f0b7b2d9..7f205f35a 100644 --- a/src/i18n/fi.js +++ b/src/i18n/fi.js @@ -9,7 +9,9 @@ export default { 'lock.fallback': 'Olemme pahoillamme, mutta jotain meni vikaan kun salasanaa yritettiin vaihtaa.', enterprise_email: - 'Sähköpostisi verkkotunnus on osa yrityspalvelun tarjoajaa. Voit palauttaa salasanasi turva-järjestelmänvalvojalta.' + 'Sähköpostisi verkkotunnus on osa yrityspalvelun tarjoajaa. Voit palauttaa salasanasi turva-järjestelmänvalvojalta.', + invalid_captcha: 'Ratkaise haastekysymys varmistaaksesi, että et ole robotti.', + invalid_recaptcha: 'Valitse valintaruutu varmistaaksesi, että et ole robotti.' }, login: { blocked_user: 'Käyttäjä on estetty.', diff --git a/src/i18n/fr.js b/src/i18n/fr.js index 8f833aa3b..d1b7a7b3c 100644 --- a/src/i18n/fr.js +++ b/src/i18n/fr.js @@ -9,7 +9,9 @@ export default { 'lock.fallback': 'Nous sommes désolés, un problème est survenu lors de la demande de changement de mot de passe.', enterprise_email: - "Le domaine de votre messagerie fait partie d'un fournisseur d'identité d'entreprise. Pour réinitialiser votre mot de passe, veuillez contacter votre administrateur de sécurité." + "Le domaine de votre messagerie fait partie d'un fournisseur d'identité d'entreprise. Pour réinitialiser votre mot de passe, veuillez contacter votre administrateur de sécurité.", + invalid_captcha: "Résolvez la question du défi pour vérifier que vous n'êtes pas un robot.", + invalid_recaptcha: "Cochez la case pour vérifier que vous n'êtes pas un robot." }, login: { blocked_user: 'L’utilisateur est bloqué.', diff --git a/src/i18n/he.js b/src/i18n/he.js index 5011aa428..ce86409a9 100644 --- a/src/i18n/he.js +++ b/src/i18n/he.js @@ -7,7 +7,9 @@ export default { too_many_requests: 'הגעת למגבלת הנסיונות לשינוי סיסמא. אנא המתן לפני הנסיון הבא.', 'lock.fallback': 'אנחנו מתנצלים, משהו השתבש בעת הנסיון לשינוי הסיסמא', enterprise_email: - 'הדומיין של כתובת המייל שלך הוא חלק מספק זהויות ארגוני. על מנת לאפס את הסיסמא שלך, אנא צור קשר עם אחראי האבטחה בארגון.' + 'הדומיין של כתובת המייל שלך הוא חלק מספק זהויות ארגוני. על מנת לאפס את הסיסמא שלך, אנא צור קשר עם אחראי האבטחה בארגון.', + invalid_captcha: 'לפתור את שאלת האתגר כדי לוודא שאתה לא רובוט.', + invalid_recaptcha: 'בחר בתיבת הסימון כדי לוודא שאתה לא רובוט.' }, login: { blocked_user: 'המשתמש חסום.', diff --git a/src/i18n/hr.js b/src/i18n/hr.js index fb1ce2f72..9474759d1 100755 --- a/src/i18n/hr.js +++ b/src/i18n/hr.js @@ -9,7 +9,9 @@ export default { 'lock.fallback': 'Ispričavamo se, ali nešto je pošlo po zlu tijekom obrade zahtjeva za promjenom lozinke.', enterprise_email: - 'Domena vaše e-pošte dio je davatelja identiteta tvrtke. Da biste poništili zaporku, obratite se svom administratoru za sigurnost.' + 'Domena vaše e-pošte dio je davatelja identiteta tvrtke. Da biste poništili zaporku, obratite se svom administratoru za sigurnost.', + invalid_captcha: 'Riješite izazovno pitanje kako biste provjerili da niste robot.', + invalid_recaptcha: 'Označite potvrdni okvir da biste potvrdili da niste robot.' }, login: { blocked_user: 'Korisnik je blokiran.', diff --git a/src/i18n/hu.js b/src/i18n/hu.js index 70c121ced..cabd58032 100644 --- a/src/i18n/hu.js +++ b/src/i18n/hu.js @@ -8,7 +8,9 @@ export default { 'Elérted a jelszóváltoztatási probálkozások engedélyezett számát. Kérjük, várj egy kicsit mielőtt újrapróbálnád!', 'lock.fallback': 'Sajnáljuk, valami hiba történt a jelszóváltoztatás során.', enterprise_email: - 'Az e-mail címed egy vállalati azonosítószolgáltatáshoz tartozik. A jelszó visszaállításában a biztonsági adminisztrátor tud segítséget nyújtani.' + 'Az e-mail címed egy vállalati azonosítószolgáltatáshoz tartozik. A jelszó visszaállításában a biztonsági adminisztrátor tud segítséget nyújtani.', + invalid_captcha: 'Oldja meg a kihívást, és ellenőrizze, hogy nem robot.', + invalid_recaptcha: 'Jelölje be a jelölőnégyzetet annak ellenőrzéséhez, hogy nem robot vagy-e.' }, login: { blocked_user: 'A felhasználó le van tiltva.', diff --git a/src/i18n/id.js b/src/i18n/id.js index 17e8e6215..5b610e5e2 100644 --- a/src/i18n/id.js +++ b/src/i18n/id.js @@ -8,7 +8,10 @@ export default { 'Anda telah mencapai batas upaya perubahan kata sandi. Harap tunggu sebelum mencoba lagi.', 'lock.fallback': 'Maaf, terjadi kesalahan saat meminta perubahan kata sandi.', enterprise_email: - 'Domain email Anda adalah bagian dari penyedia identitas Perusahaan. Untuk mengatur ulang kata sandi, harap lihat administrator keamanan Anda.' + 'Domain email Anda adalah bagian dari penyedia identitas Perusahaan. Untuk mengatur ulang kata sandi, harap lihat administrator keamanan Anda.', + invalid_captcha: + 'Selesaikan pertanyaan tantangan untuk memverifikasi bahwa Anda bukan robot.', + invalid_recaptcha: 'Pilih kotak centang untuk memverifikasi bahwa Anda bukan robot.' }, login: { blocked_user: 'Pengguna diblokir.', diff --git a/src/i18n/it.js b/src/i18n/it.js index b7ddf711c..b12975d3a 100644 --- a/src/i18n/it.js +++ b/src/i18n/it.js @@ -6,7 +6,9 @@ export default { 'lock.fallback': 'Ci dispiace, qualcosa è andato storto durante la richiesta di modifica della password.', enterprise_email: - "Il dominio della tua email fa parte di un provider di identità aziendale. Per reimpostare la password, consultare l'amministratore della sicurezza." + "Il dominio della tua email fa parte di un provider di identità aziendale. Per reimpostare la password, consultare l'amministratore della sicurezza.", + invalid_captcha: 'Risolvi la domanda di verifica per verificare che non sei un robot.', + invalid_recaptcha: 'Seleziona la casella di controllo per verificare che non sei un robot.' }, login: { blocked_user: "L'utente è bloccato.", diff --git a/src/i18n/ja.js b/src/i18n/ja.js index c3a75ae89..b199bc977 100644 --- a/src/i18n/ja.js +++ b/src/i18n/ja.js @@ -9,7 +9,9 @@ export default { 'lock.fallback': '申し訳ございません。パスワード変更中に何らかの理由によりエラーが発生しました。', enterprise_email: - '電子メールのドメインは、エンタープライズ向けIDプロバイダの一部です。パスワードをリセットするには、セキュリティ管理者にお問い合わせください。' + '電子メールのドメインは、エンタープライズ向けIDプロバイダの一部です。パスワードをリセットするには、セキュリティ管理者にお問い合わせください。', + invalid_captcha: 'チャレンジ質問を解いて、ロボットではないことを確認してください。', + invalid_recaptcha: 'チェックボックスを選択して、ロボットでないことを確認します。' }, login: { blocked_user: 'ユーザーはブロックされています。', diff --git a/src/i18n/ko.js b/src/i18n/ko.js index cd9559d26..5047815dd 100644 --- a/src/i18n/ko.js +++ b/src/i18n/ko.js @@ -8,7 +8,9 @@ export default { '비밀번호 변경 요청 횟수가 제한을 초과하였습니다. 시간을 두고 나중에 다시 시도해 주세요.', 'lock.fallback': '죄송합니다. 특정 오류로 인해 비밀번호 변경에 실패하였습니다.', enterprise_email: - '이메일 도메인은 엔터프라이즈 ID 제공 업체의 일부입니다. 암호를 재설정하려면 보안 관리자에게 문의하십시오.' + '이메일 도메인은 엔터프라이즈 ID 제공 업체의 일부입니다. 암호를 재설정하려면 보안 관리자에게 문의하십시오.', + invalid_captcha: '로봇이 아닌 사람인지 확인하기 위해 챌린지 질문을 해결하십시오.', + invalid_recaptcha: '로봇이 아닌지 확인하려면 확인란을 선택하십시오.' }, login: { blocked_user: '차단된 사용자 계정입니다.', diff --git a/src/i18n/lt.js b/src/i18n/lt.js index 24e6ddfe6..06b529879 100644 --- a/src/i18n/lt.js +++ b/src/i18n/lt.js @@ -8,7 +8,9 @@ export default { 'Jūs pasiekėte slaptažodžio keitimų limitą. Prašome palaukti, prieš bandant dar kartą.', 'lock.fallback': 'Atsiprašome, nesklandumai keičiant slaptažodį.', enterprise_email: - 'Jūsų el.pašto domenas yra Enterprise tapatybės teikėjo dalis. Norėdami iš naujo nustatyti slaptažodį, apsilankykite pas savo saugumo administratorių.' + 'Jūsų el.pašto domenas yra Enterprise tapatybės teikėjo dalis. Norėdami iš naujo nustatyti slaptažodį, apsilankykite pas savo saugumo administratorių.', + invalid_captcha: 'Išspręskite iššūkio klausimą ir įsitikinkite, kad nesate robotas.', + invalid_recaptcha: 'Pažymėkite žymimąjį laukelį, kad patikrintumėte, ar nesate robotas.' }, login: { blocked_user: 'Vartotojas užblokuotas.', diff --git a/src/i18n/lv.js b/src/i18n/lv.js index e7c432012..51e6b1320 100644 --- a/src/i18n/lv.js +++ b/src/i18n/lv.js @@ -8,7 +8,9 @@ export default { 'Jūs sasniedzāt atļauto paroles maiņas mēģinājumu skaitu. Lūdzu, uzgaidiet, pirms mēģinat vēlreiz.', 'lock.fallback': 'Diemžēl, pieprasot paroles maiņu, radās problēma.', enterprise_email: - 'Jūsu e-pasta domēns ir daļa no uzņēmuma identitātes nodrošinātāja. Lai atiestatītu paroli, lūdzu, sazinieties ar administratoru.' + 'Jūsu e-pasta domēns ir daļa no uzņēmuma identitātes nodrošinātāja. Lai atiestatītu paroli, lūdzu, sazinieties ar administratoru.', + invalid_captcha: 'Atrisiniet izaicinājuma jautājumu, lai pārliecinātos, ka neesat robots.', + invalid_recaptcha: 'Atzīmējiet izvēles rūtiņu, lai pārliecinātos, ka neesat robots.' }, login: { blocked_user: 'Lietotājs ir bloķēts.', diff --git a/src/i18n/ms.js b/src/i18n/ms.js index 1f8a20197..b77cfea5e 100644 --- a/src/i18n/ms.js +++ b/src/i18n/ms.js @@ -8,7 +8,9 @@ export default { 'Anda telah mencapai had percubaan penukaran kata laluan. Sila tunggu sebelum mencuba lagi.', 'lock.fallback': 'Harap maaf, sesuatu berlaku semasa meminta penukaran kata laluan.', enterprise_email: - 'Domain e-mel anda merupakan sebahagian daripada penyedia identiti Perusahaan. Untuk menetapkan semula kata laluan anda, sila berjumpa dengan pentadbir keselamatan anda.' + 'Domain e-mel anda merupakan sebahagian daripada penyedia identiti Perusahaan. Untuk menetapkan semula kata laluan anda, sila berjumpa dengan pentadbir keselamatan anda.', + invalid_captcha: 'Selesaikan soalan cabaran untuk mengesahkan bahawa anda bukan robot.', + invalid_recaptcha: 'Pilih kotak pilihan untuk mengesahkan bahawa anda bukan robot.', }, login: { blocked_user: 'Pengguna ini disekat.', diff --git a/src/i18n/nb.js b/src/i18n/nb.js index 130237f64..b971e7edc 100644 --- a/src/i18n/nb.js +++ b/src/i18n/nb.js @@ -8,7 +8,9 @@ export default { 'Du er midlertidig blokkert på grunn av for mange passord-endringsforsøk. Vent litt før du prøver igjen.', 'lock.fallback': 'Beklager, noe gikk galt med forespørselen om passord endring.', enterprise_email: - 'E-postdomenet ditt er en del av en Enterprise Identity-leverandør. For å tilbakestille passordet, vennligst se din sikkerhetsadministrator.' + 'E-postdomenet ditt er en del av en Enterprise Identity-leverandør. For å tilbakestille passordet, vennligst se din sikkerhetsadministrator.', + invalid_captcha: 'Løs utfordringsspørsmålet for å bekrefte at du ikke er en robot.', + invalid_recaptcha: 'Merk av i avmerkingsboksen for å bekrefte at du ikke er en robot.' }, login: { blocked_user: 'Brukeren er blokkert.', diff --git a/src/i18n/nl.js b/src/i18n/nl.js index 9fc7fcf7c..d20a4c583 100644 --- a/src/i18n/nl.js +++ b/src/i18n/nl.js @@ -9,7 +9,9 @@ export default { 'lock.fallback': 'Onze excuses, er is iets fout gegaan bij de de aanvraag voor een wachtwoord wijziging.', enterprise_email: - 'Het domein van uw e-mail maakt deel uit van een Enterprise-identiteitsprovider. Raadpleeg uw beveiligingsbeheerder om uw wachtwoord opnieuw in te stellen.' + 'Het domein van uw e-mail maakt deel uit van een Enterprise-identiteitsprovider. Raadpleeg uw beveiligingsbeheerder om uw wachtwoord opnieuw in te stellen.', + invalid_captcha: 'Los de vraag op om te verifiëren dat u geen robot bent.', + invalid_recaptcha: 'Selecteer het vakje om te verifiëren dat u geen robot bent.' }, login: { blocked_user: 'De gebruiker is geblokkeerd.', diff --git a/src/i18n/nn.js b/src/i18n/nn.js index e3fbfd504..0beda0164 100644 --- a/src/i18n/nn.js +++ b/src/i18n/nn.js @@ -8,7 +8,9 @@ export default { 'Du har nådd grensa for antal forsøk på å endre passord. Ver venleg og vent ei stund før du prøvar på nytt', 'lock.fallback': 'Beklagar, men noko giekk galt då du prøvde å endre passordet.', enterprise_email: - 'E-postdomenet ditt er ein del av ein Enterprise Identity-leverandør. For å tilbakestille passordet, ver venleg og kontakt din sikkerheitsadministrator.' + 'E-postdomenet ditt er ein del av ein Enterprise Identity-leverandør. For å tilbakestille passordet, ver venleg og kontakt din sikkerheitsadministrator.', + invalid_captcha: 'Løs utfordringsspørsmålet for å bekrefte at du ikke er en robot.', + invalid_recaptcha: 'Merk av i avmerkingsboksen for å bekrefte at du ikke er en robot.' }, login: { blocked_user: 'Denne brukaren er blokkert', diff --git a/src/i18n/no.js b/src/i18n/no.js index 706dd5dde..c1eb0f9ca 100644 --- a/src/i18n/no.js +++ b/src/i18n/no.js @@ -8,7 +8,9 @@ export default { 'Du har nådd grensen for antall forsøk på å endre passord. Vennligst vent en stund før du forsøker på nytt', 'lock.fallback': 'Beklager, men noe gikk galt når du forsøkte å endre passordet.', enterprise_email: - 'E-postdomenet ditt er en del av en Enterprise Identity-leverandør. For å tilbakestille passordet, vennligst se din sikkerhetsadministrator.' + 'E-postdomenet ditt er en del av en Enterprise Identity-leverandør. For å tilbakestille passordet, vennligst se din sikkerhetsadministrator.', + invalid_captcha: 'Løs utfordringsspørsmålet for å bekrefte at du ikke er en robot.', + invalid_recaptcha: 'Merk av i avmerkingsboksen for å bekrefte at du ikke er en robot.' }, login: { blocked_user: 'Denne brukeren er blokkert', diff --git a/src/i18n/pl.js b/src/i18n/pl.js index 3ff15d060..f92b7580b 100644 --- a/src/i18n/pl.js +++ b/src/i18n/pl.js @@ -8,7 +8,9 @@ export default { 'Przekroczyłeś limit prób zmiany hasła. Odczekaj chwilę, zanim spróbujesz ponownie.', 'lock.fallback': 'Przykro nam, coś poszło nie tak podczas próby zmiany hasła.', enterprise_email: - 'Domena Twojego adresu e-mail jest częścią dostawcy tożsamości korporacyjnej. Aby zresetować hasło, skontaktuj się z administratorem bezpieczeństwa.' + 'Domena Twojego adresu e-mail jest częścią dostawcy tożsamości korporacyjnej. Aby zresetować hasło, skontaktuj się z administratorem bezpieczeństwa.', + invalid_captcha: 'Rozwiąż pytanie kontrolne, aby sprawdzić, czy nie jesteś robotem.', + invalid_recaptcha: 'Zaznacz pole wyboru, aby potwierdzić, że nie jesteś robotem.' }, login: { blocked_user: 'Ten użytkownik jest zablokowany.', diff --git a/src/i18n/pt-br.js b/src/i18n/pt-br.js index 06769d8c8..9b8e2daed 100644 --- a/src/i18n/pt-br.js +++ b/src/i18n/pt-br.js @@ -5,7 +5,9 @@ export default { 'Você atingiu o limite máximo de tentativas. Por favor aguarde antes de tentar novamente.', 'lock.fallback': 'Sentimos muito, mas algo deu errado ao requisitar a mudança de senha.', enterprise_email: - "O domínio do seu e-mail faz parte de um provedor de identidade 'Enterprise'. Para redefinir sua senha, consulte seu administrador de segurança." + "O domínio do seu e-mail faz parte de um provedor de identidade 'Enterprise'. Para redefinir sua senha, consulte seu administrador de segurança.", + invalid_captcha: 'Resolva a questão do desafio para verificar se você não é um robô.', + invalid_recaptcha: 'Marque a caixa de seleção para verificar se você não é um robô.' }, login: { blocked_user: 'O usuário está bloqueado.', diff --git a/src/i18n/pt.js b/src/i18n/pt.js index 17a5a224b..a77745c8c 100644 --- a/src/i18n/pt.js +++ b/src/i18n/pt.js @@ -8,7 +8,9 @@ export default { 'Foi atingido o limite de tentativas de alteração da palavra-passe. Aguarde antes de tentar novamente.', 'lock.fallback': 'Lamentamos, ocorreu um problema ao solicitar a alteração da palavra-passe.', enterprise_email: - 'O domínio do seu endereço eletrónico é parte de um fornecedor de identidade empresarial. Para repor a sua palavra-passe, consulte o seu administrador de segurança.' + 'O domínio do seu endereço eletrónico é parte de um fornecedor de identidade empresarial. Para repor a sua palavra-passe, consulte o seu administrador de segurança.', + invalid_captcha: 'Resolva a questão do desafio para verificar se você não é um robô.', + invalid_recaptcha: 'Marque a caixa de seleção para verificar se você não é um robô.' }, login: { blocked_user: 'O utilizador está bloqueado.', diff --git a/src/i18n/ro.js b/src/i18n/ro.js index faa0484af..9e33c1a3a 100644 --- a/src/i18n/ro.js +++ b/src/i18n/ro.js @@ -8,7 +8,9 @@ export default { 'Ai depășit limita de introducere a parolei. Avem rugămintea să aștepți până la următoarea încercare.', 'lock.fallback': 'Ne pare rău, a apărut o eroare în procesul de recuperare a parolei.', enterprise_email: - 'Domeniul e-mailului dvs. face parte dintr-un furnizor de identitate de tip Enterprise. Pentru a reseta parola, consultați administratorul de securitate.' + 'Domeniul e-mailului dvs. face parte dintr-un furnizor de identitate de tip Enterprise. Pentru a reseta parola, consultați administratorul de securitate.', + invalid_captcha: 'Rezolvați întrebarea pentru a verifica dacă nu sunteți un robot.', + invalid_recaptcha: 'Selectați caseta pentru a verifica dacă nu sunteți un robot.' }, login: { blocked_user: 'Utilizatorul este blocat.', diff --git a/src/i18n/ru.js b/src/i18n/ru.js index d8a521cf3..f5d39dd3a 100644 --- a/src/i18n/ru.js +++ b/src/i18n/ru.js @@ -9,7 +9,9 @@ export default { 'lock.fallback': 'Произошла непредвиденная ошибка при запросе на восстановление пароля. Приносим свои извинения.', enterprise_email: - 'Домен вашей электронной почты является частью корпоративной информационной системы. Чтобы сбросить пароль, обратитесь к администратору службы безопасности.' + 'Домен вашей электронной почты является частью корпоративной информационной системы. Чтобы сбросить пароль, обратитесь к администратору службы безопасности.', + invalid_captcha: 'Решите сложный вопрос, чтобы убедиться, что вы не робот.', + invalid_recaptcha: 'Установите флажок, чтобы убедиться, что вы не робот.' }, login: { blocked_user: 'Пользователь заблокирован.', diff --git a/src/i18n/sk.js b/src/i18n/sk.js index 0f2ae2fd6..a219b91c9 100644 --- a/src/i18n/sk.js +++ b/src/i18n/sk.js @@ -8,7 +8,9 @@ export default { 'Prekročili ste limit pokusov o zmenu hesla. Prosím počkajte pred ďalším pokusom.', 'lock.fallback': 'Prepáčte, zmena hesla nebola úspešná.', enterprise_email: - 'Doména vášho e-mailu je súčasťou poskytovateľa Enterprise Identity. Ak chcete obnoviť svoje heslo, navštívte správcu zabezpečenia.' + 'Doména vášho e-mailu je súčasťou poskytovateľa Enterprise Identity. Ak chcete obnoviť svoje heslo, navštívte správcu zabezpečenia.', + invalid_captcha: 'Vyriešte výzvu a overte, či nie ste robot.', + invalid_recaptcha: 'Začiarknutím políčka overíte, či nie ste robot.' }, login: { blocked_user: 'Užívateľ je blokovaný.', diff --git a/src/i18n/sl.js b/src/i18n/sl.js index 0a0204177..d7591a7a0 100644 --- a/src/i18n/sl.js +++ b/src/i18n/sl.js @@ -8,7 +8,9 @@ export default { 'Dosegli ste omejitev števila poskusov spremembe gesla. Pred ponovnim poskusom morate počakati.', 'lock.fallback': 'Žal je prišlo do napake pri zahtevi za spremembo gesla.', enterprise_email: - 'Domena vašega e-poštnega naslova je del ponudnika identitete podjetja. Če želite ponastaviti geslo, obiščite svojega skrbnika za varnost.' + 'Domena vašega e-poštnega naslova je del ponudnika identitete podjetja. Če želite ponastaviti geslo, obiščite svojega skrbnika za varnost.', + invalid_captcha: 'Rešite izzivno vprašanje in preverite, ali niste robot.', + invalid_recaptcha: 'Izberite potrditveno polje, da preverite, da niste robot.' }, login: { blocked_user: 'Uporabnik je blokiran.', diff --git a/src/i18n/sr.js b/src/i18n/sr.js index a23d08c89..4049796c6 100644 --- a/src/i18n/sr.js +++ b/src/i18n/sr.js @@ -8,7 +8,9 @@ export default { 'Dostigli ste ograničenje broja pokušaja promene lozinke. Sačekajte pre nego što pokušate ponovo.', 'lock.fallback': 'Žao nam je, došlo je do greške prilikom slanja zahteva za promenu lozinke.', enterprise_email: - 'Domen vaše adrese e-pošte pripada kompanijskom dobavljaču identiteta. Da biste ponovo postavili lozinku, obratite se administratoru bezbednosti.' + 'Domen vaše adrese e-pošte pripada kompanijskom dobavljaču identiteta. Da biste ponovo postavili lozinku, obratite se administratoru bezbednosti.', + invalid_captcha: 'Решите изазовно питање да бисте потврдили да нисте робот.', + invalid_recaptcha: 'Потврдите избор у пољу за потврду да нисте робот.' }, login: { blocked_user: 'Korisnik je blokiran.', diff --git a/src/i18n/sv.js b/src/i18n/sv.js index b1a729648..a7082fcf6 100644 --- a/src/i18n/sv.js +++ b/src/i18n/sv.js @@ -8,7 +8,9 @@ export default { 'Du har nått gränsen för maximalt antal försök att ändra ditt lösenord. Vänta och försök sedan igen.', 'lock.fallback': 'Något gick fel när vi försökte ändra ditt lösenord.', enterprise_email: - 'Din e-post domän är en del av en företagsidentitetsleverantör. För att återställa ditt lösenord, se din säkerhetsadministratör.' + 'Din e-post domän är en del av en företagsidentitetsleverantör. För att återställa ditt lösenord, se din säkerhetsadministratör.', + invalid_captcha: 'Lös utmaningsfrågan för att verifiera att du inte är en robot.', + invalid_recaptcha: 'Markera kryssrutan för att verifiera att du inte är en robot.' }, login: { blocked_user: 'Användaren är spärrad.', diff --git a/src/i18n/tr.js b/src/i18n/tr.js index 5c07ce876..f2ed23ed9 100644 --- a/src/i18n/tr.js +++ b/src/i18n/tr.js @@ -9,7 +9,9 @@ export default { 'lock.fallback': 'Özür dileriz, şifre değiştirme isteğiniz gerçekleştirilirken bir hata oluştu.', enterprise_email: - 'E-postanızın alanı, bir kurumsal kimlik sağlayıcısının parçasıdır. Parolanızı sıfırlamak için lütfen güvenlik yöneticinize başvurun.' + 'E-postanızın alanı, bir kurumsal kimlik sağlayıcısının parçasıdır. Parolanızı sıfırlamak için lütfen güvenlik yöneticinize başvurun.', + invalid_captcha: 'Robot olmadığınızı doğrulamak için meydan okuma sorusunu çözün.', + invalid_recaptcha: 'Robot olmadığınızı doğrulamak için onay kutusunu seçin.' }, login: { blocked_user: 'Kullanıcı engellendi.', diff --git a/src/i18n/ua.js b/src/i18n/ua.js index 82761f28a..9be0a5eb1 100644 --- a/src/i18n/ua.js +++ b/src/i18n/ua.js @@ -8,7 +8,9 @@ export default { 'Ви досягли граничної кількості запитів на відновлення паролю. Будь ласка, почекайте перед повторною спробою.', 'lock.fallback': 'Йой! Виникла непередбачувана помилка. Перепрошуємо.', enterprise_email: - "Your email's domain is part of an Enterprise identity provider. To reset your password, please see your security administrator." + "Your email's domain is part of an Enterprise identity provider. To reset your password, please see your security administrator.", + invalid_captcha: 'Вирішіть складне питання, щоб переконатися, що ви не робот.', + invalid_recaptcha: 'Установіть прапорець, щоб переконатися, що ви не робот.' }, login: { blocked_user: 'Користувач заблокований.', diff --git a/src/i18n/uk.js b/src/i18n/uk.js index 15e819e07..0ae688c4b 100644 --- a/src/i18n/uk.js +++ b/src/i18n/uk.js @@ -8,7 +8,9 @@ export default { 'Ви досягли обмеження на кількість спроб зміни пароля. Почекайте, перш ніж продовжити спроби.', 'lock.fallback': 'На жаль, при запиті на заміну пароля сталася помилка.', enterprise_email: - 'Ваш домен електронної пошти є частиною постачальника корпоративної ідентифікації. Щоб скинути свій пароль, зверніться до адміністратора безпеки.' + 'Ваш домен електронної пошти є частиною постачальника корпоративної ідентифікації. Щоб скинути свій пароль, зверніться до адміністратора безпеки.', + invalid_captcha: 'Вирішіть складне питання, щоб переконатися, що ви не робот.', + invalid_recaptcha: 'Установіть прапорець, щоб переконатися, що ви не робот.' }, login: { blocked_user: 'Користувача заблоковано.', diff --git a/src/i18n/vi.js b/src/i18n/vi.js index 9dfb57b5c..429eb12dc 100644 --- a/src/i18n/vi.js +++ b/src/i18n/vi.js @@ -8,7 +8,9 @@ export default { 'Bạn đã sử dụng tối đa số lần đổi mật khẩu được cho phép. Vui lòng thử lại sau.', 'lock.fallback': 'Đã có lỗi xảy ra trong lúc thay đổi mật khẩu, chúng tôi rất lấy làm tiếc.', enterprise_email: - 'Tên miền email của bạn là một phần của một nhà cung cấp nhận dạng doanh nghiệp. Để đặt lại mật khẩu của bạn, vui lòng xem quản trị viên bảo mật của bạn.' + 'Tên miền email của bạn là một phần của một nhà cung cấp nhận dạng doanh nghiệp. Để đặt lại mật khẩu của bạn, vui lòng xem quản trị viên bảo mật của bạn.', + invalid_captcha: 'Giải quyết câu hỏi thử thách để xác minh bạn không phải là robot.', + invalid_recaptcha: 'Chọn hộp kiểm để xác minh bạn không phải là robot.' }, login: { blocked_user: 'Tài khoản đã bị khóa.', diff --git a/src/i18n/zh-tw.js b/src/i18n/zh-tw.js index 81a6a0d61..fd65cb966 100644 --- a/src/i18n/zh-tw.js +++ b/src/i18n/zh-tw.js @@ -7,7 +7,9 @@ export default { too_many_requests: '嘗試登入次數太多,請稍後再試。', 'lock.fallback': '對不起,修改密碼時發生錯誤。', enterprise_email: - '您的電子郵件域名是企業身份提供者的一部分。要重置您的密碼,請聯繫您的安全管理員。' + '您的電子郵件域名是企業身份提供者的一部分。要重置您的密碼,請聯繫您的安全管理員。', + invalid_captcha: '解決挑戰問題以驗證您不是機器人。', + invalid_recaptcha: '選中復選框以確認您不是機器人。' }, login: { blocked_user: '帳號已被鎖定。', diff --git a/src/i18n/zh.js b/src/i18n/zh.js index 8c60e7f9b..c219d8947 100644 --- a/src/i18n/zh.js +++ b/src/i18n/zh.js @@ -7,7 +7,9 @@ export default { too_many_requests: '您尝试登录次数过多 请稍后再试。', 'lock.fallback': '对不起,请求修改密码时出现错误。', enterprise_email: - '您的电子邮件域名是企业身份提供者的一部分。要重置您的密码,请联系您的安全管理员。' + '您的电子邮件域名是企业身份提供者的一部分。要重置您的密码,请联系您的安全管理员。', + invalid_captcha: '解决挑战问题以验证您不是机器人。', + invalid_recaptcha: '选中复选框以确认您不是机器人。' }, login: { blocked_user: '该账号已被锁定。',