diff --git a/package.json b/package.json index ed9b5b54b..e2ea340ce 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "webpack-dev-server": "^2.3.0" }, "dependencies": { - "auth0-js": "^9.19.2", + "auth0-js": "^9.20.0", "auth0-password-policies": "^1.0.2", "blueimp-md5": "^2.19.0", "classnames": "^2.3.2", diff --git a/src/__tests__/connection/passwordless/passwordless.actions.test.js b/src/__tests__/connection/passwordless/passwordless.actions.test.js index ffa8d7e51..a0e173d5c 100644 --- a/src/__tests__/connection/passwordless/passwordless.actions.test.js +++ b/src/__tests__/connection/passwordless/passwordless.actions.test.js @@ -29,7 +29,8 @@ describe('passwordless actions', () => { })); jest.mock('core/web_api', () => ({ startPasswordless: jest.fn(), - passwordlessVerify: jest.fn() + passwordlessVerify: jest.fn(), + getPasswordlessChallenge: jest.fn() })); jest.mock('core/actions', () => ({ closeLock: jest.fn(), @@ -50,7 +51,8 @@ describe('passwordless actions', () => { }, emitAuthorizationErrorEvent: jest.fn(), connections: jest.fn(), - useCustomPasswordlessConnection: jest.fn(() => false) + useCustomPasswordlessConnection: jest.fn(() => false), + passwordlessCaptcha: jest.fn() })); jest.mock('store/index', () => ({ read: jest.fn(() => 'model'), 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 new file mode 100644 index 000000000..52ccc6769 --- /dev/null +++ b/src/__tests__/engine/passwordless/__snapshots__/social_or_email_login_screen.test.js.snap @@ -0,0 +1,73 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`email passwordless renders a captcha 1`] = ` +
+
+
+

+ passwordlessEmailAlternativeInstructions +

+
+
+
+`; + +exports[`email passwordless renders correctly 1`] = ` +
+
+
+

+ passwordlessEmailAlternativeInstructions +

+
+
+`; 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 new file mode 100644 index 000000000..838c56346 --- /dev/null +++ b/src/__tests__/engine/passwordless/__snapshots__/social_or_phone_number_login_screen.test.js.snap @@ -0,0 +1,57 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`sms passwordless renders a captcha 1`] = ` +
+
+
+
+
+
+`; + +exports[`sms passwordless renders correctly 1`] = ` +
+
+
+
+
+`; diff --git a/src/__tests__/engine/passwordless/social_or_email_login_screen.test.js b/src/__tests__/engine/passwordless/social_or_email_login_screen.test.js new file mode 100644 index 000000000..0dfdb59da --- /dev/null +++ b/src/__tests__/engine/passwordless/social_or_email_login_screen.test.js @@ -0,0 +1,78 @@ +import React from 'react'; + +import { expectComponent, mockComponent } from 'testUtils'; + +jest.mock('connection/enterprise'); +jest.mock('core/index'); + +jest.mock('field/social/social_buttons_pane', () => mockComponent('social_buttons_pane')); +jest.mock('field/email/email_pane', () => mockComponent('email_pane')); +jest.mock('field/captcha/captcha_pane', () => mockComponent('captcha_pane')); +jest.mock('core/pane_separator', () => mockComponent('pane_separator')); +jest.mock('connection/database/sign_up_terms', () => mockComponent('sign_up_terms')); +jest.mock('connection/passwordless/index', () => ({ + isEmail: jest.fn() +})); + +const getComponent = () => { + const SocialOrEmailScreen = require('engine/passwordless/social_or_email_login_screen').default; + const screen = new SocialOrEmailScreen(); + return screen.render(); +}; + +describe('email passwordless', () => { + beforeEach(() => { + jest.resetModules(); + jest.resetAllMocks(); + + jest.mock('connection/database/index', () => ({ + hasScreen: () => false, + databaseUsernameValue: jest.fn() + })); + + jest.mock('connection/database/actions', () => ({ + cancelMFALogin: jest.fn(), + logIn: jest.fn() + })); + + jest.mock('core/signed_in_confirmation', () => ({ + renderSignedInConfirmation: jest.fn() + })); + + jest.mock('connection/enterprise', () => ({ + isHRDEmailValid: jest.fn(() => false), + isHRDDomain: jest.fn(() => true) + })); + + jest.mock('core/index', () => ({ + hasSomeConnections: jest.fn(() => true), + passwordlessCaptcha: jest.fn() + })); + }); + + const defaultProps = { + i18n: { + str: (...keys) => keys.join(','), + html: (...keys) => keys.join(',') + }, + model: 'model' + }; + + it('renders correctly', () => { + const Component = getComponent(); + + expectComponent().toMatchSnapshot(); + }); + + it('renders a captcha', () => { + const Component = getComponent(); + + require('core/index').passwordlessCaptcha.mockReturnValue({ + get() { + return true; + } + }); + + expectComponent().toMatchSnapshot(); + }); +}); diff --git a/src/__tests__/engine/passwordless/social_or_phone_number_login_screen.test.js b/src/__tests__/engine/passwordless/social_or_phone_number_login_screen.test.js new file mode 100644 index 000000000..4fc45a12a --- /dev/null +++ b/src/__tests__/engine/passwordless/social_or_phone_number_login_screen.test.js @@ -0,0 +1,78 @@ +import React from 'react'; + +import { expectComponent, mockComponent } from 'testUtils'; + +jest.mock('connection/enterprise'); +jest.mock('core/index'); + +jest.mock('field/social/social_buttons_pane', () => mockComponent('social_buttons_pane')); +jest.mock('field/phone-number/phone_number_pane', () => mockComponent('phone_number_pane')); +jest.mock('field/captcha/captcha_pane', () => mockComponent('captcha_pane')); +jest.mock('core/pane_separator', () => mockComponent('pane_separator')); +jest.mock('connection/database/sign_up_terms', () => mockComponent('sign_up_terms')); +jest.mock('connection/passwordless/index', () => ({ + isEmail: jest.fn() +})); + +const getComponent = () => { + const SocialOrPhoneNumberScreen = require('engine/passwordless/social_or_phone_number_login_screen').default; + const screen = new SocialOrPhoneNumberScreen(); + return screen.render(); +}; + +describe('sms passwordless', () => { + beforeEach(() => { + jest.resetModules(); + jest.resetAllMocks(); + + jest.mock('connection/database/index', () => ({ + hasScreen: () => false, + databaseUsernameValue: jest.fn() + })); + + jest.mock('connection/database/actions', () => ({ + cancelMFALogin: jest.fn(), + logIn: jest.fn() + })); + + jest.mock('core/signed_in_confirmation', () => ({ + renderSignedInConfirmation: jest.fn() + })); + + jest.mock('connection/enterprise', () => ({ + isHRDEmailValid: jest.fn(() => false), + isHRDDomain: jest.fn(() => true) + })); + + jest.mock('core/index', () => ({ + hasSomeConnections: jest.fn(() => true), + passwordlessCaptcha: jest.fn() + })); + }); + + const defaultProps = { + i18n: { + str: (...keys) => keys.join(','), + html: (...keys) => keys.join(',') + }, + model: 'model' + }; + + it('renders correctly', () => { + const Component = getComponent(); + + expectComponent().toMatchSnapshot(); + }); + + it('renders a captcha', () => { + const Component = getComponent(); + + require('core/index').passwordlessCaptcha.mockReturnValue({ + get() { + return true; + } + }); + + expectComponent().toMatchSnapshot(); + }); +}); diff --git a/src/connection/captcha.js b/src/connection/captcha.js index b44184a32..9ac89fdb2 100644 --- a/src/connection/captcha.js +++ b/src/connection/captcha.js @@ -9,12 +9,15 @@ import webApi from '../core/web_api'; * * @param {Object} m model * @param {Number} id + * @param {Boolean} isPasswordless Whether the captcha is being rendered in a passwordless flow */ -export function showMissingCaptcha(m, id) { - const captchaConfig = l.captcha(m); +export function showMissingCaptcha(m, id, isPasswordless = false) { + const captchaConfig = isPasswordless ? l.passwordlessCaptcha(m) : l.captcha(m); - const captchaError = - captchaConfig.get('provider') === 'recaptcha_v2' ? 'invalid_recaptcha' : 'invalid_captcha'; + const captchaError = ( + captchaConfig.get('provider') === 'recaptcha_v2' || + captchaConfig.get('provider') === 'recaptcha_enterprise' + ) ? 'invalid_recaptcha' : 'invalid_captcha'; const errorMessage = i18n.html(m, ['error', 'login', captchaError]); @@ -31,13 +34,14 @@ export function showMissingCaptcha(m, id) { * * @param {Object} m model * @param {Object} params + * @param {Boolean} isPasswordless Whether the captcha is being rendered in a passwordless flow * @param {Object} fields * * @returns {Boolean} returns true if is required and missing the response from the user */ -export function setCaptchaParams(m, params, fields) { - const captchaConfig = l.captcha(m); - const isCaptchaRequired = captchaConfig && l.captcha(m).get('required'); +export function setCaptchaParams(m, params, isPasswordless, fields) { + const captchaConfig = isPasswordless ? l.passwordlessCaptcha(m) : l.captcha(m); + const isCaptchaRequired = captchaConfig && captchaConfig.get('required'); if (!isCaptchaRequired) { return true; @@ -57,10 +61,21 @@ export function setCaptchaParams(m, params, 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 {boolean} wasInvalid A boolean indicating if the previous captcha was invalid. * @param {Function} [next] A callback. */ -export function swapCaptcha(id, wasInvalid, next) { +export function swapCaptcha(id, isPasswordless, wasInvalid, next) { + if (isPasswordless) { + return webApi.getPasswordlessChallenge(id, (err, newCaptcha) => { + if (!err && newCaptcha) { + swap(updateEntity, 'lock', id, l.setPasswordlessCaptcha, newCaptcha, wasInvalid); + } + if (next) { + next(); + } + }); + } return webApi.getChallenge(id, (err, newCaptcha) => { if (!err && newCaptcha) { swap(updateEntity, 'lock', id, l.setCaptcha, newCaptcha, wasInvalid); diff --git a/src/connection/database/actions.js b/src/connection/database/actions.js index df96cd44a..2d92a4deb 100644 --- a/src/connection/database/actions.js +++ b/src/connection/database/actions.js @@ -33,7 +33,7 @@ export function logIn(id, needsMFA = false) { }; const fields = [usernameField, 'password']; - const isCaptchaValid = setCaptchaParams(m, params, fields); + const isCaptchaValid = setCaptchaParams(m, params, false, 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, wasInvalid, next); + return swapCaptcha(id, false, wasInvalid, next); } next(); @@ -88,7 +88,7 @@ export function signUp(id) { autoLogin: shouldAutoLogin(m) }; - const isCaptchaValid = setCaptchaParams(m, params, fields); + const isCaptchaValid = setCaptchaParams(m, params, false, fields); if (!isCaptchaValid) { return showMissingCaptcha(m, id); } @@ -131,7 +131,7 @@ export function signUp(id) { const wasInvalidCaptcha = error && error.code === 'invalid_captcha'; - swapCaptcha(id, wasInvalidCaptcha, () => { + swapCaptcha(id, false, 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, true, () => { + return swapCaptcha(id, false, true, () => { swap(updateEntity, 'lock', id, l.setSubmitting, false, errorMessage); }); } diff --git a/src/connection/database/login_pane.jsx b/src/connection/database/login_pane.jsx index 5ed0ec26f..7339f3023 100644 --- a/src/connection/database/login_pane.jsx +++ b/src/connection/database/login_pane.jsx @@ -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)} /> + swapCaptcha(l.id(lock), false, false)} /> ) : null; const dontRememberPassword = diff --git a/src/connection/enterprise/actions.js b/src/connection/enterprise/actions.js index 48cc4807a..8dbaa8daa 100644 --- a/src/connection/enterprise/actions.js +++ b/src/connection/enterprise/actions.js @@ -53,7 +53,7 @@ export function logIn(id) { return logInSSO(id, ssoConnection, params); } - const isCaptchaValid = setCaptchaParams(m, params, fields); + const isCaptchaValid = setCaptchaParams(m, params, false, 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, wasCaptchaInvalid, next); + swapCaptcha(id, false, wasCaptchaInvalid, next); } ); } diff --git a/src/connection/enterprise/hrd_pane.jsx b/src/connection/enterprise/hrd_pane.jsx index 9d6bca783..b9854b6a6 100644 --- a/src/connection/enterprise/hrd_pane.jsx +++ b/src/connection/enterprise/hrd_pane.jsx @@ -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)} /> + swapCaptcha(l.id(model), false, false)} /> ) : null; return ( diff --git a/src/connection/passwordless/actions.js b/src/connection/passwordless/actions.js index e7b201018..a99239e0f 100644 --- a/src/connection/passwordless/actions.js +++ b/src/connection/passwordless/actions.js @@ -1,6 +1,5 @@ -import { Map } from 'immutable'; import { read, getEntity, swap, updateEntity } from '../../store/index'; -import { closeLock, logIn as coreLogIn, validateAndSubmit, logInSuccess } from '../../core/actions'; +import { validateAndSubmit, logInSuccess } from '../../core/actions'; import webApi from '../../core/web_api'; import * as c from '../../field/index'; import * as l from '../../core/index'; @@ -17,8 +16,9 @@ import { } from './index'; import { phoneNumberWithDiallingCode } from '../../field/phone_number'; import * as i18n from '../../i18n'; +import { setCaptchaParams, showMissingCaptcha, swapCaptcha } from '../captcha'; -function getErrorMessage(m, error) { +function getErrorMessage(m, id, error) { let key = error.error; if ( @@ -28,15 +28,28 @@ function getErrorMessage(m, error) { key = 'bad.phone_number'; } + if (error.code === 'invalid_captcha') { + const captchaConfig = l.passwordlessCaptcha(m); + key = ( + captchaConfig.get('provider') === 'recaptcha_v2' || + captchaConfig.get('provider') === 'recaptcha_enterprise' + ) ? 'invalid_recaptcha' : 'invalid_captcha'; + } + return ( i18n.html(m, ['error', 'passwordless', key]) || i18n.html(m, ['error', 'passwordless', 'lock.fallback']) ); } +function swapCaptchaAfterError(id, error){ + const wasCaptchaInvalid = error && error.code === 'invalid_captcha'; + swapCaptcha(id, true, wasCaptchaInvalid); +} + export function requestPasswordlessEmail(id) { validateAndSubmit(id, ['email'], m => { - sendEmail(m, requestPasswordlessEmailSuccess, requestPasswordlessEmailError); + sendEmail(m, id, requestPasswordlessEmailSuccess, requestPasswordlessEmailError); }); } @@ -49,14 +62,15 @@ export function requestPasswordlessEmailSuccess(id) { export function requestPasswordlessEmailError(id, error) { const m = read(getEntity, 'lock', id); - const errorMessage = getErrorMessage(m, error); - return swap(updateEntity, 'lock', id, l.setSubmitting, false, errorMessage); + const errorMessage = getErrorMessage(m, id, error); + swap(updateEntity, 'lock', id, l.setSubmitting, false, errorMessage); + swapCaptchaAfterError(id, error); } export function resendEmail(id) { swap(updateEntity, 'lock', id, resend); const m = read(getEntity, 'lock', id); - sendEmail(m, resendEmailSuccess, resendEmailError); + sendEmail(m, id, resendEmailSuccess, resendEmailError); } function resendEmailSuccess(id) { @@ -75,7 +89,7 @@ function getPasswordlessConnectionName(m, defaultPasswordlessConnection) { : defaultPasswordlessConnection; } -function sendEmail(m, successFn, errorFn) { +function sendEmail(m, id, successFn, errorFn) { const params = { connection: getPasswordlessConnectionName(m, 'email'), email: c.getFieldValue(m, 'email'), @@ -85,6 +99,11 @@ function sendEmail(m, successFn, errorFn) { if (isSendLink(m) && !l.auth.params(m).isEmpty()) { params.authParams = l.auth.params(m).toJS(); } + const isCaptchaValid = setCaptchaParams(m, params, true, []); + + if (!isCaptchaValid) { + return showMissingCaptcha(m, id, true); + } webApi.startPasswordless(l.id(m), params, error => { if (error) { @@ -102,6 +121,10 @@ export function sendSMS(id) { phoneNumber: phoneNumberWithDiallingCode(m), send: send(m) }; + const isCaptchaValid = setCaptchaParams(m, params, true, []); + if (!isCaptchaValid) { + return showMissingCaptcha(m, id, true); + } webApi.startPasswordless(id, params, error => { if (error) { setTimeout(() => sendSMSError(id, error), 250); @@ -122,9 +145,10 @@ function sendSMSSuccess(id) { function sendSMSError(id, error) { const m = read(getEntity, 'lock', id); - const errorMessage = getErrorMessage(m, error); + const errorMessage = getErrorMessage(m, id, error); l.emitAuthorizationErrorEvent(m, error); - return swap(updateEntity, 'lock', id, l.setSubmitting, false, errorMessage); + swap(updateEntity, 'lock', id, l.setSubmitting, false, errorMessage); + swapCaptchaAfterError(id, error); } export function logIn(id) { @@ -146,7 +170,7 @@ export function logIn(id) { let errorMessage; if (error) { const m = read(getEntity, 'lock', id); - errorMessage = getErrorMessage(m, error); + errorMessage = getErrorMessage(m, id, error); if (error.logToConsole) { console.error(error.description); } @@ -160,6 +184,7 @@ export function logIn(id) { export function restart(id) { swap(updateEntity, 'lock', id, restartPasswordless); + swapCaptcha(id, true, false); } export function toggleTermsAcceptance(id) { diff --git a/src/core/index.js b/src/core/index.js index b6c684229..dec33ad19 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -421,15 +421,19 @@ export function setCaptcha(m, value, wasInvalid) { return set(m, 'captcha', Immutable.fromJS(value)); } +export function setPasswordlessCaptcha(m, value, wasInvalid) { + m = captchaField.reset(m, wasInvalid); + return set(m, 'passwordlessCaptcha', Immutable.fromJS(value)); +} + export function captcha(m) { - //some tests send an string as model. - // https://github.com/auth0/lock/blob/82f56187698528699478bd429858cf91e387763c/src/__tests__/engine/classic/sign_up_pane.test.jsx#L28 - if (typeof m !== 'object') { - return; - } return get(m, 'captcha'); } +export function passwordlessCaptcha(m) { + return get(m, 'passwordlessCaptcha'); +} + export function prefill(m) { return get(m, 'prefill', {}); } @@ -575,7 +579,11 @@ export function loginErrorMessage(m, error, type) { if (code === 'invalid_captcha') { const currentCaptcha = get(m, 'captcha'); - if (currentCaptcha && currentCaptcha.get('provider') === 'recaptcha_v2') { + if ( + currentCaptcha && ( + currentCaptcha.get('provider') === 'recaptcha_v2' || + currentCaptcha.get('provider') === 'recaptcha_enterprise' + )) { code = 'invalid_recaptcha'; } } diff --git a/src/core/remote_data.js b/src/core/remote_data.js index 77f0e79eb..6f2f20121 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 } from '../core/index'; +import { setCaptcha, setPasswordlessCaptcha } from '../core/index'; export function syncRemoteData(m) { if (l.useTenantInfo(m)) { @@ -60,5 +60,15 @@ export function syncRemoteData(m) { successFn: setCaptcha }); + m = sync(m, 'passwordlessCaptcha', { + syncFn: (m, cb) => { + webApi.getPasswordlessChallenge(m.get('id'), (err, r) => { + cb(null, r); + }); + }, + successFn: setPasswordlessCaptcha + }); + + return m; } diff --git a/src/core/web_api.js b/src/core/web_api.js index a2a4eec17..7a4fbb14d 100644 --- a/src/core/web_api.js +++ b/src/core/web_api.js @@ -60,6 +60,10 @@ class Auth0WebAPI { return this.clients[lockID].getChallenge(callback); } + getPasswordlessChallenge(lockID, callback) { + return this.clients[lockID].getPasswordlessChallenge(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 c9a6c5303..ddb412b09 100644 --- a/src/core/web_api/p2_api.js +++ b/src/core/web_api/p2_api.js @@ -195,6 +195,10 @@ class Auth0APIClient { return this.client.client.getChallenge(...params); } + getPasswordlessChallenge(...params) { + return this.client.client.passwordless.getChallenge(...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 f7f4e5a91..615141cbe 100644 --- a/src/engine/classic/sign_up_pane.jsx +++ b/src/engine/classic/sign_up_pane.jsx @@ -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)} /> + swapCaptcha(l.id(model), false, 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 fd1e3c458..9fab6b03f 100644 --- a/src/engine/passwordless/social_or_email_login_screen.jsx +++ b/src/engine/passwordless/social_or_email_login_screen.jsx @@ -2,6 +2,8 @@ import React from 'react'; 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 PaneSeparator from '../../core/pane_separator'; import { mustAcceptTerms, termsAccepted, showTerms } from '../../connection/passwordless/index'; import { toggleTermsAcceptance } from '../../connection/passwordless/actions'; @@ -45,12 +47,18 @@ const Component = ({ i18n, model }) => { const separator = social && email ? : null; + const captchaPane = l.passwordlessCaptcha(model) && l.passwordlessCaptcha(model).get('required') + ? ( + swapCaptcha(l.id(model), true, false)} /> + ) : null; + return (
{social} {separator} {header} {email} + {captchaPane}
); }; 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 ced2719a9..1f4d6ad21 100644 --- a/src/engine/passwordless/social_or_phone_number_login_screen.jsx +++ b/src/engine/passwordless/social_or_phone_number_login_screen.jsx @@ -3,6 +3,8 @@ import Screen from '../../core/screen'; 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 { renderSignedInConfirmation } from '../../core/signed_in_confirmation'; import PaneSeparator from '../../core/pane_separator'; import * as l from '../../core/index'; @@ -35,6 +37,11 @@ const Component = ({ i18n, model }) => { /> ) : null; + const captchaPane = l.passwordlessCaptcha(model) && l.passwordlessCaptcha(model).get('required') + ? ( + swapCaptcha(l.id(model), true, false)} /> + ) : null; + const separator = social && phoneNumber ? : null; return ( @@ -42,6 +49,7 @@ const Component = ({ i18n, model }) => { {social} {separator} {phoneNumber} + {captchaPane}
); }; diff --git a/src/field/captcha/captcha_pane.jsx b/src/field/captcha/captcha_pane.jsx index 33b1234f9..bdaa9098a 100644 --- a/src/field/captcha/captcha_pane.jsx +++ b/src/field/captcha/captcha_pane.jsx @@ -11,9 +11,9 @@ import { ReCAPTCHA, isRecaptcha } from './recaptcha'; export default class CaptchaPane extends React.Component { render() { - const { i18n, lock, onReload } = this.props; + const { i18n, lock, onReload, isPasswordless } = this.props; const lockId = l.id(lock); - const captcha = l.captcha(lock); + const captcha = isPasswordless ? l.passwordlessCaptcha(lock) : l.captcha(lock); const value = getFieldValue(lock, 'captcha'); const isValid = !isFieldVisiblyInvalid(lock, 'captcha'); const provider = captcha.get('provider'); diff --git a/src/i18n/af.js b/src/i18n/af.js index af86b3212..90b09dc59 100644 --- a/src/i18n/af.js +++ b/src/i18n/af.js @@ -35,7 +35,9 @@ export default { passwordless: { 'bad.email': 'Die e-pos is ongeldig', 'bad.phone_number': 'Die telefoonnommer is ongeldig', - 'lock.fallback': 'Jammer, iets het verkeerd gegaan' + 'lock.fallback': 'Jammer, iets het verkeerd gegaan', + 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." }, signUp: { invalid_password: 'Wagwoord is ongeldig.', diff --git a/src/i18n/ar.js b/src/i18n/ar.js index b9945f0f2..a3c0283ea 100644 --- a/src/i18n/ar.js +++ b/src/i18n/ar.js @@ -39,7 +39,9 @@ export default { passwordless: { 'bad.email': 'البريد الإلكتروني غير صالح.', 'bad.phone_number': 'رقم الهاتف غير صالح.', - 'lock.fallback': 'المعذرة، حصل خطأ ما.' + 'lock.fallback': 'المعذرة، حصل خطأ ما.', + invalid_captcha: 'حل سؤال التحدي للتحقق من أنك لست روبوت.', + invalid_recaptcha: 'حدد مربع الاختيار للتحقق من أنك لست روبوتًا.' }, signUp: { invalid_password: 'كلمة المرور غير صالحة.', diff --git a/src/i18n/az.js b/src/i18n/az.js index 906771624..927368aa4 100644 --- a/src/i18n/az.js +++ b/src/i18n/az.js @@ -40,7 +40,9 @@ export default { passwordless: { 'bad.email': 'E-poçt düzgün deyil', 'bad.phone_number': 'Telefon nömrəsi düzgün deyil', - 'lock.fallback': 'Üzr istəyirik, səhv oldu' + 'lock.fallback': 'Üzr istəyirik, səhv oldu', + 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.' }, signUp: { invalid_password: 'Şifrə yanlışdır.', diff --git a/src/i18n/bg.js b/src/i18n/bg.js index e64fbc64e..4bf899722 100644 --- a/src/i18n/bg.js +++ b/src/i18n/bg.js @@ -41,7 +41,9 @@ export default { passwordless: { 'bad.email': 'Имейлът е невалиден', 'bad.phone_number': 'Телефонният номер е невалиден', - 'lock.fallback': 'Съжаляваме, възникна грешка' + 'lock.fallback': 'Съжаляваме, възникна грешка', + invalid_captcha: 'Решете задачата, за да се уверим, че не сте робот.', + invalid_recaptcha: 'Поставете отметка, за да се уверим, че не сте робот.' }, signUp: { invalid_password: 'Паролата е невалидна.', diff --git a/src/i18n/ca.js b/src/i18n/ca.js index 3c09e0f6e..6a530cb57 100644 --- a/src/i18n/ca.js +++ b/src/i18n/ca.js @@ -42,7 +42,9 @@ export default { passwordless: { 'bad.email': "L'adreça de correu no és vàlida", 'bad.phone_number': 'El número de telèfon no és vàlid', - 'lock.fallback': 'Quelcom ha fet fallida' + 'lock.fallback': 'Quelcom ha fet fallida', + 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.' }, signUp: { invalid_password: 'La contrasenya no és vàlida.', diff --git a/src/i18n/cs.js b/src/i18n/cs.js index 476a54e94..2d65fe15d 100644 --- a/src/i18n/cs.js +++ b/src/i18n/cs.js @@ -40,7 +40,9 @@ export default { passwordless: { 'bad.email': 'E-mail je neplatný', 'bad.phone_number': 'Telefonní číslo je neplatné', - 'lock.fallback': 'Je nám líto, něco se pokazilo' + 'lock.fallback': 'Je nám líto, něco se pokazilo', + 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.' }, signUp: { invalid_password: 'Heslo je neplatné.', diff --git a/src/i18n/da.js b/src/i18n/da.js index 7462d559e..40ed20a12 100644 --- a/src/i18n/da.js +++ b/src/i18n/da.js @@ -40,7 +40,9 @@ export default { passwordless: { 'bad.email': 'Denne e-mail er ugyldig', 'bad.phone_number': 'Dette telefonnummer er ugyldigt', - 'lock.fallback': 'Vi beklager, men der skete en fejl' + 'lock.fallback': 'Vi beklager, men der skete en fejl', + 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.' }, signUp: { invalid_password: 'Adgangskoden er ugyldigt', diff --git a/src/i18n/de.js b/src/i18n/de.js index b3906038e..15179443e 100644 --- a/src/i18n/de.js +++ b/src/i18n/de.js @@ -42,7 +42,9 @@ export default { passwordless: { 'bad.email': 'Diese E-Mail-Adresse ist ungültig', 'bad.phone_number': 'Diese Telefonnummer ist ungültig', - 'lock.fallback': 'Es tut uns leid, etwas ist schiefgelaufen.' + 'lock.fallback': 'Es tut uns leid, etwas ist schiefgelaufen.', + 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.' }, signUp: { invalid_password: 'Passwort ist ungültig.', diff --git a/src/i18n/el.js b/src/i18n/el.js index 2c836dd11..b90081763 100644 --- a/src/i18n/el.js +++ b/src/i18n/el.js @@ -42,7 +42,9 @@ export default { passwordless: { 'bad.email': 'Το email δεν είναι έγκυρο', 'bad.phone_number': 'Ο αριθμός τηλεφώνου δεν είναι έγκυρος', - 'lock.fallback': 'Λυπούμαστε, κάτι πήγε στραβά' + 'lock.fallback': 'Λυπούμαστε, κάτι πήγε στραβά', + invalid_captcha: 'Λύστε την ερώτηση πρόκλησης για να επιβεβαιώσετε ότι δεν είστε ρομπότ.', + invalid_recaptcha: 'Επιλέξτε το πλαίσιο ελέγχου για να επαληθεύσετε ότι δεν είστε ρομπότ.' }, signUp: { invalid_password: 'Ο κωδικός δεν είναι έγκυρος.', diff --git a/src/i18n/en.js b/src/i18n/en.js index 189aa8ec1..01819b618 100644 --- a/src/i18n/en.js +++ b/src/i18n/en.js @@ -36,7 +36,9 @@ export default { passwordless: { 'bad.email': 'The email is invalid', 'bad.phone_number': 'The phone number is invalid', - 'lock.fallback': "We're sorry, something went wrong" + 'lock.fallback': "We're sorry, something went wrong", + 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.' }, signUp: { invalid_password: 'Password is invalid.', diff --git a/src/i18n/es.js b/src/i18n/es.js index 4cacda613..6b2a87619 100644 --- a/src/i18n/es.js +++ b/src/i18n/es.js @@ -37,7 +37,9 @@ export default { passwordless: { 'bad.email': 'Correo inválido', 'bad.phone_number': 'Teléfono inválido', - 'lock.fallback': 'Ocurrió un error durante el envío' + 'lock.fallback': 'Ocurrió un error durante el envío', + 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.' }, signUp: { invalid_password: 'La contraseña es inválida.', diff --git a/src/i18n/et.js b/src/i18n/et.js index ecc34cc43..c2a3ce3fc 100644 --- a/src/i18n/et.js +++ b/src/i18n/et.js @@ -39,7 +39,9 @@ export default { passwordless: { 'bad.email': 'Vigane e-mail', 'bad.phone_number': 'Vigane telefoninumber', - 'lock.fallback': 'Vabandame, midagi läks valesti.' + 'lock.fallback': 'Vabandame, midagi läks valesti.', + invalid_captcha: 'Lahendage väljakutseküsimus ja veenduge, et te pole robot.', + invalid_recaptcha: 'Valige märkeruut, et kontrollida, kas te pole robot.' }, signUp: { invalid_password: 'Parool on vigane.', diff --git a/src/i18n/fa.js b/src/i18n/fa.js index 83bed0597..bf9fac7b9 100644 --- a/src/i18n/fa.js +++ b/src/i18n/fa.js @@ -39,7 +39,9 @@ export default { passwordless: { 'bad.email': 'ایمیل نا معتبر است.', 'bad.phone_number': 'شماره تلفن نامعتبر است.', - 'lock.fallback': 'متاسفیم ، خطایی رخ داده است.' + 'lock.fallback': 'متاسفیم ، خطایی رخ داده است.', + invalid_captcha: 'حل مسئله چالش برای تأیید اینکه ربات نیستید.', + invalid_recaptcha: 'کادر تأیید را انتخاب کنید تا تأیید کنید که روبات نیستید.' }, signUp: { invalid_password: 'رمز نامعتبر است.', diff --git a/src/i18n/fi.js b/src/i18n/fi.js index d1147f38e..1f0b7b2d9 100644 --- a/src/i18n/fi.js +++ b/src/i18n/fi.js @@ -42,7 +42,9 @@ export default { passwordless: { 'bad.email': 'Sähköposti ei kelpaa', 'bad.phone_number': 'Puhelinnumero ei kelpaa', - 'lock.fallback': 'Olemme pahoillamme, jotain meni vikaan' + 'lock.fallback': 'Olemme pahoillamme, jotain meni vikaan', + invalid_captcha: 'Ratkaise haastekysymys varmistaaksesi, että et ole robotti.', + invalid_recaptcha: 'Valitse valintaruutu varmistaaksesi, että et ole robotti.' }, signUp: { invalid_password: 'Salasana ei kelpaa.', diff --git a/src/i18n/fr.js b/src/i18n/fr.js index fb61364f1..8f833aa3b 100644 --- a/src/i18n/fr.js +++ b/src/i18n/fr.js @@ -44,7 +44,9 @@ export default { passwordless: { 'bad.email': 'L’adresse de messagerie n’est pas valide', 'bad.phone_number': 'Le numéro de téléphone n’est pas valide', - 'lock.fallback': 'Nous sommes désolés, un problème est survenu' + 'lock.fallback': 'Nous sommes désolés, un problème est survenu', + 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." }, signUp: { invalid_password: 'Le mot de passe n’est pas valide.', diff --git a/src/i18n/he.js b/src/i18n/he.js index 1c950739f..5011aa428 100644 --- a/src/i18n/he.js +++ b/src/i18n/he.js @@ -38,7 +38,9 @@ export default { passwordless: { 'bad.email': 'כתובת המייל אינה תקינה', 'bad.phone_number': 'מספר הטלפון לא תקין', - 'lock.fallback': 'אנו מתנצלים, משהו השתבש' + 'lock.fallback': 'אנו מתנצלים, משהו השתבש', + invalid_captcha: 'לפתור את שאלת האתגר כדי לוודא שאתה לא רובוט.', + invalid_recaptcha: 'בחר בתיבת הסימון כדי לוודא שאתה לא רובוט.' }, signUp: { invalid_password: 'סיסמא לא תקינה.', diff --git a/src/i18n/hr.js b/src/i18n/hr.js index 2a8be33d8..fb1ce2f72 100755 --- a/src/i18n/hr.js +++ b/src/i18n/hr.js @@ -42,7 +42,9 @@ export default { passwordless: { 'bad.email': 'Neispravna adresa elektroničke pošte', 'bad.phone_number': 'Neispravan broj telefona', - 'lock.fallback': 'Ispričavamo se, ali nešto je pošlo po zlu.' + 'lock.fallback': 'Ispričavamo se, ali nešto je pošlo po zlu.', + invalid_captcha: 'Riješite izazovno pitanje kako biste provjerili da niste robot.', + invalid_recaptcha: 'Označite potvrdni okvir da biste potvrdili da niste robot.' }, signUp: { invalid_password: 'Lozinka je neispravna.', diff --git a/src/i18n/hu.js b/src/i18n/hu.js index 1b1f32de3..70c121ced 100644 --- a/src/i18n/hu.js +++ b/src/i18n/hu.js @@ -41,7 +41,9 @@ export default { passwordless: { 'bad.email': 'Érvénytelen e-mail cím.', 'bad.phone_number': 'Érvénytelen telefonszám.', - 'lock.fallback': 'Sajnáljuk, valami hiba történt.' + 'lock.fallback': 'Sajnáljuk, valami hiba történt.', + 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.' }, signUp: { invalid_password: 'Érvénytelen jelszó.', diff --git a/src/i18n/id.js b/src/i18n/id.js index 82aad6a33..17e8e6215 100644 --- a/src/i18n/id.js +++ b/src/i18n/id.js @@ -41,7 +41,9 @@ export default { passwordless: { 'bad.email': 'Email ini tidak valid.', 'bad.phone_number': 'Nomor telepon tidak valid.', - 'lock.fallback': 'Maaf, terjadi kesalahan' + 'lock.fallback': 'Maaf, terjadi kesalahan', + invalid_captcha: 'Selesaikan pertanyaan tantangan untuk memverifikasi bahwa Anda bukan robot.', + invalid_recaptcha: 'Pilih kotak centang untuk memverifikasi bahwa Anda bukan robot.' }, signUp: { invalid_password: 'Kata sandi tidak valid.', diff --git a/src/i18n/it.js b/src/i18n/it.js index ef87df622..b7ddf711c 100644 --- a/src/i18n/it.js +++ b/src/i18n/it.js @@ -40,7 +40,9 @@ export default { passwordless: { 'bad.email': "L'email non è valida", 'bad.phone_number': 'Il numero di telefono non è valido', - 'lock.fallback': 'Ci dispiace, qualcosa è andato storto' + 'lock.fallback': 'Ci dispiace, qualcosa è andato storto', + 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.' }, signUp: { invalid_password: 'La password non è valida.', diff --git a/src/i18n/ja.js b/src/i18n/ja.js index d9c0638e0..c3a75ae89 100644 --- a/src/i18n/ja.js +++ b/src/i18n/ja.js @@ -40,7 +40,9 @@ export default { passwordless: { 'bad.email': 'メールアドレスが不正です', 'bad.phone_number': '電話番号が不正です', - 'lock.fallback': '申し訳ございません。エラーが発生しました。' + 'lock.fallback': '申し訳ございません。エラーが発生しました。', + invalid_captcha: 'チャレンジ質問を解いて、ロボットではないことを確認してください。', + invalid_recaptcha: 'チェックボックスを選択して、ロボットでないことを確認します。' }, signUp: { invalid_password: 'パスワードが不正です。', diff --git a/src/i18n/ko.js b/src/i18n/ko.js index b60bacfcf..cd9559d26 100644 --- a/src/i18n/ko.js +++ b/src/i18n/ko.js @@ -39,7 +39,9 @@ export default { passwordless: { 'bad.email': '이메일 주소가 유효하지 않습니다', 'bad.phone_number': '전화번호가 유효하지 않습니다', - 'lock.fallback': '죄송합니다. 오류가 발생하였습니다' + 'lock.fallback': '죄송합니다. 오류가 발생하였습니다', + invalid_captcha: '로봇이 아닌 사람인지 확인하기 위해 챌린지 질문을 해결하십시오.', + invalid_recaptcha: '로봇이 아닌지 확인하려면 확인란을 선택하십시오.' }, signUp: { invalid_password: '비밀번호가 유효하지 않습니다.', diff --git a/src/i18n/lt.js b/src/i18n/lt.js index c202fa229..24e6ddfe6 100644 --- a/src/i18n/lt.js +++ b/src/i18n/lt.js @@ -39,7 +39,9 @@ export default { passwordless: { 'bad.email': 'Neteisingas el.pašto adresas', 'bad.phone_number': 'Neteisingas telefono numeris', - 'lock.fallback': 'Atsiprašome, įvyko netikėta klaida.' + 'lock.fallback': 'Atsiprašome, įvyko netikėta klaida.', + 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.' }, signUp: { invalid_password: 'Slaptažodis neteisingas.', diff --git a/src/i18n/lv.js b/src/i18n/lv.js index 63e505ae0..e7c432012 100644 --- a/src/i18n/lv.js +++ b/src/i18n/lv.js @@ -40,7 +40,9 @@ export default { passwordless: { 'bad.email': 'Nederīga e-pasta adrese', 'bad.phone_number': 'Nederīgs tālruņa numurs', - 'lock.fallback': 'Diemžēl radās problēma' + 'lock.fallback': 'Diemžēl radās problēma', + 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.' }, signUp: { invalid_password: 'Nederīga parole.', diff --git a/src/i18n/ms.js b/src/i18n/ms.js index 704dcc156..1f8a20197 100644 --- a/src/i18n/ms.js +++ b/src/i18n/ms.js @@ -41,7 +41,9 @@ export default { passwordless: { 'bad.email': 'E-mel ini tidak sah', 'bad.phone_number': 'Nombor telefon tidak sah', - 'lock.fallback': 'Harap maaf, sesuatu berlaku' + 'lock.fallback': 'Harap maaf, sesuatu berlaku', + invalid_captcha: 'Selesaikan soalan cabaran untuk mengesahkan bahawa anda bukan robot.', + invalid_recaptcha: 'Pilih kotak pilihan untuk mengesahkan bahawa anda bukan robot.' }, signUp: { invalid_password: 'Kata laluan tidak sah.', diff --git a/src/i18n/nb.js b/src/i18n/nb.js index 5d7f9c19a..130237f64 100644 --- a/src/i18n/nb.js +++ b/src/i18n/nb.js @@ -39,7 +39,9 @@ export default { passwordless: { 'bad.email': 'E-postadressen er ugyldig', 'bad.phone_number': 'Telefonnummeret er ugyldig', - 'lock.fallback': 'Beklager, noe gikk galt' + 'lock.fallback': 'Beklager, noe gikk galt', + 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.' }, signUp: { invalid_password: 'Passordet er ugyldig.', diff --git a/src/i18n/nl.js b/src/i18n/nl.js index 9672a23f3..9fc7fcf7c 100644 --- a/src/i18n/nl.js +++ b/src/i18n/nl.js @@ -42,7 +42,9 @@ export default { passwordless: { 'bad.email': 'Het e-mailadres is ongeldig', 'bad.phone_number': 'Het telefoonnummer is ongeldig', - 'lock.fallback': 'Onze excuses, er is iets fout gegaan.' + 'lock.fallback': 'Onze excuses, er is iets fout gegaan.', + 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.' }, signUp: { invalid_password: 'Het wachtwoord is ongeldig.', diff --git a/src/i18n/nn.js b/src/i18n/nn.js index 0d442681c..e3fbfd504 100644 --- a/src/i18n/nn.js +++ b/src/i18n/nn.js @@ -41,7 +41,9 @@ export default { passwordless: { 'bad.email': 'Ugyldig e-postadresse', 'bad.phone_number': 'Ugyldig telefonnummer', - 'lock.fallback': 'Beklagar, men noko gjekk galt' + 'lock.fallback': 'Beklagar, men noko gjekk galt', + 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.' }, signUp: { invalid_password: 'Ugyldig passord.', diff --git a/src/i18n/no.js b/src/i18n/no.js index ee4879fa9..706dd5dde 100644 --- a/src/i18n/no.js +++ b/src/i18n/no.js @@ -41,7 +41,9 @@ export default { passwordless: { 'bad.email': 'Ugyldig e-postadresse', 'bad.phone_number': 'Ugyldig telefonnummer', - 'lock.fallback': 'Beklager, men noe gikk galt' + 'lock.fallback': 'Beklager, men noe gikk galt', + 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.' }, signUp: { invalid_password: 'Ugyldig passord.', diff --git a/src/i18n/pl.js b/src/i18n/pl.js index b04bd9a52..3ff15d060 100644 --- a/src/i18n/pl.js +++ b/src/i18n/pl.js @@ -41,7 +41,9 @@ export default { passwordless: { 'bad.email': 'Adres email nie jest poprawny', 'bad.phone_number': 'Numer telefonu nie jest poprawny', - 'lock.fallback': 'Przykro nam, coś poszło nie tak' + 'lock.fallback': 'Przykro nam, coś poszło nie tak', + invalid_captcha: 'Rozwiąż pytanie kontrolne, aby sprawdzić, czy nie jesteś robotem.', + invalid_recaptcha: 'Zaznacz pole wyboru, aby potwierdzić, że nie jesteś robotem.' }, signUp: { invalid_password: 'Hasło nie jest poprawne.', diff --git a/src/i18n/pt-br.js b/src/i18n/pt-br.js index 46e504a15..06769d8c8 100644 --- a/src/i18n/pt-br.js +++ b/src/i18n/pt-br.js @@ -37,7 +37,9 @@ export default { passwordless: { 'bad.email': 'O email é inválido', 'bad.phone_number': 'O número de telefone é inválido', - 'lock.fallback': 'Sentimos muito, algo deu errado' + 'lock.fallback': 'Sentimos muito, algo deu errado', + 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ô.' }, signUp: { invalid_password: 'A senha é inválida.', diff --git a/src/i18n/pt.js b/src/i18n/pt.js index eda26f583..17a5a224b 100644 --- a/src/i18n/pt.js +++ b/src/i18n/pt.js @@ -42,7 +42,9 @@ export default { passwordless: { 'bad.email': 'O endereço de correio eletrónico é inválido', 'bad.phone_number': 'O número de telefone é inválido', - 'lock.fallback': 'Lamentamos, correu um erro.' + 'lock.fallback': 'Lamentamos, correu um erro.', + 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ô.' }, signUp: { invalid_password: 'Palavra-passe inválida.', diff --git a/src/i18n/ro.js b/src/i18n/ro.js index edc1118a3..faa0484af 100644 --- a/src/i18n/ro.js +++ b/src/i18n/ro.js @@ -41,7 +41,9 @@ export default { passwordless: { 'bad.email': 'Adresa de email este invalidă', 'bad.phone_number': 'Numărul de telefon este invalid', - 'lock.fallback': 'Ne pare rău, ceva nu a funcționat' + 'lock.fallback': 'Ne pare rău, ceva nu a funcționat', + 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.' }, signUp: { invalid_password: 'Parolă invalidă.', diff --git a/src/i18n/ru.js b/src/i18n/ru.js index 8d96e0fa1..d8a521cf3 100644 --- a/src/i18n/ru.js +++ b/src/i18n/ru.js @@ -44,7 +44,9 @@ export default { passwordless: { 'bad.email': 'Недействительный адрес электронной почты', 'bad.phone_number': 'Недействительный номер телефона', - 'lock.fallback': 'Произошла непредвиденная ошибка. Приносим свои извинения' + 'lock.fallback': 'Произошла непредвиденная ошибка. Приносим свои извинения', + invalid_captcha: 'Решите сложный вопрос, чтобы убедиться, что вы не робот.', + invalid_recaptcha: 'Установите флажок, чтобы убедиться, что вы не робот.' }, signUp: { invalid_password: 'Неверный пароль.', diff --git a/src/i18n/sk.js b/src/i18n/sk.js index fa2bcc8b0..0f2ae2fd6 100644 --- a/src/i18n/sk.js +++ b/src/i18n/sk.js @@ -39,7 +39,9 @@ export default { passwordless: { 'bad.email': 'Neplatný e-mail', 'bad.phone_number': 'Neplatné telefónne číslo', - 'lock.fallback': 'Ospravedlňujeme sa, niečo nie je v poriadku' + 'lock.fallback': 'Ospravedlňujeme sa, niečo nie je v poriadku', + 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.' }, signUp: { invalid_password: 'Neplatné heslo.', diff --git a/src/i18n/sl.js b/src/i18n/sl.js index 8fea2fb27..0a0204177 100644 --- a/src/i18n/sl.js +++ b/src/i18n/sl.js @@ -39,7 +39,9 @@ export default { passwordless: { 'bad.email': 'Napačen e-poštni naslov', 'bad.phone_number': 'Napačna telefonska številka', - 'lock.fallback': 'Žal je prišlo do napake' + 'lock.fallback': 'Žal je prišlo do napake', + invalid_captcha: 'Rešite izzivno vprašanje in preverite, ali niste robot.', + invalid_recaptcha: 'Izberite potrditveno polje, da preverite, da niste robot.' }, signUp: { invalid_password: 'Napačno geslo.', diff --git a/src/i18n/sr.js b/src/i18n/sr.js index 2db1bda1d..a23d08c89 100644 --- a/src/i18n/sr.js +++ b/src/i18n/sr.js @@ -39,7 +39,9 @@ export default { passwordless: { 'bad.email': 'Adresa e-pošte je nevažeća', 'bad.phone_number': 'Broj telefona je nevažeći', - 'lock.fallback': 'Žao nam je, došlo je do greške' + 'lock.fallback': 'Žao nam je, došlo je do greške', + invalid_captcha: 'Решите изазовно питање да бисте потврдили да нисте робот.', + invalid_recaptcha: 'Потврдите избор у пољу за потврду да нисте робот.' }, signUp: { invalid_password: 'Lozinka je nevažeća.', diff --git a/src/i18n/sv.js b/src/i18n/sv.js index 14ec10c68..b1a729648 100644 --- a/src/i18n/sv.js +++ b/src/i18n/sv.js @@ -39,7 +39,9 @@ export default { passwordless: { 'bad.email': 'Din e-postadress är ogiltig.', 'bad.phone_number': 'Ditt telefonnummer är ogiltigt.', - 'lock.fallback': 'Något gick fel.' + 'lock.fallback': 'Något gick fel.', + 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.' }, signUp: { invalid_password: 'Lösenordet är ogiltigt.', diff --git a/src/i18n/tr.js b/src/i18n/tr.js index 4c61b8948..5c07ce876 100644 --- a/src/i18n/tr.js +++ b/src/i18n/tr.js @@ -40,7 +40,9 @@ export default { passwordless: { 'bad.email': 'E-posta geçerli değil', 'bad.phone_number': 'Telefon numarası geçerli değil', - 'lock.fallback': 'Özür dileriz, bir hata oluştu' + 'lock.fallback': 'Özür dileriz, bir hata oluştu', + 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.' }, signUp: { invalid_password: 'Şifre geçersiz.', diff --git a/src/i18n/ua.js b/src/i18n/ua.js index 3f1dbc82a..82761f28a 100644 --- a/src/i18n/ua.js +++ b/src/i18n/ua.js @@ -42,7 +42,9 @@ export default { passwordless: { 'bad.email': 'Недійсна адреса електронної пошти', 'bad.phone_number': 'Недійсний номер телефону', - 'lock.fallback': 'Йой! Виникла непередбачувана помилка при спробі авторизації. Перепрошуємо.' + 'lock.fallback': 'Йой! Виникла непередбачувана помилка при спробі авторизації. Перепрошуємо.', + invalid_captcha: 'Вирішіть складне питання, щоб переконатися, що ви не робот.', + invalid_recaptcha: 'Установіть прапорець, щоб переконатися, що ви не робот.' }, signUp: { invalid_password: 'Невірний пароль.', diff --git a/src/i18n/uk.js b/src/i18n/uk.js index d000f71b3..15e819e07 100644 --- a/src/i18n/uk.js +++ b/src/i18n/uk.js @@ -41,7 +41,9 @@ export default { passwordless: { 'bad.email': 'Неправильна адреса електронної пошти', 'bad.phone_number': 'Неправильний номер телефону', - 'lock.fallback': 'На жаль, сталася помилка' + 'lock.fallback': 'На жаль, сталася помилка', + invalid_captcha: 'Вирішіть складне питання, щоб переконатися, що ви не робот.', + invalid_recaptcha: 'Установіть прапорець, щоб переконатися, що ви не робот.' }, signUp: { invalid_password: 'Неправильний пароль.', diff --git a/src/i18n/vi.js b/src/i18n/vi.js index dea15eb2e..9dfb57b5c 100644 --- a/src/i18n/vi.js +++ b/src/i18n/vi.js @@ -39,7 +39,9 @@ export default { passwordless: { 'bad.email': 'Email không hợp lệ.', 'bad.phone_number': 'Số điện thoại không hợp lệ.', - 'lock.fallback': 'Đã có lỗi xãy ra, chúng tôi rất lấy làm tiếc.' + 'lock.fallback': 'Đã có lỗi xãy ra, chúng tôi rất lấy làm tiếc.', + 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.' }, signUp: { invalid_password: 'Mật khẩu không hợp lệ.', diff --git a/src/i18n/zh-tw.js b/src/i18n/zh-tw.js index 884131838..81a6a0d61 100644 --- a/src/i18n/zh-tw.js +++ b/src/i18n/zh-tw.js @@ -35,7 +35,9 @@ export default { passwordless: { 'bad.email': '電子信箱錯誤', 'bad.phone_number': '手機號碼錯誤。', - 'lock.fallback': '對不起,發生錯誤。' + 'lock.fallback': '對不起,發生錯誤。', + invalid_captcha: '解決挑戰問題以驗證您不是機器人。', + invalid_recaptcha: '選中復選框以確認您不是機器人。' }, signUp: { invalid_password: '密碼錯誤', diff --git a/src/i18n/zh.js b/src/i18n/zh.js index d962a229b..8c60e7f9b 100644 --- a/src/i18n/zh.js +++ b/src/i18n/zh.js @@ -35,7 +35,9 @@ export default { passwordless: { 'bad.email': '邮箱错误', 'bad.phone_number': '手机号码格式不正确。', - 'lock.fallback': '对不起,出现错误。' + 'lock.fallback': '对不起,出现错误。', + invalid_captcha: '解决挑战问题以验证您不是机器人。', + invalid_recaptcha: '选中复选框以确认您不是机器人。' }, signUp: { invalid_password: '密码错误', diff --git a/yarn.lock b/yarn.lock index 3804e2cc3..2a566a9ec 100644 --- a/yarn.lock +++ b/yarn.lock @@ -850,7 +850,7 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -auth0-js@^9.19.2: +auth0-js@^9.20.0: version "9.20.0" resolved "https://registry.yarnpkg.com/auth0-js/-/auth0-js-9.20.0.tgz#80d140a6741f677f5295f2b38e750e23961726fe" integrity sha512-g158V/fP+QHZqvLjqc5nsdLmJkLz8ceMQjkkrfybPXK7a6uPsJXqTEft9aQp8Y5w6qyyLi9EGD5df+iGGiTaVQ==