treewide: import utility classes explicitly
[project/luci.git] / modules / luci-mod-system / htdocs / luci-static / resources / view / system / password.js
index 7a79d7e2da02b8b7870727a6e9870c9804bdab7f..2b79633cac1deb9cf574ad5923a401fe8f1a1333 100644 (file)
@@ -1,31 +1,97 @@
-function submitPassword(ev) {
-       var pw1 = document.body.querySelector('[name="pw1"]'),
-           pw2 = document.body.querySelector('[name="pw2"]');
-
-       if (!pw1.value.length || !pw2.value.length)
-               return;
-
-       if (pw1.value === pw2.value) {
-               L.showModal(_('Change login password'),
-                       E('p', { class: 'spinning' }, _('Changing password…')));
-
-               L.post('admin/system/admin/password/json', { password: pw1.value },
-                       function() {
-                               showModal(_('Change login password'), [
-                                       E('div', _('The system password has been successfully changed.')),
-                                       E('div', { 'class': 'right' },
-                                               E('div', { class: 'btn', click: L.hideModal }, _('Dismiss')))
-                               ]);
-
-                               pw1.value = pw2.value = '';
-                       });
-       }
-       else {
-               L.showModal(_('Change login password'), [
-                       E('div', { class: 'alert-message warning' },
-                               _('Given password confirmation did not match, password not changed!')),
-                       E('div', { 'class': 'right' },
-                               E('div', { class: 'btn', click: L.hideModal }, _('Dismiss')))
-               ]);
+'use strict';
+'require view';
+'require dom';
+'require ui';
+'require form';
+'require rpc';
+
+var formData = {
+       password: {
+               pw1: null,
+               pw2: null
        }
-}
+};
+
+var callSetPassword = rpc.declare({
+       object: 'luci',
+       method: 'setPassword',
+       params: [ 'username', 'password' ],
+       expect: { result: false }
+});
+
+return view.extend({
+       checkPassword: function(section_id, value) {
+               var strength = document.querySelector('.cbi-value-description'),
+                   strongRegex = new RegExp("^(?=.{8,})(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*\\W).*$", "g"),
+                   mediumRegex = new RegExp("^(?=.{7,})(((?=.*[A-Z])(?=.*[a-z]))|((?=.*[A-Z])(?=.*[0-9]))|((?=.*[a-z])(?=.*[0-9]))).*$", "g"),
+                   enoughRegex = new RegExp("(?=.{6,}).*", "g");
+
+               if (strength && value.length) {
+                       if (false == enoughRegex.test(value))
+                               strength.innerHTML = '%s: <span style="color:red">%s</span>'.format(_('Password strength'), _('More Characters'));
+                       else if (strongRegex.test(value))
+                               strength.innerHTML = '%s: <span style="color:green">%s</span>'.format(_('Password strength'), _('Strong'));
+                       else if (mediumRegex.test(value))
+                               strength.innerHTML = '%s: <span style="color:orange">%s</span>'.format(_('Password strength'), _('Medium'));
+                       else
+                               strength.innerHTML = '%s: <span style="color:red">%s</span>'.format(_('Password strength'), _('Weak'));
+               }
+
+               return true;
+       },
+
+       render: function() {
+               var m, s, o;
+
+               m = new form.JSONMap(formData, _('Router Password'), _('Changes the administrator password for accessing the device'));
+               s = m.section(form.NamedSection, 'password', 'password');
+
+               o = s.option(form.Value, 'pw1', _('Password'));
+               o.password = true;
+               o.validate = this.checkPassword;
+
+               o = s.option(form.Value, 'pw2', _('Confirmation'), ' ');
+               o.password = true;
+               o.renderWidget = function(/* ... */) {
+                       var node = form.Value.prototype.renderWidget.apply(this, arguments);
+
+                       node.childNodes[1].addEventListener('keydown', function(ev) {
+                               if (ev.keyCode == 13 && !ev.currentTarget.classList.contains('cbi-input-invalid'))
+                                       document.querySelector('.cbi-button-save').click();
+                       });
+
+                       return node;
+               };
+
+               return m.render();
+       },
+
+       handleSave: function() {
+               var map = document.querySelector('.cbi-map');
+
+               return dom.callClassMethod(map, 'save').then(function() {
+                       if (formData.password.pw1 == null || formData.password.pw1.length == 0)
+                               return;
+
+                       if (formData.password.pw1 != formData.password.pw2) {
+                               ui.addNotification(null, E('p', _('Given password confirmation did not match, password not changed!')), 'danger');
+                               return;
+                       }
+
+                       return callSetPassword('root', formData.password.pw1).then(function(success) {
+                               if (success)
+                                       ui.addNotification(null, E('p', _('The system password has been successfully changed.')), 'info');
+                               else
+                                       ui.addNotification(null, E('p', _('Failed to change the system password.')), 'danger');
+
+                               formData.password.pw1 = null;
+                               formData.password.pw2 = null;
+
+                               dom.callClassMethod(map, 'render');
+                       });
+               });
+       },
+
+       handleSaveApply: null,
+       handleReset: null
+});