auth0-lock 11.34.1 → 11.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.circleci/config.yml +1 -1
- package/.eslintrc.json +5 -5
- package/.github/workflows/codeql.yml +41 -0
- package/CHANGELOG.md +38 -0
- package/EXAMPLES.md +626 -0
- package/README.md +78 -653
- package/lib/__tests__/connection/passwordless/passwordless.js +4 -2
- package/lib/__tests__/engine/passwordless/social_or_email_login_screen.js +126 -0
- package/lib/__tests__/engine/passwordless/social_or_phone_number_login_screen.js +126 -0
- package/lib/connection/captcha.js +21 -6
- package/lib/connection/database/actions.js +5 -5
- package/lib/connection/database/index.js +1 -1
- package/lib/connection/database/login_pane.js +1 -1
- package/lib/connection/enterprise/actions.js +2 -2
- package/lib/connection/enterprise/hrd_pane.js +1 -1
- package/lib/connection/passwordless/actions.js +33 -11
- package/lib/core/index.js +12 -6
- package/lib/core/remote_data.js +9 -0
- package/lib/core/web_api/helper.js +3 -3
- package/lib/core/web_api/p2_api.js +6 -0
- package/lib/core/web_api.js +4 -0
- package/lib/core.js +1 -1
- package/lib/engine/classic/sign_up_pane.js +1 -1
- package/lib/engine/classic/sign_up_screen.js +1 -1
- package/lib/engine/passwordless/social_or_email_login_screen.js +12 -1
- package/lib/engine/passwordless/social_or_phone_number_login_screen.js +12 -1
- package/lib/field/captcha/captcha_pane.js +4 -3
- package/lib/field/email/email_pane.js +1 -1
- package/lib/field/index.js +1 -1
- package/lib/field/password/password_pane.js +1 -1
- package/lib/field/username/username_pane.js +1 -1
- package/lib/i18n/af.js +3 -1
- package/lib/i18n/ar.js +3 -1
- package/lib/i18n/az.js +3 -1
- package/lib/i18n/bg.js +3 -1
- package/lib/i18n/ca.js +3 -1
- package/lib/i18n/cs.js +3 -1
- package/lib/i18n/da.js +3 -1
- package/lib/i18n/de.js +3 -1
- package/lib/i18n/el.js +3 -1
- package/lib/i18n/en.js +3 -1
- package/lib/i18n/es.js +3 -1
- package/lib/i18n/et.js +3 -1
- package/lib/i18n/fa.js +3 -1
- package/lib/i18n/fi.js +3 -1
- package/lib/i18n/fr.js +3 -1
- package/lib/i18n/he.js +3 -1
- package/lib/i18n/hr.js +3 -1
- package/lib/i18n/hu.js +3 -1
- package/lib/i18n/id.js +3 -1
- package/lib/i18n/it.js +3 -1
- package/lib/i18n/ja.js +3 -1
- package/lib/i18n/ko.js +3 -1
- package/lib/i18n/lt.js +3 -1
- package/lib/i18n/lv.js +3 -1
- package/lib/i18n/ms.js +3 -1
- package/lib/i18n/nb.js +3 -1
- package/lib/i18n/nl.js +3 -1
- package/lib/i18n/nn.js +3 -1
- package/lib/i18n/no.js +3 -1
- package/lib/i18n/pl.js +3 -1
- package/lib/i18n/pt-br.js +3 -1
- package/lib/i18n/pt.js +3 -1
- package/lib/i18n/ro.js +3 -1
- package/lib/i18n/ru.js +3 -1
- package/lib/i18n/sk.js +3 -1
- package/lib/i18n/sl.js +3 -1
- package/lib/i18n/sr.js +3 -1
- package/lib/i18n/sv.js +3 -1
- package/lib/i18n/tr.js +3 -1
- package/lib/i18n/ua.js +3 -1
- package/lib/i18n/uk.js +3 -1
- package/lib/i18n/vi.js +3 -1
- package/lib/i18n/zh-tw.js +3 -1
- package/lib/i18n/zh.js +3 -1
- package/lib/i18n.js +1 -1
- package/lib/lock.js +1 -1
- package/lib/passwordless.js +1 -1
- package/lib/ui/box/multisize_slide.js +1 -1
- package/opslevel.yml +6 -0
- package/package.json +22 -21
|
@@ -52,7 +52,8 @@ describe('passwordless actions', function () {
|
|
|
52
52
|
jest.mock('core/web_api', function () {
|
|
53
53
|
return {
|
|
54
54
|
startPasswordless: jest.fn(),
|
|
55
|
-
passwordlessVerify: jest.fn()
|
|
55
|
+
passwordlessVerify: jest.fn(),
|
|
56
|
+
getPasswordlessChallenge: jest.fn()
|
|
56
57
|
};
|
|
57
58
|
});
|
|
58
59
|
jest.mock('core/actions', function () {
|
|
@@ -91,7 +92,8 @@ describe('passwordless actions', function () {
|
|
|
91
92
|
connections: jest.fn(),
|
|
92
93
|
useCustomPasswordlessConnection: jest.fn(function () {
|
|
93
94
|
return false;
|
|
94
|
-
})
|
|
95
|
+
}),
|
|
96
|
+
passwordlessCaptcha: jest.fn()
|
|
95
97
|
};
|
|
96
98
|
});
|
|
97
99
|
jest.mock('store/index', function () {
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var _react = require('react');
|
|
4
|
+
|
|
5
|
+
var _react2 = _interopRequireDefault(_react);
|
|
6
|
+
|
|
7
|
+
var _testUtils = require('testUtils');
|
|
8
|
+
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
|
|
11
|
+
jest.mock('connection/enterprise');
|
|
12
|
+
jest.mock('core/index');
|
|
13
|
+
|
|
14
|
+
jest.mock('field/social/social_buttons_pane', function () {
|
|
15
|
+
return (0, _testUtils.mockComponent)('social_buttons_pane');
|
|
16
|
+
});
|
|
17
|
+
jest.mock('field/email/email_pane', function () {
|
|
18
|
+
return (0, _testUtils.mockComponent)('email_pane');
|
|
19
|
+
});
|
|
20
|
+
jest.mock('field/captcha/captcha_pane', function () {
|
|
21
|
+
return (0, _testUtils.mockComponent)('captcha_pane');
|
|
22
|
+
});
|
|
23
|
+
jest.mock('core/pane_separator', function () {
|
|
24
|
+
return (0, _testUtils.mockComponent)('pane_separator');
|
|
25
|
+
});
|
|
26
|
+
jest.mock('connection/database/sign_up_terms', function () {
|
|
27
|
+
return (0, _testUtils.mockComponent)('sign_up_terms');
|
|
28
|
+
});
|
|
29
|
+
jest.mock('connection/passwordless/index', function () {
|
|
30
|
+
return {
|
|
31
|
+
isEmail: jest.fn()
|
|
32
|
+
};
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
var getComponent = function getComponent() {
|
|
36
|
+
var SocialOrEmailScreen = require('engine/passwordless/social_or_email_login_screen').default;
|
|
37
|
+
var screen = new SocialOrEmailScreen();
|
|
38
|
+
return screen.render();
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
describe('email passwordless', function () {
|
|
42
|
+
beforeEach(function () {
|
|
43
|
+
jest.resetModules();
|
|
44
|
+
jest.resetAllMocks();
|
|
45
|
+
|
|
46
|
+
jest.mock('connection/database/index', function () {
|
|
47
|
+
return {
|
|
48
|
+
hasScreen: function hasScreen() {
|
|
49
|
+
return false;
|
|
50
|
+
},
|
|
51
|
+
databaseUsernameValue: jest.fn()
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
jest.mock('connection/database/actions', function () {
|
|
56
|
+
return {
|
|
57
|
+
cancelMFALogin: jest.fn(),
|
|
58
|
+
logIn: jest.fn()
|
|
59
|
+
};
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
jest.mock('core/signed_in_confirmation', function () {
|
|
63
|
+
return {
|
|
64
|
+
renderSignedInConfirmation: jest.fn()
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
jest.mock('connection/enterprise', function () {
|
|
69
|
+
return {
|
|
70
|
+
isHRDEmailValid: jest.fn(function () {
|
|
71
|
+
return false;
|
|
72
|
+
}),
|
|
73
|
+
isHRDDomain: jest.fn(function () {
|
|
74
|
+
return true;
|
|
75
|
+
})
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
jest.mock('core/index', function () {
|
|
80
|
+
return {
|
|
81
|
+
hasSomeConnections: jest.fn(function () {
|
|
82
|
+
return true;
|
|
83
|
+
}),
|
|
84
|
+
passwordlessCaptcha: jest.fn()
|
|
85
|
+
};
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
var defaultProps = {
|
|
90
|
+
i18n: {
|
|
91
|
+
str: function str() {
|
|
92
|
+
for (var _len = arguments.length, keys = Array(_len), _key = 0; _key < _len; _key++) {
|
|
93
|
+
keys[_key] = arguments[_key];
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return keys.join(',');
|
|
97
|
+
},
|
|
98
|
+
html: function html() {
|
|
99
|
+
for (var _len2 = arguments.length, keys = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
100
|
+
keys[_key2] = arguments[_key2];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return keys.join(',');
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
model: 'model'
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
it('renders correctly', function () {
|
|
110
|
+
var Component = getComponent();
|
|
111
|
+
|
|
112
|
+
(0, _testUtils.expectComponent)(_react2.default.createElement(Component, defaultProps)).toMatchSnapshot();
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('renders a captcha', function () {
|
|
116
|
+
var Component = getComponent();
|
|
117
|
+
|
|
118
|
+
require('core/index').passwordlessCaptcha.mockReturnValue({
|
|
119
|
+
get: function get() {
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
(0, _testUtils.expectComponent)(_react2.default.createElement(Component, defaultProps)).toMatchSnapshot();
|
|
125
|
+
});
|
|
126
|
+
});
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var _react = require('react');
|
|
4
|
+
|
|
5
|
+
var _react2 = _interopRequireDefault(_react);
|
|
6
|
+
|
|
7
|
+
var _testUtils = require('testUtils');
|
|
8
|
+
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
|
|
11
|
+
jest.mock('connection/enterprise');
|
|
12
|
+
jest.mock('core/index');
|
|
13
|
+
|
|
14
|
+
jest.mock('field/social/social_buttons_pane', function () {
|
|
15
|
+
return (0, _testUtils.mockComponent)('social_buttons_pane');
|
|
16
|
+
});
|
|
17
|
+
jest.mock('field/phone-number/phone_number_pane', function () {
|
|
18
|
+
return (0, _testUtils.mockComponent)('phone_number_pane');
|
|
19
|
+
});
|
|
20
|
+
jest.mock('field/captcha/captcha_pane', function () {
|
|
21
|
+
return (0, _testUtils.mockComponent)('captcha_pane');
|
|
22
|
+
});
|
|
23
|
+
jest.mock('core/pane_separator', function () {
|
|
24
|
+
return (0, _testUtils.mockComponent)('pane_separator');
|
|
25
|
+
});
|
|
26
|
+
jest.mock('connection/database/sign_up_terms', function () {
|
|
27
|
+
return (0, _testUtils.mockComponent)('sign_up_terms');
|
|
28
|
+
});
|
|
29
|
+
jest.mock('connection/passwordless/index', function () {
|
|
30
|
+
return {
|
|
31
|
+
isEmail: jest.fn()
|
|
32
|
+
};
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
var getComponent = function getComponent() {
|
|
36
|
+
var SocialOrPhoneNumberScreen = require('engine/passwordless/social_or_phone_number_login_screen').default;
|
|
37
|
+
var screen = new SocialOrPhoneNumberScreen();
|
|
38
|
+
return screen.render();
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
describe('sms passwordless', function () {
|
|
42
|
+
beforeEach(function () {
|
|
43
|
+
jest.resetModules();
|
|
44
|
+
jest.resetAllMocks();
|
|
45
|
+
|
|
46
|
+
jest.mock('connection/database/index', function () {
|
|
47
|
+
return {
|
|
48
|
+
hasScreen: function hasScreen() {
|
|
49
|
+
return false;
|
|
50
|
+
},
|
|
51
|
+
databaseUsernameValue: jest.fn()
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
jest.mock('connection/database/actions', function () {
|
|
56
|
+
return {
|
|
57
|
+
cancelMFALogin: jest.fn(),
|
|
58
|
+
logIn: jest.fn()
|
|
59
|
+
};
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
jest.mock('core/signed_in_confirmation', function () {
|
|
63
|
+
return {
|
|
64
|
+
renderSignedInConfirmation: jest.fn()
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
jest.mock('connection/enterprise', function () {
|
|
69
|
+
return {
|
|
70
|
+
isHRDEmailValid: jest.fn(function () {
|
|
71
|
+
return false;
|
|
72
|
+
}),
|
|
73
|
+
isHRDDomain: jest.fn(function () {
|
|
74
|
+
return true;
|
|
75
|
+
})
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
jest.mock('core/index', function () {
|
|
80
|
+
return {
|
|
81
|
+
hasSomeConnections: jest.fn(function () {
|
|
82
|
+
return true;
|
|
83
|
+
}),
|
|
84
|
+
passwordlessCaptcha: jest.fn()
|
|
85
|
+
};
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
var defaultProps = {
|
|
90
|
+
i18n: {
|
|
91
|
+
str: function str() {
|
|
92
|
+
for (var _len = arguments.length, keys = Array(_len), _key = 0; _key < _len; _key++) {
|
|
93
|
+
keys[_key] = arguments[_key];
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return keys.join(',');
|
|
97
|
+
},
|
|
98
|
+
html: function html() {
|
|
99
|
+
for (var _len2 = arguments.length, keys = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
100
|
+
keys[_key2] = arguments[_key2];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return keys.join(',');
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
model: 'model'
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
it('renders correctly', function () {
|
|
110
|
+
var Component = getComponent();
|
|
111
|
+
|
|
112
|
+
(0, _testUtils.expectComponent)(_react2.default.createElement(Component, defaultProps)).toMatchSnapshot();
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('renders a captcha', function () {
|
|
116
|
+
var Component = getComponent();
|
|
117
|
+
|
|
118
|
+
require('core/index').passwordlessCaptcha.mockReturnValue({
|
|
119
|
+
get: function get() {
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
(0, _testUtils.expectComponent)(_react2.default.createElement(Component, defaultProps)).toMatchSnapshot();
|
|
125
|
+
});
|
|
126
|
+
});
|
|
@@ -32,11 +32,14 @@ function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj;
|
|
|
32
32
|
*
|
|
33
33
|
* @param {Object} m model
|
|
34
34
|
* @param {Number} id
|
|
35
|
+
* @param {Boolean} isPasswordless Whether the captcha is being rendered in a passwordless flow
|
|
35
36
|
*/
|
|
36
37
|
function showMissingCaptcha(m, id) {
|
|
37
|
-
var
|
|
38
|
+
var isPasswordless = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
38
39
|
|
|
39
|
-
var
|
|
40
|
+
var captchaConfig = isPasswordless ? l.passwordlessCaptcha(m) : l.captcha(m);
|
|
41
|
+
|
|
42
|
+
var captchaError = captchaConfig.get('provider') === 'recaptcha_v2' || captchaConfig.get('provider') === 'recaptcha_enterprise' ? 'invalid_recaptcha' : 'invalid_captcha';
|
|
40
43
|
|
|
41
44
|
var errorMessage = i18n.html(m, ['error', 'login', captchaError]);
|
|
42
45
|
|
|
@@ -53,13 +56,14 @@ function showMissingCaptcha(m, id) {
|
|
|
53
56
|
*
|
|
54
57
|
* @param {Object} m model
|
|
55
58
|
* @param {Object} params
|
|
59
|
+
* @param {Boolean} isPasswordless Whether the captcha is being rendered in a passwordless flow
|
|
56
60
|
* @param {Object} fields
|
|
57
61
|
*
|
|
58
62
|
* @returns {Boolean} returns true if is required and missing the response from the user
|
|
59
63
|
*/
|
|
60
|
-
function setCaptchaParams(m, params, fields) {
|
|
61
|
-
var captchaConfig = l.captcha(m);
|
|
62
|
-
var isCaptchaRequired = captchaConfig &&
|
|
64
|
+
function setCaptchaParams(m, params, isPasswordless, fields) {
|
|
65
|
+
var captchaConfig = isPasswordless ? l.passwordlessCaptcha(m) : l.captcha(m);
|
|
66
|
+
var isCaptchaRequired = captchaConfig && captchaConfig.get('required');
|
|
63
67
|
|
|
64
68
|
if (!isCaptchaRequired) {
|
|
65
69
|
return true;
|
|
@@ -79,10 +83,21 @@ function setCaptchaParams(m, params, fields) {
|
|
|
79
83
|
* Get a new challenge and display the new captcha image.
|
|
80
84
|
*
|
|
81
85
|
* @param {number} id The id of the Lock instance.
|
|
86
|
+
* @param {Boolean} isPasswordless Whether the captcha is being rendered in a passwordless flow.
|
|
82
87
|
* @param {boolean} wasInvalid A boolean indicating if the previous captcha was invalid.
|
|
83
88
|
* @param {Function} [next] A callback.
|
|
84
89
|
*/
|
|
85
|
-
function swapCaptcha(id, wasInvalid, next) {
|
|
90
|
+
function swapCaptcha(id, isPasswordless, wasInvalid, next) {
|
|
91
|
+
if (isPasswordless) {
|
|
92
|
+
return _web_api2.default.getPasswordlessChallenge(id, function (err, newCaptcha) {
|
|
93
|
+
if (!err && newCaptcha) {
|
|
94
|
+
(0, _index3.swap)(_index3.updateEntity, 'lock', id, l.setPasswordlessCaptcha, newCaptcha, wasInvalid);
|
|
95
|
+
}
|
|
96
|
+
if (next) {
|
|
97
|
+
next();
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
86
101
|
return _web_api2.default.getChallenge(id, function (err, newCaptcha) {
|
|
87
102
|
if (!err && newCaptcha) {
|
|
88
103
|
(0, _index3.swap)(_index3.updateEntity, 'lock', id, l.setCaptcha, newCaptcha, wasInvalid);
|
|
@@ -57,7 +57,7 @@ function logIn(id) {
|
|
|
57
57
|
};
|
|
58
58
|
|
|
59
59
|
var fields = [usernameField, 'password'];
|
|
60
|
-
var isCaptchaValid = (0, _captcha.setCaptchaParams)(m, params, fields);
|
|
60
|
+
var isCaptchaValid = (0, _captcha.setCaptchaParams)(m, params, false, fields);
|
|
61
61
|
|
|
62
62
|
if (!isCaptchaValid) {
|
|
63
63
|
return (0, _captcha.showMissingCaptcha)(m, id);
|
|
@@ -77,7 +77,7 @@ function logIn(id) {
|
|
|
77
77
|
|
|
78
78
|
if (error) {
|
|
79
79
|
var wasInvalid = error && error.code === 'invalid_captcha';
|
|
80
|
-
return (0, _captcha.swapCaptcha)(id, wasInvalid, next);
|
|
80
|
+
return (0, _captcha.swapCaptcha)(id, false, wasInvalid, next);
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
next();
|
|
@@ -114,7 +114,7 @@ function signUp(id) {
|
|
|
114
114
|
autoLogin: (0, _index4.shouldAutoLogin)(m)
|
|
115
115
|
};
|
|
116
116
|
|
|
117
|
-
var isCaptchaValid = (0, _captcha.setCaptchaParams)(m, params, fields);
|
|
117
|
+
var isCaptchaValid = (0, _captcha.setCaptchaParams)(m, params, false, fields);
|
|
118
118
|
if (!isCaptchaValid) {
|
|
119
119
|
return (0, _captcha.showMissingCaptcha)(m, id);
|
|
120
120
|
}
|
|
@@ -157,7 +157,7 @@ function signUp(id) {
|
|
|
157
157
|
|
|
158
158
|
var wasInvalidCaptcha = error && error.code === 'invalid_captcha';
|
|
159
159
|
|
|
160
|
-
(0, _captcha.swapCaptcha)(id, wasInvalidCaptcha, function () {
|
|
160
|
+
(0, _captcha.swapCaptcha)(id, false, wasInvalidCaptcha, function () {
|
|
161
161
|
setTimeout(function () {
|
|
162
162
|
return signUpError(id, error);
|
|
163
163
|
}, 250);
|
|
@@ -257,7 +257,7 @@ function signUpError(id, error) {
|
|
|
257
257
|
|
|
258
258
|
if (errorKey === 'invalid_captcha') {
|
|
259
259
|
errorMessage = i18n.html(m, ['error', 'login', errorKey]);
|
|
260
|
-
return (0, _captcha.swapCaptcha)(id, true, function () {
|
|
260
|
+
return (0, _captcha.swapCaptcha)(id, false, true, function () {
|
|
261
261
|
(0, _index.swap)(_index.updateEntity, 'lock', id, l.setSubmitting, false, errorMessage);
|
|
262
262
|
});
|
|
263
263
|
}
|
|
@@ -73,7 +73,7 @@ function initDatabase(m, options) {
|
|
|
73
73
|
|
|
74
74
|
function assertMaybeBoolean(opts, name) {
|
|
75
75
|
var valid = opts[name] === undefined || typeof opts[name] === 'boolean';
|
|
76
|
-
if (!valid) l.warn(opts, 'The `' + name + '` option will be ignored, because it is not a
|
|
76
|
+
if (!valid) l.warn(opts, 'The `' + name + '` option will be ignored, because it is not a boolean.');
|
|
77
77
|
return valid;
|
|
78
78
|
}
|
|
79
79
|
|
|
@@ -112,7 +112,7 @@ var LoginPane = function (_React$Component) {
|
|
|
112
112
|
});
|
|
113
113
|
|
|
114
114
|
var captchaPane = l.captcha(lock) && l.captcha(lock).get('required') && ((0, _enterprise.isHRDDomain)(lock, (0, _database.databaseUsernameValue)(lock)) || !sso) ? _react2.default.createElement(_captcha_pane2.default, { i18n: i18n, lock: lock, onReload: function onReload() {
|
|
115
|
-
return (0, _captcha.swapCaptcha)(l.id(lock), false);
|
|
115
|
+
return (0, _captcha.swapCaptcha)(l.id(lock), false, false);
|
|
116
116
|
} }) : null;
|
|
117
117
|
|
|
118
118
|
var dontRememberPassword = showForgotPasswordLink && (0, _index.hasScreen)(lock, 'forgotPassword') ? _react2.default.createElement(
|
|
@@ -70,7 +70,7 @@ function logIn(id) {
|
|
|
70
70
|
return logInSSO(id, ssoConnection, params);
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
var isCaptchaValid = (0, _captcha.setCaptchaParams)(m, params, fields);
|
|
73
|
+
var isCaptchaValid = (0, _captcha.setCaptchaParams)(m, params, false, fields);
|
|
74
74
|
|
|
75
75
|
if (!isCaptchaValid && !ssoConnection) {
|
|
76
76
|
return (0, _captcha.showMissingCaptcha)(m, id);
|
|
@@ -95,7 +95,7 @@ function logInActiveFlow(id, params) {
|
|
|
95
95
|
login_hint: username
|
|
96
96
|
}), function (id, error, fields, next) {
|
|
97
97
|
var wasCaptchaInvalid = error && error.code === 'invalid captcha';
|
|
98
|
-
(0, _captcha.swapCaptcha)(id, wasCaptchaInvalid, next);
|
|
98
|
+
(0, _captcha.swapCaptcha)(id, false, wasCaptchaInvalid, next);
|
|
99
99
|
});
|
|
100
100
|
}
|
|
101
101
|
|
|
@@ -57,7 +57,7 @@ var HRDPane = function (_React$Component) {
|
|
|
57
57
|
|
|
58
58
|
|
|
59
59
|
var captchaPane = l.captcha(model) && l.captcha(model).get('required') ? _react2.default.createElement(_captcha_pane2.default, { i18n: i18n, lock: model, onReload: function onReload() {
|
|
60
|
-
return (0, _captcha.swapCaptcha)(l.id(model), false);
|
|
60
|
+
return (0, _captcha.swapCaptcha)(l.id(model), false, false);
|
|
61
61
|
} }) : null;
|
|
62
62
|
|
|
63
63
|
return _react2.default.createElement(
|
|
@@ -13,8 +13,6 @@ exports.logIn = logIn;
|
|
|
13
13
|
exports.restart = restart;
|
|
14
14
|
exports.toggleTermsAcceptance = toggleTermsAcceptance;
|
|
15
15
|
|
|
16
|
-
var _immutable = require('immutable');
|
|
17
|
-
|
|
18
16
|
var _index = require('../../store/index');
|
|
19
17
|
|
|
20
18
|
var _actions = require('../../core/actions');
|
|
@@ -39,23 +37,35 @@ var _i18n = require('../../i18n');
|
|
|
39
37
|
|
|
40
38
|
var i18n = _interopRequireWildcard(_i18n);
|
|
41
39
|
|
|
40
|
+
var _captcha = require('../captcha');
|
|
41
|
+
|
|
42
42
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
|
43
43
|
|
|
44
44
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
45
45
|
|
|
46
|
-
function getErrorMessage(m, error) {
|
|
46
|
+
function getErrorMessage(m, id, error) {
|
|
47
47
|
var key = error.error;
|
|
48
48
|
|
|
49
49
|
if (error.error === 'sms_provider_error' && (error.description || '').indexOf('(Code: 21211)') > -1) {
|
|
50
50
|
key = 'bad.phone_number';
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
if (error.code === 'invalid_captcha') {
|
|
54
|
+
var captchaConfig = l.passwordlessCaptcha(m);
|
|
55
|
+
key = captchaConfig.get('provider') === 'recaptcha_v2' || captchaConfig.get('provider') === 'recaptcha_enterprise' ? 'invalid_recaptcha' : 'invalid_captcha';
|
|
56
|
+
}
|
|
57
|
+
|
|
53
58
|
return i18n.html(m, ['error', 'passwordless', key]) || i18n.html(m, ['error', 'passwordless', 'lock.fallback']);
|
|
54
59
|
}
|
|
55
60
|
|
|
61
|
+
function swapCaptchaAfterError(id, error) {
|
|
62
|
+
var wasCaptchaInvalid = error && error.code === 'invalid_captcha';
|
|
63
|
+
(0, _captcha.swapCaptcha)(id, true, wasCaptchaInvalid);
|
|
64
|
+
}
|
|
65
|
+
|
|
56
66
|
function requestPasswordlessEmail(id) {
|
|
57
67
|
(0, _actions.validateAndSubmit)(id, ['email'], function (m) {
|
|
58
|
-
sendEmail(m, requestPasswordlessEmailSuccess, requestPasswordlessEmailError);
|
|
68
|
+
sendEmail(m, id, requestPasswordlessEmailSuccess, requestPasswordlessEmailError);
|
|
59
69
|
});
|
|
60
70
|
}
|
|
61
71
|
|
|
@@ -68,14 +78,15 @@ function requestPasswordlessEmailSuccess(id) {
|
|
|
68
78
|
|
|
69
79
|
function requestPasswordlessEmailError(id, error) {
|
|
70
80
|
var m = (0, _index.read)(_index.getEntity, 'lock', id);
|
|
71
|
-
var errorMessage = getErrorMessage(m, error);
|
|
72
|
-
|
|
81
|
+
var errorMessage = getErrorMessage(m, id, error);
|
|
82
|
+
(0, _index.swap)(_index.updateEntity, 'lock', id, l.setSubmitting, false, errorMessage);
|
|
83
|
+
swapCaptchaAfterError(id, error);
|
|
73
84
|
}
|
|
74
85
|
|
|
75
86
|
function resendEmail(id) {
|
|
76
87
|
(0, _index.swap)(_index.updateEntity, 'lock', id, _index4.resend);
|
|
77
88
|
var m = (0, _index.read)(_index.getEntity, 'lock', id);
|
|
78
|
-
sendEmail(m, resendEmailSuccess, resendEmailError);
|
|
89
|
+
sendEmail(m, id, resendEmailSuccess, resendEmailError);
|
|
79
90
|
}
|
|
80
91
|
|
|
81
92
|
function resendEmailSuccess(id) {
|
|
@@ -92,7 +103,7 @@ function getPasswordlessConnectionName(m, defaultPasswordlessConnection) {
|
|
|
92
103
|
return connections.size > 0 && l.useCustomPasswordlessConnection(m) ? connections.first().get('name') : defaultPasswordlessConnection;
|
|
93
104
|
}
|
|
94
105
|
|
|
95
|
-
function sendEmail(m, successFn, errorFn) {
|
|
106
|
+
function sendEmail(m, id, successFn, errorFn) {
|
|
96
107
|
var params = {
|
|
97
108
|
connection: getPasswordlessConnectionName(m, 'email'),
|
|
98
109
|
email: c.getFieldValue(m, 'email'),
|
|
@@ -102,6 +113,11 @@ function sendEmail(m, successFn, errorFn) {
|
|
|
102
113
|
if ((0, _index4.isSendLink)(m) && !l.auth.params(m).isEmpty()) {
|
|
103
114
|
params.authParams = l.auth.params(m).toJS();
|
|
104
115
|
}
|
|
116
|
+
var isCaptchaValid = (0, _captcha.setCaptchaParams)(m, params, true, []);
|
|
117
|
+
|
|
118
|
+
if (!isCaptchaValid) {
|
|
119
|
+
return (0, _captcha.showMissingCaptcha)(m, id, true);
|
|
120
|
+
}
|
|
105
121
|
|
|
106
122
|
_web_api2.default.startPasswordless(l.id(m), params, function (error) {
|
|
107
123
|
if (error) {
|
|
@@ -121,6 +137,10 @@ function sendSMS(id) {
|
|
|
121
137
|
phoneNumber: (0, _phone_number.phoneNumberWithDiallingCode)(m),
|
|
122
138
|
send: (0, _index4.send)(m)
|
|
123
139
|
};
|
|
140
|
+
var isCaptchaValid = (0, _captcha.setCaptchaParams)(m, params, true, []);
|
|
141
|
+
if (!isCaptchaValid) {
|
|
142
|
+
return (0, _captcha.showMissingCaptcha)(m, id, true);
|
|
143
|
+
}
|
|
124
144
|
_web_api2.default.startPasswordless(id, params, function (error) {
|
|
125
145
|
if (error) {
|
|
126
146
|
setTimeout(function () {
|
|
@@ -143,9 +163,10 @@ function sendSMSSuccess(id) {
|
|
|
143
163
|
|
|
144
164
|
function sendSMSError(id, error) {
|
|
145
165
|
var m = (0, _index.read)(_index.getEntity, 'lock', id);
|
|
146
|
-
var errorMessage = getErrorMessage(m, error);
|
|
166
|
+
var errorMessage = getErrorMessage(m, id, error);
|
|
147
167
|
l.emitAuthorizationErrorEvent(m, error);
|
|
148
|
-
|
|
168
|
+
(0, _index.swap)(_index.updateEntity, 'lock', id, l.setSubmitting, false, errorMessage);
|
|
169
|
+
swapCaptchaAfterError(id, error);
|
|
149
170
|
}
|
|
150
171
|
|
|
151
172
|
function logIn(id) {
|
|
@@ -166,7 +187,7 @@ function logIn(id) {
|
|
|
166
187
|
var errorMessage = void 0;
|
|
167
188
|
if (error) {
|
|
168
189
|
var _m = (0, _index.read)(_index.getEntity, 'lock', id);
|
|
169
|
-
errorMessage = getErrorMessage(_m, error);
|
|
190
|
+
errorMessage = getErrorMessage(_m, id, error);
|
|
170
191
|
if (error.logToConsole) {
|
|
171
192
|
console.error(error.description);
|
|
172
193
|
}
|
|
@@ -180,6 +201,7 @@ function logIn(id) {
|
|
|
180
201
|
|
|
181
202
|
function restart(id) {
|
|
182
203
|
(0, _index.swap)(_index.updateEntity, 'lock', id, _index4.restartPasswordless);
|
|
204
|
+
(0, _captcha.swapCaptcha)(id, true, false);
|
|
183
205
|
}
|
|
184
206
|
|
|
185
207
|
function toggleTermsAcceptance(id) {
|
package/lib/core/index.js
CHANGED
|
@@ -39,7 +39,9 @@ exports.setLoggedIn = setLoggedIn;
|
|
|
39
39
|
exports.loggedIn = loggedIn;
|
|
40
40
|
exports.defaultADUsernameFromEmailPrefix = defaultADUsernameFromEmailPrefix;
|
|
41
41
|
exports.setCaptcha = setCaptcha;
|
|
42
|
+
exports.setPasswordlessCaptcha = setPasswordlessCaptcha;
|
|
42
43
|
exports.captcha = captcha;
|
|
44
|
+
exports.passwordlessCaptcha = passwordlessCaptcha;
|
|
43
45
|
exports.prefill = prefill;
|
|
44
46
|
exports.warn = warn;
|
|
45
47
|
exports.error = error;
|
|
@@ -572,15 +574,19 @@ function setCaptcha(m, value, wasInvalid) {
|
|
|
572
574
|
return set(m, 'captcha', _immutable2.default.fromJS(value));
|
|
573
575
|
}
|
|
574
576
|
|
|
577
|
+
function setPasswordlessCaptcha(m, value, wasInvalid) {
|
|
578
|
+
m = captchaField.reset(m, wasInvalid);
|
|
579
|
+
return set(m, 'passwordlessCaptcha', _immutable2.default.fromJS(value));
|
|
580
|
+
}
|
|
581
|
+
|
|
575
582
|
function captcha(m) {
|
|
576
|
-
//some tests send an string as model.
|
|
577
|
-
// https://github.com/auth0/lock/blob/82f56187698528699478bd429858cf91e387763c/src/__tests__/engine/classic/sign_up_pane.test.jsx#L28
|
|
578
|
-
if ((typeof m === 'undefined' ? 'undefined' : _typeof(m)) !== 'object') {
|
|
579
|
-
return;
|
|
580
|
-
}
|
|
581
583
|
return get(m, 'captcha');
|
|
582
584
|
}
|
|
583
585
|
|
|
586
|
+
function passwordlessCaptcha(m) {
|
|
587
|
+
return get(m, 'passwordlessCaptcha');
|
|
588
|
+
}
|
|
589
|
+
|
|
584
590
|
function prefill(m) {
|
|
585
591
|
return get(m, 'prefill', {});
|
|
586
592
|
}
|
|
@@ -779,7 +785,7 @@ function loginErrorMessage(m, error, type) {
|
|
|
779
785
|
|
|
780
786
|
if (code === 'invalid_captcha') {
|
|
781
787
|
var currentCaptcha = get(m, 'captcha');
|
|
782
|
-
if (currentCaptcha && currentCaptcha.get('provider') === 'recaptcha_v2') {
|
|
788
|
+
if (currentCaptcha && (currentCaptcha.get('provider') === 'recaptcha_v2' || currentCaptcha.get('provider') === 'recaptcha_enterprise')) {
|
|
783
789
|
code = 'invalid_recaptcha';
|
|
784
790
|
}
|
|
785
791
|
}
|
package/lib/core/remote_data.js
CHANGED
|
@@ -98,5 +98,14 @@ function syncRemoteData(m) {
|
|
|
98
98
|
successFn: _index2.setCaptcha
|
|
99
99
|
});
|
|
100
100
|
|
|
101
|
+
m = (0, _sync2.default)(m, 'passwordlessCaptcha', {
|
|
102
|
+
syncFn: function syncFn(m, cb) {
|
|
103
|
+
_web_api2.default.getPasswordlessChallenge(m.get('id'), function (err, r) {
|
|
104
|
+
cb(null, r);
|
|
105
|
+
});
|
|
106
|
+
},
|
|
107
|
+
successFn: _index2.setPasswordlessCaptcha
|
|
108
|
+
});
|
|
109
|
+
|
|
101
110
|
return m;
|
|
102
111
|
} // shouldn't depend on this
|
|
@@ -21,8 +21,8 @@ function normalizeError(error, domain) {
|
|
|
21
21
|
|
|
22
22
|
// TODO: the following checks were copied from https://github.com/auth0/lock/blob/0a5abf1957c9bb746b0710b274d0feed9b399958/index.js#L1263-L1288
|
|
23
23
|
// Some of the checks are missing because I couldn't reproduce them and I'm
|
|
24
|
-
//
|
|
25
|
-
// We need a better
|
|
24
|
+
// afraid they'll break existent functionality if add them.
|
|
25
|
+
// We need a better error handling story in auth0.js.
|
|
26
26
|
|
|
27
27
|
if (error.status === 'User closed the popup window') {
|
|
28
28
|
// {
|
|
@@ -176,5 +176,5 @@ function trimAuthParams() {
|
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
function getVersion() {
|
|
179
|
-
return '11.
|
|
179
|
+
return '11.35.0';
|
|
180
180
|
}
|
|
@@ -206,6 +206,12 @@ var Auth0APIClient = function () {
|
|
|
206
206
|
return (_client$client2 = this.client.client).getChallenge.apply(_client$client2, arguments);
|
|
207
207
|
};
|
|
208
208
|
|
|
209
|
+
Auth0APIClient.prototype.getPasswordlessChallenge = function getPasswordlessChallenge() {
|
|
210
|
+
var _client$client$passwo;
|
|
211
|
+
|
|
212
|
+
return (_client$client$passwo = this.client.client.passwordless).getChallenge.apply(_client$client$passwo, arguments);
|
|
213
|
+
};
|
|
214
|
+
|
|
209
215
|
Auth0APIClient.prototype.getUserCountry = function getUserCountry(cb) {
|
|
210
216
|
return this.client.client.getUserCountry(cb);
|
|
211
217
|
};
|
package/lib/core/web_api.js
CHANGED
|
@@ -75,6 +75,10 @@ var Auth0WebAPI = function () {
|
|
|
75
75
|
return this.clients[lockID].getChallenge(callback);
|
|
76
76
|
};
|
|
77
77
|
|
|
78
|
+
Auth0WebAPI.prototype.getPasswordlessChallenge = function getPasswordlessChallenge(lockID, callback) {
|
|
79
|
+
return this.clients[lockID].getPasswordlessChallenge(callback);
|
|
80
|
+
};
|
|
81
|
+
|
|
78
82
|
Auth0WebAPI.prototype.getSSOData = function getSSOData(lockID) {
|
|
79
83
|
var _clients$lockID;
|
|
80
84
|
|