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==