[FIX] auth_password_policy: Cannot read property 'decorations' of undefined

Revision on https://github.com/odoo/odoo/commit/a47f6093f80cefa51c5a1bc1301db01007f97761

The commit above introduced a visual 'password strength' next to
the password wizard in Settings > Users, when the module
`auth_password_policy` is installed.

However, there was an traceback when trying to access the 'General
Settings' when some specific apps and modules were installed.

This issue comes from the small design issue with the new
PasswordField: it was designed as a field object that was
instantiated and returned in the `init` function of an InputField
with the password attribute set. This is not a solid design,
because the documentation of the `init` function does not
specify that it should return the newly instantiated object.

As a result, the implementation was very fragile and only worked
on FieldChar but not FieldText.

This commit fixes the issue by turning the FieldPassword a field
widget. As a result, the enabling of the password meter next to
a password input has changed:

Before this commit:

```
<field name="new_passwd" password="True" options="{'password_meter': True}"/>
```

With this commit:

```
<field name="new_passwd" password="True" widget="password_meter"/>
```

Closes #27440

closes odoo/odoo#27586
This commit is contained in:
Alexandre Kühn
2018-10-09 14:26:21 +00:00
parent 70e604a8fa
commit 5bbbd25edf
2 changed files with 5 additions and 18 deletions
@@ -7,6 +7,7 @@
odoo.define('auth_password_policy.PasswordField', function (require) {
"use strict";
var fields = require('web.basic_fields');
var registry = require('web.field_registry');
var policy = require('auth_password_policy');
var Meter = require('auth_password_policy.Meter');
var _formatValue = require('web.AbstractField').prototype._formatValue;
@@ -21,12 +22,12 @@ var PasswordField = fields.InputField.extend({
},
willStart: function () {
var _this = this;
var getPolicy = this.nodeOptions['password_meter'] ? this._rpc({
var getPolicy = this._rpc({
model: 'res.users',
method: 'get_password_policy',
}).then(function (p) {
_this._meter = new Meter(_this, new policy.Policy(p), policy.recommendations);
}) : undefined;
});
return $.when(
this._super.apply(this, arguments),
getPolicy
@@ -46,9 +47,6 @@ var PasswordField = fields.InputField.extend({
// insertAfter doesn't work and appendTo means the meter is
// ignored (as this.$el is an input[type=password])
_this.$el = t.add(meter.$el);
if (!_this.nodeOptions['password_meter']) {
meter.$el.hide();
}
}, _this.$el);
}).then(function () {
// initial meter update when re-editing
@@ -84,17 +82,6 @@ var PasswordField = fields.InputField.extend({
}
});
fields.InputField.include({
init: function (parent, name, record, options) {
var fieldsInfo = record.fieldsInfo[options.viewType];
var attrs = options.attrs || (fieldsInfo && fieldsInfo[name]) || {};
if ('password' in attrs
&& Object.getPrototypeOf(this) !== PasswordField.prototype) {
return new PasswordField(parent, name, record, options);
}
this._super.apply(this, arguments);
}
});
registry.add("password_meter", PasswordField);
return PasswordField;
});
@@ -5,7 +5,7 @@
<field name="model">change.password.user</field>
<field name="arch" type="xml">
<xpath expr="//field[@name='new_passwd']" position="attributes">
<attribute name="options">{'password_meter': True}</attribute>
<attribute name="widget">password_meter</attribute>
</xpath>
</field>
</record>