auth0-lock 11.30.3 → 11.31.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 +66 -19
- package/.eslintrc.json +9 -2
- package/.prettierignore +1 -0
- package/.prettierrc.yaml +5 -0
- package/.shiprc +7 -0
- package/CHANGELOG.md +387 -208
- package/DEVELOPMENT.md +13 -3
- package/LICENSE +23 -0
- package/README.md +160 -139
- package/karma.conf.js +129 -0
- package/lib/__tests__/connection/database/reset_password.js +82 -4
- package/lib/__tests__/core/index.js +134 -0
- package/lib/__tests__/core/web_api/helper.js +3 -3
- package/lib/__tests__/core/web_api.js +7 -7
- package/lib/__tests__/setup-tests.js +1 -1
- package/lib/__tests__/ui/box/chrome.js +16 -3
- package/lib/__tests__/utils/format.js +33 -0
- package/lib/browser.js +6 -6
- package/lib/connection/database/index.js +2 -2
- package/lib/connection/database/reset_password.js +15 -0
- package/lib/core/actions.js +3 -3
- package/lib/core/index.js +11 -18
- package/lib/core/web_api/helper.js +1 -1
- package/lib/core.js +1 -1
- package/lib/i18n/nl.js +34 -34
- package/lib/i18n.js +5 -3
- package/lib/lock.js +1 -1
- package/lib/passwordless.js +1 -1
- package/lib/store/index.js +1 -1
- package/lib/sync.js +1 -1
- package/lib/ui/box/chrome.js +16 -5
- package/lib/ui/box/container.js +4 -4
- package/lib/ui/box/header.js +4 -4
- package/lib/ui/box.js +5 -5
- package/lib/ui/input/password/password_strength.js +3 -3
- package/lib/utils/cdn_utils.js +6 -6
- package/lib/utils/format.js +48 -0
- package/package.json +40 -36
- package/.zuul.yml +0 -19
- package/circle.yml +0 -19
package/karma.conf.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
module.exports = function(config) {
|
|
2
|
+
process.env.CHROME_BIN = require('puppeteer').executablePath();
|
|
3
|
+
|
|
4
|
+
config.set({
|
|
5
|
+
// base path that will be used to resolve all patterns (eg. files, exclude)
|
|
6
|
+
basePath: '',
|
|
7
|
+
|
|
8
|
+
// frameworks to use
|
|
9
|
+
frameworks: ['mocha', 'browserify'],
|
|
10
|
+
|
|
11
|
+
//plugins
|
|
12
|
+
plugins: [
|
|
13
|
+
'karma-mocha',
|
|
14
|
+
'karma-babel-preprocessor',
|
|
15
|
+
'karma-browserstack-launcher',
|
|
16
|
+
'karma-chrome-launcher',
|
|
17
|
+
'karma-browserify',
|
|
18
|
+
'karma-mocha-reporter'
|
|
19
|
+
],
|
|
20
|
+
|
|
21
|
+
// list of files / patterns to load in the browser
|
|
22
|
+
files: [
|
|
23
|
+
'test/**/*.test.js',
|
|
24
|
+
'test/setup.js',
|
|
25
|
+
{
|
|
26
|
+
pattern: 'src/!(__tests__)/**/*.jsx?',
|
|
27
|
+
type: 'js'
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
|
|
31
|
+
preprocessors: {
|
|
32
|
+
'src/!(__tests__)/**/*.jsx?': ['browserify'],
|
|
33
|
+
'test/**/*.js': ['browserify']
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
browserify: {
|
|
37
|
+
debug: true,
|
|
38
|
+
transform: ['babelify'],
|
|
39
|
+
extensions: ['.js', '.jsx']
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
// test results reporter to use
|
|
43
|
+
reporters: ['mocha', 'BrowserStack'],
|
|
44
|
+
|
|
45
|
+
// web server port
|
|
46
|
+
port: 9876,
|
|
47
|
+
|
|
48
|
+
// enable / disable colors in the output (reporters and logs)
|
|
49
|
+
colors: true,
|
|
50
|
+
|
|
51
|
+
singleRun: true,
|
|
52
|
+
|
|
53
|
+
browserNoActivityTimeout: 60000,
|
|
54
|
+
|
|
55
|
+
browserDisconnectTimeout: 20000,
|
|
56
|
+
|
|
57
|
+
browserDisconnectTolerance: 3,
|
|
58
|
+
|
|
59
|
+
// level of logging
|
|
60
|
+
logLevel: config.LOG_INFO,
|
|
61
|
+
|
|
62
|
+
browserStack: {
|
|
63
|
+
username: process.env.BROWSERSTACK_USERNAME,
|
|
64
|
+
accessKey: process.env.BROWSERSTACK_ACCESS_KEY,
|
|
65
|
+
name: 'Lock.js Browser Tests',
|
|
66
|
+
project: 'Lock.js SDK'
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
mochaReporter: {
|
|
70
|
+
output: 'minimal'
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
// define browsers
|
|
74
|
+
customLaunchers: {
|
|
75
|
+
bs_chrome_windows: {
|
|
76
|
+
base: 'BrowserStack',
|
|
77
|
+
browser: 'chrome',
|
|
78
|
+
browser_version: 'latest',
|
|
79
|
+
os: 'Windows',
|
|
80
|
+
os_version: '10',
|
|
81
|
+
displayName: 'Chrome on Windows 10'
|
|
82
|
+
},
|
|
83
|
+
bs_edge_windows: {
|
|
84
|
+
base: 'BrowserStack',
|
|
85
|
+
browser: 'edge',
|
|
86
|
+
browser_version: 'latest',
|
|
87
|
+
os: 'Windows',
|
|
88
|
+
os_version: '10',
|
|
89
|
+
displayName: 'Chrome on Windows 10'
|
|
90
|
+
},
|
|
91
|
+
bs_firefox_windows: {
|
|
92
|
+
base: 'BrowserStack',
|
|
93
|
+
browser: 'firefox',
|
|
94
|
+
browser_version: 'latest',
|
|
95
|
+
os: 'Windows',
|
|
96
|
+
os_version: '10',
|
|
97
|
+
displayName: 'Firefox on Windows 10'
|
|
98
|
+
},
|
|
99
|
+
bs_safari: {
|
|
100
|
+
base: 'BrowserStack',
|
|
101
|
+
browser: 'safari',
|
|
102
|
+
browser_version: 'latest',
|
|
103
|
+
os: 'OS X',
|
|
104
|
+
os_version: 'Big Sur',
|
|
105
|
+
displayName: 'Latest Safari on Big Sur'
|
|
106
|
+
},
|
|
107
|
+
bs_ie11_windows: {
|
|
108
|
+
base: 'BrowserStack',
|
|
109
|
+
browser: 'IE',
|
|
110
|
+
browser_version: 'latest',
|
|
111
|
+
os: 'Windows',
|
|
112
|
+
os_version: '10',
|
|
113
|
+
displayName: 'IE11 on Windows 10'
|
|
114
|
+
},
|
|
115
|
+
chrome_headless: {
|
|
116
|
+
base: 'Chrome',
|
|
117
|
+
flags: ['--headless']
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
browsers: [
|
|
122
|
+
'bs_chrome_windows',
|
|
123
|
+
'bs_firefox_windows',
|
|
124
|
+
'bs_safari',
|
|
125
|
+
'bs_ie11_windows',
|
|
126
|
+
'bs_edge_windows'
|
|
127
|
+
]
|
|
128
|
+
});
|
|
129
|
+
};
|
|
@@ -4,15 +4,30 @@ var _react = require('react');
|
|
|
4
4
|
|
|
5
5
|
var _react2 = _interopRequireDefault(_react);
|
|
6
6
|
|
|
7
|
-
var
|
|
7
|
+
var _testUtils = require('testUtils');
|
|
8
|
+
|
|
9
|
+
var _immutable = require('immutable');
|
|
10
|
+
|
|
11
|
+
var _immutable2 = _interopRequireDefault(_immutable);
|
|
12
|
+
|
|
13
|
+
var _field = require('../../../field');
|
|
8
14
|
|
|
9
15
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
16
|
|
|
17
|
+
jest.mock('connection/database/reset_password_pane', function () {
|
|
18
|
+
return (0, _testUtils.mockComponent)('reset_password_pane');
|
|
19
|
+
});
|
|
20
|
+
|
|
11
21
|
var getScreen = function getScreen() {
|
|
12
22
|
var ResetPasswordScreen = require('connection/database/reset_password').default;
|
|
13
23
|
return new ResetPasswordScreen();
|
|
14
24
|
};
|
|
15
25
|
|
|
26
|
+
var getComponent = function getComponent() {
|
|
27
|
+
var screen = getScreen();
|
|
28
|
+
return screen.render();
|
|
29
|
+
};
|
|
30
|
+
|
|
16
31
|
describe('ResetPasswordScreen', function () {
|
|
17
32
|
beforeEach(function () {
|
|
18
33
|
jest.resetModules();
|
|
@@ -35,9 +50,11 @@ describe('ResetPasswordScreen', function () {
|
|
|
35
50
|
});
|
|
36
51
|
|
|
37
52
|
jest.mock('i18n', function () {
|
|
38
|
-
return {
|
|
53
|
+
return {
|
|
54
|
+
str: function str(_, keys) {
|
|
39
55
|
return keys.join(',');
|
|
40
|
-
}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
41
58
|
});
|
|
42
59
|
|
|
43
60
|
jest.mock('core/index', function () {
|
|
@@ -46,7 +63,16 @@ describe('ResetPasswordScreen', function () {
|
|
|
46
63
|
return 'id';
|
|
47
64
|
},
|
|
48
65
|
setGlobalError: 'setGlobalError',
|
|
49
|
-
clearGlobalError: 'clearGlobalError'
|
|
66
|
+
clearGlobalError: 'clearGlobalError',
|
|
67
|
+
connectionResolver: jest.fn().mockReturnValue(undefined),
|
|
68
|
+
ui: {
|
|
69
|
+
allowAutocomplete: function allowAutocomplete() {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
submitting: function submitting() {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
50
76
|
};
|
|
51
77
|
});
|
|
52
78
|
|
|
@@ -57,6 +83,7 @@ describe('ResetPasswordScreen', function () {
|
|
|
57
83
|
};
|
|
58
84
|
});
|
|
59
85
|
});
|
|
86
|
+
|
|
60
87
|
it('isSubmitDisabled returns true when `isEnterpriseDomain` is true', function () {
|
|
61
88
|
jest.useFakeTimers();
|
|
62
89
|
require('connection/enterprise').isEnterpriseDomain = function () {
|
|
@@ -67,6 +94,7 @@ describe('ResetPasswordScreen', function () {
|
|
|
67
94
|
jest.runTimersToTime(50);
|
|
68
95
|
expect(require('store/index').swap.mock.calls[0]).toMatchSnapshot();
|
|
69
96
|
});
|
|
97
|
+
|
|
70
98
|
it('isSubmitDisabled returns false when `isEnterpriseDomain` is false', function () {
|
|
71
99
|
require('connection/enterprise').isEnterpriseDomain = function () {
|
|
72
100
|
return false;
|
|
@@ -75,4 +103,54 @@ describe('ResetPasswordScreen', function () {
|
|
|
75
103
|
expect(screen.isSubmitDisabled()).toBe(false);
|
|
76
104
|
expect(require('store/index').swap.mock.calls[0]).toMatchSnapshot();
|
|
77
105
|
});
|
|
106
|
+
|
|
107
|
+
describe('a custom connection resolver is being used', function () {
|
|
108
|
+
var lock = void 0;
|
|
109
|
+
var i18n = void 0;
|
|
110
|
+
|
|
111
|
+
beforeEach(function () {
|
|
112
|
+
lock = _immutable2.default.fromJS({
|
|
113
|
+
id: '__lock-id__'
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
i18n = {
|
|
117
|
+
html: jest.fn(),
|
|
118
|
+
str: jest.fn()
|
|
119
|
+
};
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('copies the username to the email field if an email address was entered', function () {
|
|
123
|
+
require('core/index').connectionResolver.mockReturnValue(function () {
|
|
124
|
+
return function () {
|
|
125
|
+
return true;
|
|
126
|
+
};
|
|
127
|
+
});
|
|
128
|
+
var store = require('store/index');
|
|
129
|
+
var Component = getComponent();
|
|
130
|
+
|
|
131
|
+
// Set a field on Lock to set the username field, then check it was set as the email
|
|
132
|
+
var l = (0, _field.setField)(lock, 'username', 'test@test.com');
|
|
133
|
+
|
|
134
|
+
(0, _testUtils.expectComponent)(_react2.default.createElement(Component, { i18n: i18n, model: l })).toMatchSnapshot();
|
|
135
|
+
|
|
136
|
+
expect(store.swap).toHaveBeenCalledWith('updateEntity', 'lock', 'id', expect.anything(), 'test@test.com', false);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('sets the email field to a blank value if username is not an email address', function () {
|
|
140
|
+
require('core/index').connectionResolver.mockReturnValue(function () {
|
|
141
|
+
return function () {
|
|
142
|
+
return true;
|
|
143
|
+
};
|
|
144
|
+
});
|
|
145
|
+
var store = require('store/index');
|
|
146
|
+
var Component = getComponent();
|
|
147
|
+
|
|
148
|
+
// Set a field on Lock to set the username field, then check it was set as the email
|
|
149
|
+
var l = (0, _field.setField)(lock, 'username', 'some-username');
|
|
150
|
+
|
|
151
|
+
(0, _testUtils.expectComponent)(_react2.default.createElement(Component, { i18n: i18n, model: l })).toMatchSnapshot();
|
|
152
|
+
|
|
153
|
+
expect(store.swap).toHaveBeenCalledWith('updateEntity', 'lock', 'id', expect.anything(), '', false);
|
|
154
|
+
});
|
|
155
|
+
});
|
|
78
156
|
});
|
|
@@ -59,6 +59,7 @@ describe('setup', function () {
|
|
|
59
59
|
mockInit = jest.fn();
|
|
60
60
|
jest.resetModules();
|
|
61
61
|
});
|
|
62
|
+
|
|
62
63
|
it('default redirectUrl should not include location.hash', function () {
|
|
63
64
|
(0, _testUtils.setURL)('https://test.com/path/#not-this-part');
|
|
64
65
|
var options = {};
|
|
@@ -70,6 +71,7 @@ describe('setup', function () {
|
|
|
70
71
|
var model = mock.calls[0][1].toJS();
|
|
71
72
|
expect(model.auth.redirectUrl).toBe('https://test.com/path/');
|
|
72
73
|
});
|
|
74
|
+
|
|
73
75
|
it('default redirectUrl should work when `window.location.origin` is not available', function () {
|
|
74
76
|
(0, _testUtils.setURL)('https://test.com/path/#not-this-part', { noOrigin: true });
|
|
75
77
|
var options = {};
|
|
@@ -81,6 +83,7 @@ describe('setup', function () {
|
|
|
81
83
|
var model = mock.calls[0][1].toJS();
|
|
82
84
|
expect(model.auth.redirectUrl).toBe('https://test.com/path/');
|
|
83
85
|
});
|
|
86
|
+
|
|
84
87
|
it('should work with redirect:false and responseType:id_token', function () {
|
|
85
88
|
var options = {
|
|
86
89
|
auth: {
|
|
@@ -88,6 +91,7 @@ describe('setup', function () {
|
|
|
88
91
|
responseType: 'id_token'
|
|
89
92
|
}
|
|
90
93
|
};
|
|
94
|
+
|
|
91
95
|
setup('id', 'clientID', 'domain', options, 'hookRunner', 'emitEventFn', 'handleEventFn');
|
|
92
96
|
var _mockInit3 = mockInit,
|
|
93
97
|
mock = _mockInit3.mock;
|
|
@@ -96,6 +100,136 @@ describe('setup', function () {
|
|
|
96
100
|
var model = mock.calls[0][1].toJS();
|
|
97
101
|
expect(model).toMatchSnapshot();
|
|
98
102
|
});
|
|
103
|
+
|
|
104
|
+
describe('clientBaseUrl', function () {
|
|
105
|
+
it('should default to the specified domain', function () {
|
|
106
|
+
var _mockInit4 = mockInit,
|
|
107
|
+
mock = _mockInit4.mock;
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
setup('id', 'clientID', 'my-tenant.us.auth0.com', {}, 'hookRunner', 'emitEventFn', 'handleEventFn');
|
|
111
|
+
|
|
112
|
+
expect(mock.calls.length).toBe(1);
|
|
113
|
+
|
|
114
|
+
var model = mock.calls[0][1].toJS();
|
|
115
|
+
expect(model.clientBaseUrl).toBe('https://my-tenant.us.auth0.com');
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('should use the clientBaseUrl option if given', function () {
|
|
119
|
+
var _mockInit5 = mockInit,
|
|
120
|
+
mock = _mockInit5.mock;
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
setup('id', 'clientID', 'my-tenant.us.auth0.com', {
|
|
124
|
+
clientBaseUrl: 'https://client-base-url.example.com',
|
|
125
|
+
configurationBaseUrl: 'https://config-base-url.example.com',
|
|
126
|
+
assetsUrl: 'https://assets-url.example.com'
|
|
127
|
+
}, 'hookRunner', 'emitEventFn', 'handleEventFn');
|
|
128
|
+
|
|
129
|
+
expect(mock.calls.length).toBe(1);
|
|
130
|
+
|
|
131
|
+
var model = mock.calls[0][1].toJS();
|
|
132
|
+
expect(model.clientBaseUrl).toBe('https://client-base-url.example.com');
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('should use configurationBaseUrl if given', function () {
|
|
136
|
+
var _mockInit6 = mockInit,
|
|
137
|
+
mock = _mockInit6.mock;
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
setup('id', 'clientID', 'my-tenant.us.auth0.com', {
|
|
141
|
+
configurationBaseUrl: 'https://config-base-url.example.com',
|
|
142
|
+
assetsUrl: 'https://assets-url.example.com'
|
|
143
|
+
}, 'hookRunner', 'emitEventFn', 'handleEventFn');
|
|
144
|
+
|
|
145
|
+
expect(mock.calls.length).toBe(1);
|
|
146
|
+
|
|
147
|
+
var model = mock.calls[0][1].toJS();
|
|
148
|
+
expect(model.clientBaseUrl).toBe('https://config-base-url.example.com');
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('should use assetsUrl if given', function () {
|
|
152
|
+
var _mockInit7 = mockInit,
|
|
153
|
+
mock = _mockInit7.mock;
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
setup('id', 'clientID', 'my-tenant.us.auth0.com', {
|
|
157
|
+
assetsUrl: 'https://assets-url.example.com'
|
|
158
|
+
}, 'hookRunner', 'emitEventFn', 'handleEventFn');
|
|
159
|
+
|
|
160
|
+
expect(mock.calls.length).toBe(1);
|
|
161
|
+
|
|
162
|
+
var model = mock.calls[0][1].toJS();
|
|
163
|
+
expect(model.clientBaseUrl).toBe('https://assets-url.example.com');
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
describe('tenantBaseUrl', function () {
|
|
168
|
+
it('should default to domain URL when using auth0.com', function () {
|
|
169
|
+
var _mockInit8 = mockInit,
|
|
170
|
+
mock = _mockInit8.mock;
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
setup('id', 'clientID', 'my-tenant.us.auth0.com', {
|
|
174
|
+
__useTenantInfo: true
|
|
175
|
+
}, 'hookRunner', 'emitEventFn', 'handleEventFn');
|
|
176
|
+
|
|
177
|
+
expect(mock.calls.length).toBe(1);
|
|
178
|
+
|
|
179
|
+
var model = mock.calls[0][1].toJS();
|
|
180
|
+
expect(model.tenantBaseUrl).toBe('https://my-tenant.us.auth0.com/tenants/v1/my-tenant.js');
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it('should default to domain URL when using a custom domain', function () {
|
|
184
|
+
var _mockInit9 = mockInit,
|
|
185
|
+
mock = _mockInit9.mock;
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
setup('id', 'clientID', 'auth.my-tenant.com', {
|
|
189
|
+
__useTenantInfo: true
|
|
190
|
+
}, 'hookRunner', 'emitEventFn', 'handleEventFn');
|
|
191
|
+
|
|
192
|
+
expect(mock.calls.length).toBe(1);
|
|
193
|
+
|
|
194
|
+
var model = mock.calls[0][1].toJS();
|
|
195
|
+
expect(model.tenantBaseUrl).toBe('https://auth.my-tenant.com/info-v1.js');
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it('should use configurationBaseUrl if specified', function () {
|
|
199
|
+
var _mockInit10 = mockInit,
|
|
200
|
+
mock = _mockInit10.mock;
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
setup('id', 'clientID', 'auth.my-tenant.com', {
|
|
204
|
+
__useTenantInfo: true,
|
|
205
|
+
configurationBaseUrl: 'https://config-base-url.com'
|
|
206
|
+
}, 'hookRunner', 'emitEventFn', 'handleEventFn');
|
|
207
|
+
|
|
208
|
+
expect(mock.calls.length).toBe(1);
|
|
209
|
+
|
|
210
|
+
var model = mock.calls[0][1].toJS();
|
|
211
|
+
expect(model.tenantBaseUrl).toBe('https://config-base-url.com/info-v1.js');
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it('should use configurationBaseUrl with a custom tenant if specified', function () {
|
|
215
|
+
var _mockInit11 = mockInit,
|
|
216
|
+
mock = _mockInit11.mock;
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
setup('id', 'clientID', 'auth.my-tenant.com', {
|
|
220
|
+
__useTenantInfo: true,
|
|
221
|
+
configurationBaseUrl: 'https://config-base-url.com',
|
|
222
|
+
overrides: {
|
|
223
|
+
__tenant: 'custom-tenant'
|
|
224
|
+
}
|
|
225
|
+
}, 'hookRunner', 'emitEventFn', 'handleEventFn');
|
|
226
|
+
|
|
227
|
+
expect(mock.calls.length).toBe(1);
|
|
228
|
+
|
|
229
|
+
var model = mock.calls[0][1].toJS();
|
|
230
|
+
expect(model.tenantBaseUrl).toBe('https://config-base-url.com/tenants/v1/custom-tenant.js');
|
|
231
|
+
});
|
|
232
|
+
});
|
|
99
233
|
});
|
|
100
234
|
|
|
101
235
|
describe('setResolvedConnection', function () {
|
|
@@ -44,8 +44,8 @@ describe('normalizeError', function () {
|
|
|
44
44
|
var currentWindowObj = void 0;
|
|
45
45
|
|
|
46
46
|
beforeAll(function () {
|
|
47
|
-
currentWindowObj =
|
|
48
|
-
|
|
47
|
+
currentWindowObj = window.window;
|
|
48
|
+
window.window = {
|
|
49
49
|
locaction: {
|
|
50
50
|
host: domainMock
|
|
51
51
|
}
|
|
@@ -53,7 +53,7 @@ describe('normalizeError', function () {
|
|
|
53
53
|
});
|
|
54
54
|
|
|
55
55
|
afterAll(function () {
|
|
56
|
-
|
|
56
|
+
window.window = currentWindowObj;
|
|
57
57
|
});
|
|
58
58
|
|
|
59
59
|
describe('domain is undefined', function () {
|
|
@@ -19,16 +19,16 @@ describe('Auth0WebApi', function () {
|
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
beforeEach(function () {
|
|
22
|
-
originalWindow =
|
|
22
|
+
originalWindow = window.window;
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
afterEach(function () {
|
|
26
|
-
|
|
26
|
+
window.window = originalWindow;
|
|
27
27
|
});
|
|
28
28
|
|
|
29
29
|
describe('setupClient', function () {
|
|
30
30
|
it('sets the correct options when is on the hosted login page', function () {
|
|
31
|
-
delete
|
|
31
|
+
delete window.location;
|
|
32
32
|
window.location = _extends({}, originalWindow.location, { host: DEFAULT_DOMAIN, search: '' });
|
|
33
33
|
_web_api2.default.setupClient(LOCK_ID, CLIENT_ID, DEFAULT_DOMAIN, { redirect: true });
|
|
34
34
|
|
|
@@ -42,7 +42,7 @@ describe('Auth0WebApi', function () {
|
|
|
42
42
|
});
|
|
43
43
|
|
|
44
44
|
it('sets redirect: true when on the same origin as the specified domain', function () {
|
|
45
|
-
delete
|
|
45
|
+
delete window.location;
|
|
46
46
|
window.location = _extends({}, originalWindow.location, { host: DEFAULT_DOMAIN, search: '' });
|
|
47
47
|
|
|
48
48
|
_web_api2.default.setupClient(LOCK_ID, CLIENT_ID, DEFAULT_DOMAIN, {});
|
|
@@ -50,7 +50,7 @@ describe('Auth0WebApi', function () {
|
|
|
50
50
|
});
|
|
51
51
|
|
|
52
52
|
it('sets redirect: false when on a different origin as the specified domain', function () {
|
|
53
|
-
delete
|
|
53
|
+
delete window.location;
|
|
54
54
|
window.location = _extends({}, originalWindow.location, { host: 'test-other.com', search: '' });
|
|
55
55
|
|
|
56
56
|
_web_api2.default.setupClient(LOCK_ID, CLIENT_ID, DEFAULT_DOMAIN, {});
|
|
@@ -58,7 +58,7 @@ describe('Auth0WebApi', function () {
|
|
|
58
58
|
});
|
|
59
59
|
|
|
60
60
|
it('forces popup and sso mode for cordova, only when not running in the hosted environment', function () {
|
|
61
|
-
delete
|
|
61
|
+
delete window.location;
|
|
62
62
|
window.location = _extends({}, originalWindow.location, { host: DEFAULT_DOMAIN, search: '' });
|
|
63
63
|
window.cordova = true;
|
|
64
64
|
|
|
@@ -68,7 +68,7 @@ describe('Auth0WebApi', function () {
|
|
|
68
68
|
});
|
|
69
69
|
|
|
70
70
|
it('forces popup and sso mode for electron, only when not running in the hosted environment', function () {
|
|
71
|
-
delete
|
|
71
|
+
delete window.location;
|
|
72
72
|
window.location = _extends({}, originalWindow.location, { host: DEFAULT_DOMAIN, search: '' });
|
|
73
73
|
window.electron = true;
|
|
74
74
|
|
|
@@ -12,6 +12,6 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
12
12
|
(0, _enzyme.configure)({ adapter: new _enzymeAdapterReact2.default() });
|
|
13
13
|
|
|
14
14
|
//jest polyfills
|
|
15
|
-
|
|
15
|
+
window.requestAnimationFrame = function (callback) {
|
|
16
16
|
setTimeout(callback, 0);
|
|
17
17
|
};
|
|
@@ -10,8 +10,6 @@ var _immutable = require('immutable');
|
|
|
10
10
|
|
|
11
11
|
var _immutable2 = _interopRequireDefault(_immutable);
|
|
12
12
|
|
|
13
|
-
var _reactTestRenderer = require('react-test-renderer');
|
|
14
|
-
|
|
15
13
|
var _testUtils = require('testUtils');
|
|
16
14
|
|
|
17
15
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -44,7 +42,10 @@ jest.mock('core/index', function () {
|
|
|
44
42
|
return {
|
|
45
43
|
handleEvent: jest.fn(function (_, event, fn) {
|
|
46
44
|
mockEventRegister[event] = fn;
|
|
47
|
-
})
|
|
45
|
+
}),
|
|
46
|
+
ui: {
|
|
47
|
+
forceAutoHeight: jest.fn().mockReturnValue(false)
|
|
48
|
+
}
|
|
48
49
|
};
|
|
49
50
|
});
|
|
50
51
|
|
|
@@ -113,4 +114,16 @@ describe('Chrome', function () {
|
|
|
113
114
|
|
|
114
115
|
(0, _testUtils.expectComponent)(_react2.default.createElement(Chrome, props)).toMatchSnapshot();
|
|
115
116
|
});
|
|
117
|
+
|
|
118
|
+
it('adds the auto-height class when forceAutoHeight UI prop is true', function () {
|
|
119
|
+
require('core/index').ui.forceAutoHeight.mockReturnValue(true);
|
|
120
|
+
|
|
121
|
+
var props = _extends({}, defaultProps, {
|
|
122
|
+
info: 'This is an information message',
|
|
123
|
+
success: 'This is a success message',
|
|
124
|
+
error: 'There is an error'
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
(0, _testUtils.expectComponent)(_react2.default.createElement(Chrome, props)).toMatchSnapshot();
|
|
128
|
+
});
|
|
116
129
|
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var _format = require('../../utils/format');
|
|
4
|
+
|
|
5
|
+
var _format2 = _interopRequireDefault(_format);
|
|
6
|
+
|
|
7
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
8
|
+
|
|
9
|
+
describe('format', function () {
|
|
10
|
+
it('can format a string', function () {
|
|
11
|
+
expect((0, _format2.default)('a string')).toEqual('a string');
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('can replace a string', function () {
|
|
15
|
+
expect((0, _format2.default)('%s', 'test')).toEqual('test');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('can replace a string inside a string', function () {
|
|
19
|
+
expect((0, _format2.default)('a string: %s', 'test')).toEqual('a string: test');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('can replace multiple strings', function () {
|
|
23
|
+
expect((0, _format2.default)('%s:%s', 'a', 'b')).toEqual('a:b');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('can replace with a number', function () {
|
|
27
|
+
expect((0, _format2.default)('%d', 12)).toEqual('12');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('can format an object', function () {
|
|
31
|
+
expect((0, _format2.default)('%j', { key: 'value' })).toEqual('{"key":"value"}');
|
|
32
|
+
});
|
|
33
|
+
});
|
package/lib/browser.js
CHANGED
|
@@ -19,14 +19,14 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
19
19
|
* the package.json file points to index.js.
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
if (typeof
|
|
23
|
-
|
|
22
|
+
if (typeof window.define == 'function' && window.define.amd) {
|
|
23
|
+
window.define('auth0Lock', function () {
|
|
24
24
|
return _index2.default;
|
|
25
25
|
});
|
|
26
|
-
|
|
26
|
+
window.define('auth0LockPasswordless', function () {
|
|
27
27
|
return _passwordless2.default;
|
|
28
28
|
});
|
|
29
|
-
} else if (
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
} else if (window.window) {
|
|
30
|
+
window.Auth0Lock = _index2.default;
|
|
31
|
+
window.Auth0LockPasswordless = _passwordless2.default;
|
|
32
32
|
}
|
|
@@ -92,7 +92,7 @@ function assertMaybeString(opts, name) {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
function assertMaybeArray(opts, name) {
|
|
95
|
-
var valid = opts[name] === undefined ||
|
|
95
|
+
var valid = opts[name] === undefined || window.Array.isArray(opts[name]);
|
|
96
96
|
if (!valid) l.warn(opts, 'The `' + name + '` option will be ignored, because it is not an array.');
|
|
97
97
|
return valid;
|
|
98
98
|
}
|
|
@@ -208,7 +208,7 @@ function processDatabaseOptions(opts) {
|
|
|
208
208
|
options = undefined;
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
-
if (options != undefined && !
|
|
211
|
+
if (options != undefined && !window.Array.isArray(options) && typeof options != 'function' || type === 'select' && options === undefined) {
|
|
212
212
|
l.warn(opts, 'Ignoring an element of `additionalSignUpFields` (' + name + ') because it has a "select" `type` but does not specify an `options` property that is an Array or a function.');
|
|
213
213
|
filter = false;
|
|
214
214
|
}
|
|
@@ -34,6 +34,10 @@ var l = _interopRequireWildcard(_index3);
|
|
|
34
34
|
|
|
35
35
|
var _index4 = require('../../store/index');
|
|
36
36
|
|
|
37
|
+
var _email = require('../../field/email');
|
|
38
|
+
|
|
39
|
+
var _field = require('../../field');
|
|
40
|
+
|
|
37
41
|
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; } }
|
|
38
42
|
|
|
39
43
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -54,6 +58,17 @@ var Component = function Component(_ref) {
|
|
|
54
58
|
null,
|
|
55
59
|
headerText
|
|
56
60
|
);
|
|
61
|
+
var connectionResolver = l.connectionResolver(model);
|
|
62
|
+
|
|
63
|
+
// When using a custom connection resolver, `usernameStyle` is always 'username' (as opposed to 'email').
|
|
64
|
+
// If the user has entered an email address as the username, and a custom resolver is being used, copy the
|
|
65
|
+
// value from the 'username' field to the 'email' field so that `EmailPane` can render it.
|
|
66
|
+
if (connectionResolver) {
|
|
67
|
+
var field = (0, _field.getField)(model, 'username');
|
|
68
|
+
var value = field.get('value', '');
|
|
69
|
+
|
|
70
|
+
(0, _index4.swap)(_index4.updateEntity, 'lock', l.id(model), _email.setEmail, (0, _email.isEmail)(value, false) ? value : '', false);
|
|
71
|
+
}
|
|
57
72
|
|
|
58
73
|
return _react2.default.createElement(_reset_password_pane2.default, {
|
|
59
74
|
emailInputPlaceholder: i18n.str('emailInputPlaceholder'),
|
package/lib/core/actions.js
CHANGED
|
@@ -67,14 +67,14 @@ function handleAuthCallback() {
|
|
|
67
67
|
var keepHash = ms.filter(function (m) {
|
|
68
68
|
return !l.hashCleanup(m);
|
|
69
69
|
}).size > 0;
|
|
70
|
-
var urlWithoutHash =
|
|
70
|
+
var urlWithoutHash = window.location.href.split('#')[0];
|
|
71
71
|
var callback = function callback(error, authResult) {
|
|
72
72
|
var parsed = !!(error || authResult);
|
|
73
73
|
if (parsed && !keepHash) {
|
|
74
|
-
|
|
74
|
+
window.history.replaceState(null, '', urlWithoutHash);
|
|
75
75
|
}
|
|
76
76
|
};
|
|
77
|
-
resumeAuth(
|
|
77
|
+
resumeAuth(window.location.hash, callback);
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
function resumeAuth(hash, callback) {
|