Description
Typing into the signup password field can throw TypeError: policy.toJS is not a function in PasswordStrength.render, causing the Lock form to unmount. In an embedded invitation flow, this leaves the host application's loading spinner visible.
Expected: a missing connection policy should not crash password validation or the strength hint. A configured policy should continue to enforce its rules.
Reproduction
This is reproducible consistently with the installed 15.0.1 modules when the selected connection has no passwordPolicy. The precise reason that policy is unavailable in the original application has not been established.
In a scratch project with auth0-lock@15.0.1, immutable@3.8.3 and jsdom installed, run this CommonJS script:
const { JSDOM } = require('jsdom');
const { window } = new JSDOM('<!doctype html>', {
url: 'https://example.test'
});
global.window = window;
global.document = window.document;
Object.defineProperty(globalThis, 'navigator', {
value: window.navigator,
configurable: true
});
const { fromJS } = require('immutable');
const {
passwordStrengthPolicy
} = require('auth0-lock/lib/connection/database');
const {
validatePassword
} = require('auth0-lock/lib/field/password');
const PasswordStrength =
require('auth0-lock/lib/ui/input/password/password_strength').default;
const model = fromJS({
id: 'repro',
core: {
ui: {},
transient: {
connections: {
database: [{ name: 'db', type: 'database' }],
enterprise: []
}
}
},
client: {}
});
const policy = passwordStrengthPolicy(model);
console.log('policy:', policy, 'type:', typeof policy);
for (const [label, reproduce] of [
['validation', () => validatePassword('short', policy)],
['strength rendering', () => new PasswordStrength({
password: 'short', policy, messages: {}
}).render()]
]) {
try {
reproduce();
console.log(label + ': no exception');
} catch (error) {
console.log(label + ': ' + error.message);
}
}
Output:
policy: none type: string
validation: policy.toJS is not a function
strength rendering: policy.toJS is not a function
A separate React/JSDOM component regression reproduces the password input being removed after typing when this policy is passed to PasswordInput with strength hints enabled.
Additional context
passwordStrengthPolicy defaults to the string 'none':
return (databaseConnection(m) || Map()).get('passwordPolicy', 'none');
Both password validation and strength rendering expect an Immutable policy and call .toJS(). The truthy string bypasses the existing absent-policy guards. The same fallback is present on the current master branch.
A minimal fix tested locally is:
- return (databaseConnection(m) || Map()).get('passwordPolicy', 'none');
+ return (databaseConnection(m) || Map()).get('passwordPolicy');
This uses the existing optional-policy behavior: nonempty passwords can proceed to server validation and the client strength hint is skipped when no policy is available. Configured policies remain enforced.
Component regression cases pass with this change:
- Connections have not loaded.
- The selected database connection lacks a policy.
- An enterprise default directory is selected alongside a database connection.
- A configured minimum length of 8 still rejects a short password, shows the hint, and accepts a sufficiently long password.
Related historical issue: #1612 described the same type mismatch in tenant-info formatting. This report concerns the selector's missing-policy fallback in 15.0.1.
Lock version
15.0.1
Which browsers have you tested in?
Chrome (original error report). The deterministic reproduction and component regressions above use JSDOM; the original live invitation failure was not reproduced end to end.
Description
Typing into the signup password field can throw
TypeError: policy.toJS is not a functioninPasswordStrength.render, causing the Lock form to unmount. In an embedded invitation flow, this leaves the host application's loading spinner visible.Expected: a missing connection policy should not crash password validation or the strength hint. A configured policy should continue to enforce its rules.
Reproduction
This is reproducible consistently with the installed 15.0.1 modules when the selected connection has no
passwordPolicy. The precise reason that policy is unavailable in the original application has not been established.In a scratch project with
auth0-lock@15.0.1,immutable@3.8.3andjsdominstalled, run this CommonJS script:Output:
A separate React/JSDOM component regression reproduces the password input being removed after typing when this policy is passed to
PasswordInputwith strength hints enabled.Additional context
passwordStrengthPolicydefaults to the string'none':Both password validation and strength rendering expect an Immutable policy and call
.toJS(). The truthy string bypasses the existing absent-policy guards. The same fallback is present on the current master branch.A minimal fix tested locally is:
This uses the existing optional-policy behavior: nonempty passwords can proceed to server validation and the client strength hint is skipped when no policy is available. Configured policies remain enforced.
Component regression cases pass with this change:
Related historical issue: #1612 described the same type mismatch in tenant-info formatting. This report concerns the selector's missing-policy fallback in 15.0.1.
Lock version
15.0.1
Which browsers have you tested in?
Chrome (original error report). The deterministic reproduction and component regressions above use JSDOM; the original live invitation failure was not reproduced end to end.