From 9ae9657a8585b794bc93b993d83e64b6d7f65b92 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Mon, 16 Sep 2019 07:54:25 +0200 Subject: [PATCH] luci-mod-system: remplement password change as client side view Signed-off-by: Jo-Philipp Wich --- .../root/usr/share/rpcd/acl.d/luci-base.json | 2 +- .../resources/view/system/password.js | 123 +++++++++++++----- .../luasrc/controller/admin/system.lua | 14 +- .../luasrc/view/admin_system/password.htm | 59 --------- 4 files changed, 95 insertions(+), 103 deletions(-) delete mode 100644 modules/luci-mod-system/luasrc/view/admin_system/password.htm diff --git a/modules/luci-base/root/usr/share/rpcd/acl.d/luci-base.json b/modules/luci-base/root/usr/share/rpcd/acl.d/luci-base.json index e28bdfa72..32cb10596 100644 --- a/modules/luci-base/root/usr/share/rpcd/acl.d/luci-base.json +++ b/modules/luci-base/root/usr/share/rpcd/acl.d/luci-base.json @@ -50,7 +50,7 @@ "ubus": { "file": [ "write", "remove" ], "iwinfo": [ "scan" ], - "luci": [ "setInitAction", "setLocaltime" ], + "luci": [ "setInitAction", "setLocaltime", "setPassword" ], "uci": [ "add", "apply", "confirm", "delete", "order", "set", "rename" ] }, "uci": [ "*" ] diff --git a/modules/luci-mod-system/htdocs/luci-static/resources/view/system/password.js b/modules/luci-mod-system/htdocs/luci-static/resources/view/system/password.js index 7a79d7e2d..6c5ffa1b2 100644 --- a/modules/luci-mod-system/htdocs/luci-static/resources/view/system/password.js +++ b/modules/luci-mod-system/htdocs/luci-static/resources/view/system/password.js @@ -1,31 +1,94 @@ -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 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 L.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: %s'.format(_('Password strength'), _('More Characters')); + else if (strongRegex.test(value)) + strength.innerHTML = '%s: %s'.format(_('Password strength'), _('Strong')); + else if (mediumRegex.test(value)) + strength.innerHTML = '%s: %s'.format(_('Password strength'), _('Medium')); + else + strength.innerHTML = '%s: %s'.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 L.dom.callClassMethod(map, 'save').then(function() { + if (formData.password.pw1 == null || formData.password.pw1.length == 0) + return; + + if (formData.password.pw1 != formData.password.pw2) { + L.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) + L.ui.addNotification(null, E('p', _('The system password has been successfully changed.')), 'info'); + else + L.ui.addNotification(null, E('p', _('Failed to change the system password.')), 'danger'); + + formData.password.pw1 = null; + formData.password.pw2 = null; + + L.dom.callClassMethod(map, 'render'); + }); + }); + }, + + handleSaveApply: null, + handleReset: null +}); diff --git a/modules/luci-mod-system/luasrc/controller/admin/system.lua b/modules/luci-mod-system/luasrc/controller/admin/system.lua index be00a3f67..d1fda1d7c 100644 --- a/modules/luci-mod-system/luasrc/controller/admin/system.lua +++ b/modules/luci-mod-system/luasrc/controller/admin/system.lua @@ -12,8 +12,7 @@ function index() entry({"admin", "system", "ntp_restart"}, call("action_ntp_restart"), nil).leaf = true entry({"admin", "system", "admin"}, firstchild(), _("Administration"), 2) - entry({"admin", "system", "admin", "password"}, template("admin_system/password"), _("Router Password"), 1) - entry({"admin", "system", "admin", "password", "json"}, post("action_password")) + entry({"admin", "system", "admin", "password"}, view("system/password"), _("Router Password"), 1) if fs.access("/etc/config/dropbear") then entry({"admin", "system", "admin", "dropbear"}, cbi("admin_system/dropbear"), _("SSH Access"), 2) @@ -281,17 +280,6 @@ function action_reset() http.redirect(luci.dispatcher.build_url('admin/system/flashops')) end -function action_password() - local password = luci.http.formvalue("password") - if not password then - luci.http.status(400, "Bad Request") - return - end - - luci.http.prepare_content("application/json") - luci.http.write_json({ code = luci.sys.user.setpasswd("root", password) }) -end - function action_reboot() luci.sys.reboot() end diff --git a/modules/luci-mod-system/luasrc/view/admin_system/password.htm b/modules/luci-mod-system/luasrc/view/admin_system/password.htm deleted file mode 100644 index 6ca02a83c..000000000 --- a/modules/luci-mod-system/luasrc/view/admin_system/password.htm +++ /dev/null @@ -1,59 +0,0 @@ -<%+header%> - - - - - -
-

<%:Router Password%>

- -
- <%:Changes the administrator password for accessing the device%> -
- -
-
- -
- -
-
- -
- -
- -
-
-
-
-
- -
- -
- - - -<%+footer%> -- 2.25.1