@@ -1,6 +1,6 @@
{
"name": "auth0-lock",
"version": "11.20.2",
"version": "11.20.3",
"description": "Auth0 Lock",
"author": "Auth0 <support@auth0.com> (http://auth0.com)",
"license": "MIT",
@@ -94,7 +94,7 @@
"zuul-ngrok": "4.0.0"
},
"dependencies": {
"auth0-js": "^9.12.1",
"auth0-js": "^9.12.2",
"auth0-password-policies": "^1.0.2",
"blueimp-md5": "2.3.1",
"immutable": "^3.7.3",
@@ -0,0 +1,28 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`quick-auth.actions calls logIn with the correct parameters 1`] = `
Array [
"id",
Array [],
Object {
"connection": "name",
"connection_scope": undefined,
"isSubmitting": false,
"login_hint": "hint",
"prompt": "prompt",
},
]
`;

exports[`quick-auth.actions sets display to "popup" when using facebook and there's no redirect 1`] = `
Array [
"id",
Array [],
Object {
"connection": "name",
"connection_scope": undefined,
"display": "popup",
"isSubmitting": false,
},
]
`;
@@ -0,0 +1,116 @@
import { logIn } from '../../quick-auth/actions';

jest.mock('../../core/actions', () => ({
logIn: jest.fn()
}));

jest.mock('store/index', () => ({
read: jest.fn(() => 'model'),
getEntity: 'getEntity',
swap: jest.fn(),
updateEntity: 'updateEntity'
}));

jest.mock('../../core/index', () => ({
id: () => 'id',
auth: {
connectionScopes: jest.fn(() => ({
get: jest.fn()
})),
redirect: jest.fn(() => true)
},
setSuppressSubmitOverlay: jest.fn()
}));

describe('quick-auth.actions', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('calls logIn with the correct parameters', () => {
const connection = {
get: jest.fn(key => {
switch (key) {
case 'name':
return 'name';
case 'strategy':
return 'google';
}
})
};

logIn('id', connection, 'hint', 'prompt');

const coreActions = require('../../core/actions');

expect(coreActions.logIn.mock.calls.length).toBe(1);
expect(coreActions.logIn.mock.calls[0]).toMatchSnapshot();
});

it('sets display to "popup" when using facebook and there\'s no redirect', () => {
const connection = {
get: jest.fn(key => {
switch (key) {
case 'name':
return 'name';
case 'strategy':
return 'facebook';
}
})
};

const core = require('../../core/index');
core.auth.redirect = jest.fn(() => false);

logIn('id', connection);

const coreActions = require('../../core/actions');

expect(coreActions.logIn.mock.calls.length).toBe(1);
expect(coreActions.logIn.mock.calls[0]).toMatchSnapshot();
});

it('calls setSuppressSubmitOverlay with true when using Apple connection', () => {
const connection = {
get: jest.fn(key => {
switch (key) {
case 'name':
return 'name';
case 'strategy':
return 'apple';
}
})
};

logIn('id', connection);

const { swap } = require('store/index');
const l = require('../../core/index');

expect(swap.mock.calls.length).toBe(1);
expect(swap.mock.calls[0][3]).toBe(l.setSupressSubmitOverlay);
expect(swap.mock.calls[0][4]).toBe(true);
});

it('calls setSuppressSubmitOverlay with false when not using Apple connection', () => {
const connection = {
get: jest.fn(key => {
switch (key) {
case 'name':
return 'name';
case 'strategy':
return 'facebook';
}
})
};

logIn('id', connection);

const { swap } = require('store/index');
const l = require('../../core/index');

expect(swap.mock.calls.length).toBe(1);
expect(swap.mock.calls[0][3]).toBe(l.setSupressSubmitOverlay);
expect(swap.mock.calls[0][4]).toBe(false);
});
});
@@ -1,5 +1,51 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Container when suppressSubmitOverlay is true it does not display the overlay when submitting 1`] = `
<div
className="auth0-lock auth0-lock-opened-in-frame auth0-lock-no-submit"
lang="en"
>
<div
className="auth0-lock-center"
>
<form
className="auth0-lock-widget"
method="post"
onSubmit={[Function]}
>
<div
className="auth0-lock-widget-container"
>
<div
data-__type="chrome"
data-autofocus={false}
data-auxiliaryPane={undefined}
data-avatar={undefined}
data-backHandler={undefined}
data-classNames=""
data-contentComponent={null}
data-contentProps={Object {}}
data-disableSubmitButton={false}
data-error={undefined}
data-info={undefined}
data-isSubmitting={true}
data-logo=""
data-primaryColor=""
data-screenName="Test"
data-scrollGlobalMessagesIntoView={true}
data-showSubmitButton={false}
data-submitButtonLabel={undefined}
data-success={undefined}
data-tabs={undefined}
data-terms={undefined}
data-title={undefined}
/>
</div>
</form>
</div>
</div>
`;

exports[`Container with a custom \`connectionResolver\` calls \`connectionResolver\` onSubmit 1`] = `
Array [
"peter_picked@pickledpepper.com",
@@ -1,11 +1,6 @@
import React from 'react';
import { mount } from 'enzyme';
import immutable from 'immutable';
import { expectComponent, mockComponent } from '../../testUtils';
import sync from '../../../sync';
import { connections } from '../../../core/index';
import { email } from '../../../field/index';
import { img } from '../../../utils/preload_utils';

jest.mock('store/index', () => ({
swap: jest.fn(),
@@ -18,29 +13,36 @@ const mockEvent = {
preventDefault: () => {}
};

const getContainer = () => {
const getContainer = opts => {
const Container = require('ui/box/container').default;
return new Container({
contentProps: {
i18n: {},
model: immutable.fromJS({
client: {
connections: {
database: [{ name: 'dbA' }, { name: 'dbB' }]

const props = Object.assign(
{},
{
contentProps: {
i18n: {},
model: immutable.fromJS({
client: {
connections: {
database: [{ name: 'dbA' }, { name: 'dbB' }]
},
id: 'alksdkhasd__test-lock__alsdkhalkshd'
},
id: 'alksdkhasd__test-lock__alsdkhalkshd'
},
field: {
email: {
invalidHint: null,
showInvalid: false,
valid: true,
value: 'peter_picked@pickledpepper.com'
field: {
email: {
invalidHint: null,
showInvalid: false,
valid: true,
value: 'peter_picked@pickledpepper.com'
}
}
}
})
}
});
})
}
},
opts
);

return new Container(props);
};

describe('Container', () => {
@@ -91,4 +93,30 @@ describe('Container', () => {
expect(mock.calls[0]).toMatchSnapshot();
});
});

describe('when suppressSubmitOverlay is true', () => {
it('it does not display the overlay when submitting', () => {
const Container = require('ui/box/container').default;

const props = {
autoFocus: false,
badgeLink: 'http://badge.link',
contentComponent: null,
contentProps: {},
disableSubmitButton: false,
isMobile: false,
isModal: false,
isSubmitting: true,
logo: '',
primaryColor: '',
screenName: 'Test',
showBadge: false,
classNames: '',
suppressSubmitOverlay: true
};

// Emitted snapshot should not add 'auth0-lock-mode-loading' class to the container div
expectComponent(<Container {...props} />).toMatchSnapshot();
});
});
});
@@ -132,7 +132,8 @@ export default class Base extends EventEmitter {
terms: screen.renderTerms(m, i18nProp.html('signUpTerms')),
title: getScreenTitle(m),
classNames: screen.name === 'loading' ? 'fade' : 'horizontal-fade',
scrollGlobalMessagesIntoView: l.ui.scrollGlobalMessagesIntoView(m)
scrollGlobalMessagesIntoView: l.ui.scrollGlobalMessagesIntoView(m),
suppressSubmitOverlay: l.suppressSubmitOverlay(m) || false
};
render(l.ui.containerID(m), props);

@@ -171,7 +171,6 @@ export function validateAndSubmit(id, fields = [], f) {
? l.setSubmitting(m, true)
: fields.reduce((r, x) => showInvalidField(r, x), m);
});

const m = read(getEntity, 'lock', id);
if (l.submitting(m)) {
f(m);
@@ -152,6 +152,14 @@ export function stopRendering(m) {
return tremove(m, 'render');
}

export function setSupressSubmitOverlay(m, b) {
return set(m, 'suppressSubmitOverlay', b);
}

export function suppressSubmitOverlay(m) {
return get(m, 'suppressSubmitOverlay');
}

function extractUIOptions(id, options) {
const closable = options.container
? false
@@ -8,12 +8,12 @@ export default {
'O domínio do seu endereço eletrónico é parte de um fornecedor de identidade empresarial. Para repor a sua palavra-passe, consulte o seu administrador de segurança.'
},
login: {
blocked_user: 'O usuário está bloqueado.',
blocked_user: 'O utilizador está bloqueado.',
invalid_user_password: 'Credenciais erradas.',
'lock.fallback': 'Lamentamos, ocorreu um problema ao tentar iniciar sessão.',
'lock.invalid_code': 'Código errado.',
'lock.invalid_email_password': 'Endereço de correio eletrónico ou palavra-passe errados.',
'lock.invalid_username_password': 'Nome de usuário ou palavra-passe errados.',
'lock.invalid_username_password': 'Nome de utilizador ou palavra-passe errados.',
'lock.network':
'Não foi possível comunicar com o servidor Verifique a sua ligação e tente novamente.',
'lock.popup_closed': 'Janela instantânea fechada. Tente novamente.',
@@ -43,10 +43,10 @@ export default {
invalid_password: 'Palavra-passe inválida.',
'lock.fallback': 'Lamentamos, ocorreu um problema ao tentar registar-se.',
password_dictionary_error: 'Palavra-passe demasiado simples.',
password_no_user_info_error: 'Palavra-passe baseada nos dados do usuário.',
password_no_user_info_error: 'Palavra-passe baseada nos dados do utilizador.',
password_strength_error: 'Palavra-passe demasiado fraca.',
user_exists: 'O usuário já existe.',
username_exists: 'O nome de usuário já existe.'
user_exists: 'O utilizador já existe.',
username_exists: 'O nome de utilizador já existe.'
}
},
success: {
@@ -114,8 +114,8 @@ export default {
submitLabel: 'Enviar',
unrecoverableError: 'Ocorreu um erro.<br />Contacte a assistência técnica.',
usernameFormatErrorHint: '_", ".", "+", "-"',
usernameInputPlaceholder: 'o seu nome de usuário',
usernameOrEmailInputPlaceholder: 'nome de usuário/endereço de correio eletrónico',
usernameInputPlaceholder: 'o seu nome de utilizador',
usernameOrEmailInputPlaceholder: 'nome de utilizador/endereço de correio eletrónico',
title: 'Auth0',
welcome: 'Bem-vindo(a) %s!',
windowsAuthInstructions: 'Ligou-se a partir da sua rede empresarial&hellip;',
@@ -24,6 +24,14 @@ export function logIn(id, connection, loginHint, prompt) {
if (prompt) {
params.prompt = prompt;
}

if (connection.get('strategy') === 'apple') {
swap(updateEntity, 'lock', l.id(m), l.setSupressSubmitOverlay, true);
} else {
swap(updateEntity, 'lock', l.id(m), l.setSupressSubmitOverlay, false);
}

params.isSubmitting = false;
coreLogIn(id, [], params);
}

@@ -157,7 +157,8 @@ export default class Container extends React.Component {
terms,
title,
classNames,
scrollGlobalMessagesIntoView
scrollGlobalMessagesIntoView,
suppressSubmitOverlay
} = this.props;

const badge = showBadge ? <BottomBadge link={badgeLink} /> : null;
@@ -178,7 +179,7 @@ export default class Container extends React.Component {
className += ' auth0-lock-mobile';
}

if (isSubmitting) {
if (isSubmitting && !suppressSubmitOverlay) {
className += ' auth0-lock-mode-loading';
}

@@ -270,7 +271,8 @@ Container.propTypes = {
terms: PropTypes.element,
title: PropTypes.string,
classNames: PropTypes.string.isRequired,
scrollGlobalMessagesIntoView: PropTypes.bool
scrollGlobalMessagesIntoView: PropTypes.bool,
suppressSubmitOverlay: PropTypes.bool
// escHandler
// submitHandler,
};