luci-base: luci.js: register rpc interceptor to catch expired sessions
authorJo-Philipp Wich <jo@mein.io>
Wed, 11 Sep 2019 07:30:00 +0000 (09:30 +0200)
committerJo-Philipp Wich <jo@mein.io>
Wed, 11 Sep 2019 10:21:24 +0000 (12:21 +0200)
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
modules/luci-base/htdocs/luci-static/resources/luci.js

index 0b9886680596d1b9af8c06721a991f86823fa1db..687ac0e678646b77cbe6eb27425ce2d17689fe87 100644 (file)
                        return (ft != null && ft != false);
                },
 
+               notifySessionExpiry: function() {
+                       Poll.stop();
+
+                       L.ui.showModal(_('Session expired'), [
+                               E('div', { class: 'alert-message warning' },
+                                       _('A new login is required since the authentication session expired.')),
+                               E('div', { class: 'right' },
+                                       E('div', {
+                                               class: 'btn primary',
+                                               click: function() {
+                                                       var loc = window.location;
+                                                       window.location = loc.protocol + '//' + loc.host + loc.pathname + loc.search;
+                                               }
+                                       }, _('To login…')))
+                       ]);
+
+                       L.raise('SessionError', 'Login session is expired');
+               },
+
                setupDOM: function(res) {
                        var domEv = res[0],
                            uiClass = res[1],
 
                        rpcClass.setBaseURL(rpcBaseURL);
 
-                       Request.addInterceptor(function(res) {
-                               if (res.status != 403 || res.headers.get('X-LuCI-Login-Required') != 'yes')
+                       rpcClass.addInterceptor(function(msg, req) {
+                               if (!L.isObject(msg) || !L.isObject(msg.error) || msg.error.code != -32002)
                                        return;
 
-                               Poll.stop();
-
-                               L.ui.showModal(_('Session expired'), [
-                                       E('div', { class: 'alert-message warning' },
-                                               _('A new login is required since the authentication session expired.')),
-                                       E('div', { class: 'right' },
-                                               E('div', {
-                                                       class: 'btn primary',
-                                                       click: function() {
-                                                               var loc = window.location;
-                                                               window.location = loc.protocol + '//' + loc.host + loc.pathname + loc.search;
-                                                       }
-                                               }, _('To login…')))
-                               ]);
+                               if (!L.isObject(req) || (req.object == 'session' && req.method == 'access'))
+                                       return;
+
+                               return rpcClass.declare({
+                                       'object': 'session',
+                                       'method': 'access',
+                                       'params': [ 'scope', 'object', 'function' ],
+                                       'expect': { access: true }
+                               })('uci', 'luci', 'read').catch(L.notifySessionExpiry);
+                       });
+
+                       Request.addInterceptor(function(res) {
+                               var isDenied = false;
+
+                               if (res.status == 403 && res.headers.get('X-LuCI-Login-Required') == 'yes')
+                                       isDenied = true;
+
+                               if (!isDenied)
+                                       return;
 
-                               throw 'Session expired';
+                               L.notifySessionExpiry();
                        });
 
                        return this.probeSystemFeatures().finally(this.initDOM);