From eded3b65a736a09c8e6a35a9be0dec4e13312e10 Mon Sep 17 00:00:00 2001 From: Christophe Maudoux Date: Sun, 18 Mar 2018 13:22:21 +0100 Subject: [PATCH] Filter 2FA sessions --- .../lib/Lemonldap/NG/Manager/2ndFA.pm | 96 +++++++++++-------- lemonldap-ng-manager/site/coffee/sfa.coffee | 19 +++- .../site/htdocs/static/js/sessions.js | 6 +- .../site/htdocs/static/js/sessions.min.js | 2 +- .../site/htdocs/static/js/sfa.js | 17 +++- .../site/htdocs/static/js/sfa.min.js | 2 +- lemonldap-ng-manager/site/templates/sfa.tpl | 6 +- 7 files changed, 97 insertions(+), 51 deletions(-) diff --git a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/2ndFA.pm b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/2ndFA.pm index 5bb432fe7..530c5e777 100644 --- a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/2ndFA.pm +++ b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/2ndFA.pm @@ -31,7 +31,6 @@ sub addRoutes { # HTML template $self->addRoute( 'sfa.html', undef, ['GET'] ) - # READ ->addRoute( sfa => { ':sessionType' => 'sfa' }, ['GET'] @@ -48,7 +47,7 @@ sub addRoutes { sfa => { ':sessionType' => { ':sessionId' => 'add2FAKey' } }, ['PUT'] ) - + # VERIFY 2FA KEY ->addRoute( sfa => { ':sessionType' => { ':sessionId' => 'verify2FAKey' } }, @@ -68,43 +67,43 @@ sub addRoutes { sub delete2FAKey { - my ( $self, $req, $session, $skey ) = @_; - - my $mod = $self->getMod($req) + my ( $self, $req, $session, $skey ) = @_; + + my $mod = $self->getMod($req) or return $self->sendError( $req, undef, 400 ); - + my $params = $req->parameters(); - my $Key = $params->{Key}; - - if ( $Key =~ /\bU2F\b/ ) { - return $self->deleteU2FKey( $req, $session, $skey ); - } - elsif ( $Key =~ /\bTOTP\b/ ) { - return $self->deleteTOTPKey( $req, $session, $skey ); - } - else { - return $self->sendError( $req, undef, 400 ); - } + my $Key = $params->{Key}; + + if ( $Key =~ /\bU2F\b/ ) { + return $self->deleteU2FKey( $req, $session, $skey ); + } + elsif ( $Key =~ /\bTOTP\b/ ) { + return $self->deleteTOTPKey( $req, $session, $skey ); + } + else { + return $self->sendError( $req, undef, 400 ); + } } sub add2FAKey { my ( $self, $req, $session, $skey ) = @_; - eval 'use Crypt::U2F::Server::Simple'; - if ($@) { - $self->error("Can't load U2F library: $@"); - return 0; - } - - return $self->addU2FKey( $req, $session, $skey ); + eval 'use Crypt::U2F::Server::Simple'; + if ($@) { + $self->error("Can't load U2F library: $@"); + return 0; + } + + return $self->addU2FKey( $req, $session, $skey ); } sub verify2FAKey { - my ( $self, $req, $session, $skey ) = @_; - - return $self->addU2FKey( $req, $session, $skey ); + my ( $self, $req, $session, $skey ) = @_; + + return $self->addU2FKey( $req, $session, $skey ); } ######################## @@ -115,17 +114,16 @@ sub sfa { my ( $self, $req, $session, $skey ) = @_; # Case 1: only one session is required - if ($session) {; + if ($session) { + return $self->session( $req, $session, $skey ); } - + my $mod = $self->getMod($req) or return $self->sendError( $req, undef, 400 ); my $params = $req->parameters(); my $type = delete $params->{sessionType}; $type = ucfirst($type); - my $Key = $params->{sessionType}; - my $res; # Case 2: list of sessions @@ -133,7 +131,11 @@ sub sfa { my $whatToTrace = Lemonldap::NG::Handler::PSGI::Main->tsv->{whatToTrace}; # 2.1 Get fields to require - my @fields = ( '_httpSessionType', $self->{ipField}, $whatToTrace, '_u2fKeyHandle', '_totp2fSecret' ); + my @fields = ( + '_httpSessionType', $self->{ipField}, + $whatToTrace, '_u2fKeyHandle', + '_totp2fSecret' + ); if ( my $groupBy = $params->{groupBy} ) { $groupBy =~ s/^substr\((\w+)(?:,\d+(?:,\d+)?)?\)$/$1/; $groupBy =~ s/^_whatToTrace$/$whatToTrace/o @@ -147,6 +149,13 @@ sub sfa { # not a keyword) my $moduleOptions = $mod->{options}; $moduleOptions->{backend} = $mod->{module}; + + # Select 2FA sessions to display + if ( defined $params->{TOTPCheck} ) { + $self->{TOTPCheck} = delete $params->{TOTPCheck}; + $self->{U2FCheck} = delete $params->{U2FCheck}; + } + my %filters = map { my $s = $_; $s =~ s/\b_whatToTrace\b/$whatToTrace/o; @@ -219,13 +228,22 @@ sub sfa { } } - # Display sessions with registered U2F key only - foreach my $session ( keys %$res ) { - delete $res->{$session} - unless ( ( defined $res->{$session}->{_u2fKeyHandle} and length $res->{$session}->{_u2fKeyHandle} ) - or ( defined $res->{$session}->{_totp2fSecret} and length $res->{$session}->{_totp2fSecret} ) ) - } - + # Filter 2FA sessions if needed + if ( $self->{U2FCheck} eq '2' ) { + foreach my $session ( keys %$res ) { + delete $res->{$session} + unless ( defined $res->{$session}->{_u2fKeyHandle} + and length $res->{$session}->{_u2fKeyHandle} ); + } + } + if ( $self->{TOTPCheck} eq '2' ) { + foreach my $session ( keys %$res ) { + delete $res->{$session} + unless ( defined $res->{$session}->{_totp2fSecret} + and length $res->{$session}->{_totp2fSecret} ); + } + } + my $total = ( keys %$res ); if ( my $group = $req->params('groupBy') ) { diff --git a/lemonldap-ng-manager/site/coffee/sfa.coffee b/lemonldap-ng-manager/site/coffee/sfa.coffee index 8e35e46c3..d569369b1 100644 --- a/lemonldap-ng-manager/site/coffee/sfa.coffee +++ b/lemonldap-ng-manager/site/coffee/sfa.coffee @@ -109,10 +109,23 @@ menu = home: [] ### -# AngularJS application +# AngularJS applications ### llapp = angular.module 'llngSessionsExplorer', ['ui.tree', 'ui.bootstrap', 'llApp'] + +# Filter 2FA sessions controller +llapp.controller 'SessionsExplorerFilter', ['$scope', '$location', '$q', '$http', ($scope, $location, $q, $http) -> + $scope.filter2FA = -> + $http.get("#{scriptname}sfa/persistent?groupBy=substr(_session_uid,1)&U2FCheck=#{$scope.U2FCheck}&TOTPCheck=#{$scope.TOTPCheck}").then (response) -> + + $scope.waiting = true + , (resp) -> + $scope.waiting = false + $scope.updateTree '', $scope.data, 0, 0 +] + + # Main controller llapp.controller 'SessionsExplorerCtrl', ['$scope', '$translator', '$location', '$q', '$http', ($scope, $translator, $location, $q, $http) -> $scope.links = links @@ -151,11 +164,11 @@ llapp.controller 'SessionsExplorerCtrl', ['$scope', '$translator', '$location', console.log typeof button.action $scope.showM = false - # SESSION MANAGEMENT + # SESSIONS MANAGEMENT # Delete U2F key $scope.deleteU2FKey = -> $scope.waiting = true - $http['delete']("#{scriptname}sfa/#{sessionType}/#{$scope.currentSession.id}?Key=U2F").then (response) -> + $http['delete']("#{scriptname}sfa/#{$scope.currentSession.id}?Key=U2F").then (response) -> $scope.currentSession = null $scope.currentScope.remove() $scope.waiting = false diff --git a/lemonldap-ng-manager/site/htdocs/static/js/sessions.js b/lemonldap-ng-manager/site/htdocs/static/js/sessions.js index cf3a10ec3..8b71ec9ed 100644 --- a/lemonldap-ng-manager/site/htdocs/static/js/sessions.js +++ b/lemonldap-ng-manager/site/htdocs/static/js/sessions.js @@ -1,4 +1,4 @@ -// Generated by CoffeeScript 1.12.7 +// Generated by CoffeeScript 1.9.3 /* * Session explorer @@ -227,8 +227,8 @@ session[key] = $scope.localeDate(value); } else if (key.match(/^(_startTime|_updateTime)$/)) { session[key] = _stToStr(value); - } else if (key.match(/^(_u2fKeyHandle|_u2fUserKey)$/)) { - session[key] = '########'; + } else if (key.match(/^(_u2fKeyHandle|_u2fUserKey|_totp2fSecret)$/)) { + session[key] = '##########'; } } } diff --git a/lemonldap-ng-manager/site/htdocs/static/js/sessions.min.js b/lemonldap-ng-manager/site/htdocs/static/js/sessions.min.js index 9a3cbbe27..1a9608c62 100644 --- a/lemonldap-ng-manager/site/htdocs/static/js/sessions.min.js +++ b/lemonldap-ng-manager/site/htdocs/static/js/sessions.min.js @@ -1 +1 @@ -(function(){var c,e,d,b,g,f,a;b=25;a={_whatToTrace:[function(i,h){return"groupBy=substr("+i+",1)"},function(i,h){return i+"="+h+"*&groupBy="+i},function(i,h){return i+"="+h}],ipAddr:[function(i,h){return"groupBy=net("+i+",16,1)"},function(i,h){if(!h.match(/:/)){h=h+"."}return i+"="+h+"*&groupBy=net("+i+",32,2)"},function(i,h){if(!h.match(/:/)){h=h+"."}return i+"="+h+"*&groupBy=net("+i+",48,3)"},function(i,h){if(!h.match(/:/)){h=h+"."}return i+"="+h+"*&groupBy=net("+i+",128,4)"},function(i,h){return i+"="+h+"&groupBy=_whatToTrace"},function(i,h,j){return j.replace(/\&groupBy.*$/,"")+("&_whatToTrace="+h)}],_startTime:[function(i,h){return"groupBy=substr("+i+",8)"},function(i,h){return i+"="+h+"*&groupBy=substr("+i+",10)"},function(i,h){return i+"="+h+"*&groupBy=substr("+i+",11)"},function(i,h){return i+"="+h+"*&groupBy=substr("+i+",12)"},function(i,h){return i+"="+h+"*&groupBy=_whatToTrace"},function(i,h,j){console.log(i);console.log(h);console.log(j);return j.replace(/\&groupBy.*$/,"")+("&_whatToTrace="+h)}],doubleIp:[function(i,h){return i},function(i,h){return"_whatToTrace="+h+"&groupBy=ipAddr"},function(i,h,j){return j.replace(/\&groupBy.*$/,"")+("&ipAddr="+h)}]};f={_whatToTrace:function(i,h,k,j){if(k===1){return i+"="+h+"*&groupBy=substr("+i+","+(k+j+1)+")"}else{return null}},ipAddr:function(i,h,k,j){if(k>0&&k<4){return i+"="+h+"*&groupBy=net("+i+","+(16*k+4*(j+1))+",2)"}else{return null}}};e="_password";c={dateTitle:["_utime","_startTime","_updateTime","_lastAuthnUTime","_lastSeen"],connectionTitle:["ipAddr","_timezone","_url"],authenticationTitle:["_session_id","_user","_password","authenticationLevel"],modulesTitle:["_auth","_userDB","_passwordDB","_issuerDB","_authChoice","_authMulti","_userDBMulti"],saml:["_idp","_idpConfKey","_samlToken","_lassoSessionDump","_lassoIdentityDump"],groups:["groups","hGroups"],ldap:["dn"],BrowserID:["_browserIdAnswer","_browserIdAnswerRaw"],OpenIDConnect:["_oidc_id_token","_oidc_OP","_oidc_access_token"]};g={session:[{title:"deleteSession",icon:"trash"}],home:[]};d=angular.module("llngSessionsExplorer",["ui.tree","ui.bootstrap","llApp"]);d.controller("SessionsExplorerCtrl",["$scope","$translator","$location","$q","$http",function(p,h,i,j,m){var n,l,k,o;p.links=links;p.menulinks=menulinks;p.staticPrefix=staticPrefix;p.scriptname=scriptname;p.formPrefix=formPrefix;p.availableLanguages=availableLanguages;p.waiting=true;p.showM=false;p.showT=true;p.data=[];p.currentScope=null;p.currentSession=null;p.menu=g;p.translateP=h.translateP;p.translate=h.translate;p.translateTitle=function(q){return h.translateField(q,"title")};o="global";p.menuClick=function(q){if(q.popup){window.open(q.popup)}else{if(!q.action){q.action=q.title}switch(typeof q.action){case"function":q.action(p.currentNode,p);break;case"string":p[q.action]();break;default:console.log(typeof q.action)}}return p.showM=false};p.deleteSession=function(){p.waiting=true;return m["delete"](scriptname+"sessions/"+o+"/"+p.currentSession.id).then(function(q){p.currentSession=null;p.currentScope.remove();return p.waiting=false},function(q){p.currentSession=null;p.currentScope.remove();return p.waiting=false})};p.stoggle=function(q){var r;r=q.$modelValue;if(r.nodes.length===0){p.updateTree(r.value,r.nodes,r.level,r.over,r.query,r.count)}return q.toggle()};p.displaySession=function(r){var s,q;q=function(t){var y,A,E,C,G,J,B,I,H,O,F,K,x,w,u,z,N,M,v,L,D;A=function(P){return P};y=function(S,U){var Q,R,P,T;P=[];R=new RegExp(S);for(Q in t){T=t[Q];if(Q.match(R)&&T){P.push({title:Q,value:T});delete t[Q]}}if(P.length>0){return N.push({title:U,nodes:P})}};v=t._utime;B=t._session_id;for(O in t){D=t[O];if(!D){delete t[O]}else{if(typeof t==="string"&&D.match(/; /)){t[O]=D.split("; ")}if(typeof t[O]!=="object"){if(e.match(new RegExp("\b"+O+"\b"))){t[O]="********"}else{if(O.match(/^(_utime|_lastAuthnUTime|_lastSeen|notification)$/)){t[O]=p.localeDate(D)}else{if(O.match(/^(_startTime|_updateTime)$/)){t[O]=A(D)}else{if(O.match(/^(_u2fKeyHandle|_u2fUserKey)$/)){t[O]="########"}}}}}}}N=[];for(G in c){C=c[G];M=[];for(J=0,K=C.length;J0){N.push({title:"__"+G+"__",nodes:M})}}y("^openid","OpenID");y("^notification_(.+)","__notificationsDone__");if(t._loginHistory){L=[];if(t._loginHistory.successLogin){u=t._loginHistory.successLogin;for(I=0,x=u.length;IP.title){return 1}else{if(Q.titleb&&f[p.type]){if(t=f[p.type](p.type,y,q,v,x)){v++;w=t;q=q-1}else{v=0}}else{v=0}return m.get(scriptname+"sessions/"+o+"?"+w).then(function(A){var D,B,z,E,C;D=A.data;if(D.result){C=D.values;for(B=0,z=C.length;B0&&k<4){return i+"="+h+"*&groupBy=net("+i+","+(16*k+4*(j+1))+",2)"}else{return null}}};e="_password";c={dateTitle:["_utime","_startTime","_updateTime","_lastAuthnUTime","_lastSeen"],connectionTitle:["ipAddr","_timezone","_url"],authenticationTitle:["_session_id","_user","_password","authenticationLevel"],modulesTitle:["_auth","_userDB","_passwordDB","_issuerDB","_authChoice","_authMulti","_userDBMulti"],saml:["_idp","_idpConfKey","_samlToken","_lassoSessionDump","_lassoIdentityDump"],groups:["groups","hGroups"],ldap:["dn"],BrowserID:["_browserIdAnswer","_browserIdAnswerRaw"],OpenIDConnect:["_oidc_id_token","_oidc_OP","_oidc_access_token"]};g={session:[{title:"deleteSession",icon:"trash"}],home:[]};d=angular.module("llngSessionsExplorer",["ui.tree","ui.bootstrap","llApp"]);d.controller("SessionsExplorerCtrl",["$scope","$translator","$location","$q","$http",function(p,h,i,j,m){var n,l,k,o;p.links=links;p.menulinks=menulinks;p.staticPrefix=staticPrefix;p.scriptname=scriptname;p.formPrefix=formPrefix;p.availableLanguages=availableLanguages;p.waiting=true;p.showM=false;p.showT=true;p.data=[];p.currentScope=null;p.currentSession=null;p.menu=g;p.translateP=h.translateP;p.translate=h.translate;p.translateTitle=function(q){return h.translateField(q,"title")};o="global";p.menuClick=function(q){if(q.popup){window.open(q.popup)}else{if(!q.action){q.action=q.title}switch(typeof q.action){case"function":q.action(p.currentNode,p);break;case"string":p[q.action]();break;default:console.log(typeof q.action)}}return p.showM=false};p.deleteSession=function(){p.waiting=true;return m["delete"](scriptname+"sessions/"+o+"/"+p.currentSession.id).then(function(q){p.currentSession=null;p.currentScope.remove();return p.waiting=false},function(q){p.currentSession=null;p.currentScope.remove();return p.waiting=false})};p.stoggle=function(q){var r;r=q.$modelValue;if(r.nodes.length===0){p.updateTree(r.value,r.nodes,r.level,r.over,r.query,r.count)}return q.toggle()};p.displaySession=function(r){var s,q;q=function(t){var y,A,E,C,G,J,B,I,H,O,F,K,x,w,u,z,N,M,v,L,D;A=function(P){return P};y=function(S,U){var Q,R,P,T;P=[];R=new RegExp(S);for(Q in t){T=t[Q];if(Q.match(R)&&T){P.push({title:Q,value:T});delete t[Q]}}if(P.length>0){return N.push({title:U,nodes:P})}};v=t._utime;B=t._session_id;for(O in t){D=t[O];if(!D){delete t[O]}else{if(typeof t==="string"&&D.match(/; /)){t[O]=D.split("; ")}if(typeof t[O]!=="object"){if(e.match(new RegExp("\b"+O+"\b"))){t[O]="********"}else{if(O.match(/^(_utime|_lastAuthnUTime|_lastSeen|notification)$/)){t[O]=p.localeDate(D)}else{if(O.match(/^(_startTime|_updateTime)$/)){t[O]=A(D)}else{if(O.match(/^(_u2fKeyHandle|_u2fUserKey|_totp2fSecret)$/)){t[O]="##########"}}}}}}}N=[];for(G in c){C=c[G];M=[];for(J=0,K=C.length;J0){N.push({title:"__"+G+"__",nodes:M})}}y("^openid","OpenID");y("^notification_(.+)","__notificationsDone__");if(t._loginHistory){L=[];if(t._loginHistory.successLogin){u=t._loginHistory.successLogin;for(I=0,x=u.length;IP.title){return 1}else{if(Q.titleb&&f[p.type]){if(t=f[p.type](p.type,y,q,v,x)){v++;w=t;q=q-1}else{v=0}}else{v=0}return m.get(scriptname+"sessions/"+o+"?"+w).then(function(A){var D,B,z,E,C;D=A.data;if(D.result){C=D.values;for(B=0,z=C.length;B0&&m<4){return k+"="+j+"*&groupBy=net("+k+","+(16*m+4*(l+1))+",2)"}else{return null}}};f="_password";c={dateTitle:["_utime","_startTime","_updateTime","_lastAuthnUTime","_lastSeen"],connectionTitle:["ipAddr","_timezone","_url"],authenticationTitle:["_session_id","_user","_password","authenticationLevel"],modulesTitle:["_auth","_userDB","_passwordDB","_issuerDB","_authChoice","_authMulti","_userDBMulti"],saml:["_idp","_idpConfKey","_samlToken","_lassoSessionDump","_lassoIdentityDump"],groups:["groups","hGroups"],ldap:["dn"],BrowserID:["_browserIdAnswer","_browserIdAnswerRaw"],OpenIDConnect:["_oidc_id_token","_oidc_OP","_oidc_access_token"]};a={delU2FKey:[{title:"deleteU2FKey",icon:"trash"}],addU2FKey:[{title:"addU2FKey",icon:"plus"}],verifyU2FKey:[{title:"verifyU2FKey",icon:"check"}],delTOTPKey:[{title:"deleteTOTPKey",icon:"trash"}],addTOTPKey:[{title:"addTOTPKey",icon:"plus"}],verifyTOTPKey:[{title:"verifyTOTPKey",icon:"check"}],home:[]};g=angular.module("llngSessionsExplorer",["ui.tree","ui.bootstrap","llApp"]);g.controller("SessionsExplorerCtrl",["$scope","$translator","$location","$q","$http",function(r,j,k,l,o){var p,n,m,q;r.links=links;r.menulinks=menulinks;r.staticPrefix=staticPrefix;r.scriptname=scriptname;r.formPrefix=formPrefix;r.availableLanguages=availableLanguages;r.waiting=true;r.showM=false;r.showT=true;r.data=[];r.currentScope=null;r.currentSession=null;r.menu=a;r.translateP=j.translateP;r.translate=j.translate;r.translateTitle=function(s){return j.translateField(s,"title")};q="global";r.menuClick=function(s){if(s.popup){window.open(s.popup)}else{if(!s.action){s.action=s.title}switch(typeof s.action){case"function":s.action(r.currentNode,r);break;case"string":r[s.action]();break;default:console.log(typeof s.action)}}return r.showM=false};r.deleteU2FKey=function(){r.waiting=true;o["delete"](scriptname+"sfa/"+q+"/"+r.currentSession.id+"?Key=U2F").then(function(s){r.currentSession=null;r.currentScope.remove();return r.waiting=false},function(s){r.currentSession=null;r.currentScope.remove();return r.waiting=false});return r.showT=false};r.deleteTOTPKey=function(){r.waiting=true;o["delete"](scriptname+"sfa/"+q+"/"+r.currentSession.id+"?Key=TOTP").then(function(s){r.currentSession=null;r.currentScope.remove();return r.waiting=false},function(s){r.currentSession=null;r.currentScope.remove();return r.waiting=false});return r.showT=false};r.addU2FKey=function(){r.waiting=true;o.put(scriptname+"sfa/"+q+"/"+r.currentSession.id+"?Key=U2F").then(function(s){r.currentSession=null;r.currentScope.remove();return r.waiting=false},function(s){r.currentSession=null;r.currentScope.remove();return r.waiting=false});return r.showT=false};r.addTOTPKey=function(){r.waiting=true;o.put(scriptname+"sfa/"+q+"/"+r.currentSession.id+"?Key=TOTP").then(function(s){r.currentSession=null;r.currentScope.remove();return r.waiting=false},function(s){r.currentSession=null;r.currentScope.remove();return r.waiting=false});return r.showT=false};r.verifyU2FKey=function(){r.waiting=true;o.post(scriptname+"sfa/"+q+"/"+r.currentSession.id+"?Key=U2F").then(function(s){r.currentSession=null;r.currentScope.remove();return r.waiting=false},function(s){r.currentSession=null;r.currentScope.remove();return r.waiting=false});return r.showT=true};r.verifyTOTPKey=function(){r.waiting=true;o.post(scriptname+"sfa/"+q+"/"+r.currentSession.id+"?Key=TOTP").then(function(s){r.currentSession=null;r.currentScope.remove();return r.waiting=false},function(s){r.currentSession=null;r.currentScope.remove();return r.waiting=false});return r.showT=true};r.stoggle=function(s){var t;t=s.$modelValue;if(t.nodes.length===0){r.updateTree(t.value,t.nodes,t.level,t.over,t.query,t.count)}return s.toggle()};r.displaySession=function(t){var u,s;s=function(v){var A,C,G,E,J,L,D,K,Q,I,M,z,y,H,w,B,P,O,x,N,F;C=function(R){return R};A=function(U,W){var S,T,R,V;R=[];T=new RegExp(U);for(S in v){V=v[S];if(S.match(T)&&V){R.push({title:S,value:V});delete v[S]}}if(R.length>0){return P.push({title:W,nodes:R})}};x=v._utime;D=v._session_id;for(Q in v){F=v[Q];if(!F){delete v[Q]}else{if(typeof v==="string"&&F.match(/; /)){v[Q]=F.split("; ")}if(typeof v[Q]!=="object"){if(f.match(new RegExp("\b"+Q+"\b"))){v[Q]="********"}else{if(Q.match(/^(_utime|_lastAuthnUTime|_lastSeen|notification)$/)){v[Q]=r.localeDate(F)}else{if(Q.match(/^(_startTime|_updateTime)$/)){v[Q]=C(F)}else{if(Q.match(/^(_u2fKeyHandle|_u2fUserKey|_totp2fSecret)$/)){v[Q]="##########"}}}}}}}P=[];for(J in c){E=c[J];O=[];for(L=0,M=E.length;L0){P.push({title:"__"+J+"__",nodes:O})}}A("^openid","OpenID");A("^notification_(.+)","__notificationsDone__");if(v._loginHistory){N=[];if(v._loginHistory.successLogin){w=v._loginHistory.successLogin;for(K=0,z=w.length;KR.title){return 1}else{if(S.titleh&&e[r.type]){if(v=e[r.type](r.type,A,s,x,z)){x++;y=v;s=s-1}else{x=0}}else{x=0}return o.get(scriptname+"sfa/"+q+"?"+y).then(function(C){var F,D,B,G,E;F=C.data;if(F.result){E=F.values;for(D=0,B=E.length;D0&&m<4){return k+"="+j+"*&groupBy=net("+k+","+(16*m+4*(l+1))+",2)"}else{return null}}};f="_password";c={dateTitle:["_utime","_startTime","_updateTime","_lastAuthnUTime","_lastSeen"],connectionTitle:["ipAddr","_timezone","_url"],authenticationTitle:["_session_id","_user","_password","authenticationLevel"],modulesTitle:["_auth","_userDB","_passwordDB","_issuerDB","_authChoice","_authMulti","_userDBMulti"],saml:["_idp","_idpConfKey","_samlToken","_lassoSessionDump","_lassoIdentityDump"],groups:["groups","hGroups"],ldap:["dn"],BrowserID:["_browserIdAnswer","_browserIdAnswerRaw"],OpenIDConnect:["_oidc_id_token","_oidc_OP","_oidc_access_token"]};a={delU2FKey:[{title:"deleteU2FKey",icon:"trash"}],addU2FKey:[{title:"addU2FKey",icon:"plus"}],verifyU2FKey:[{title:"verifyU2FKey",icon:"check"}],delTOTPKey:[{title:"deleteTOTPKey",icon:"trash"}],addTOTPKey:[{title:"addTOTPKey",icon:"plus"}],verifyTOTPKey:[{title:"verifyTOTPKey",icon:"check"}],home:[]};g=angular.module("llngSessionsExplorer",["ui.tree","ui.bootstrap","llApp"]);g.controller("SessionsExplorerFilter",["$scope","$location","$q","$http",function(k,m,j,l){return k.filter2FA=function(){l.get(scriptname+"sfa/persistent?groupBy=substr(_session_uid,1)&U2FCheck="+k.U2FCheck+"&TOTPCheck="+k.TOTPCheck).then(function(n){return k.waiting=true},function(n){return k.waiting=false});return k.updateTree("",k.data,0,0)}}]);g.controller("SessionsExplorerCtrl",["$scope","$translator","$location","$q","$http",function(r,j,k,l,o){var p,n,m,q;r.links=links;r.menulinks=menulinks;r.staticPrefix=staticPrefix;r.scriptname=scriptname;r.formPrefix=formPrefix;r.availableLanguages=availableLanguages;r.waiting=true;r.showM=false;r.showT=true;r.data=[];r.currentScope=null;r.currentSession=null;r.menu=a;r.translateP=j.translateP;r.translate=j.translate;r.translateTitle=function(s){return j.translateField(s,"title")};q="global";r.menuClick=function(s){if(s.popup){window.open(s.popup)}else{if(!s.action){s.action=s.title}switch(typeof s.action){case"function":s.action(r.currentNode,r);break;case"string":r[s.action]();break;default:console.log(typeof s.action)}}return r.showM=false};r.deleteU2FKey=function(){r.waiting=true;o["delete"](scriptname+"sfa/"+r.currentSession.id+"?Key=U2F").then(function(s){r.currentSession=null;r.currentScope.remove();return r.waiting=false},function(s){r.currentSession=null;r.currentScope.remove();return r.waiting=false});return r.showT=false};r.deleteTOTPKey=function(){r.waiting=true;o["delete"](scriptname+"sfa/"+q+"/"+r.currentSession.id+"?Key=TOTP").then(function(s){r.currentSession=null;r.currentScope.remove();return r.waiting=false},function(s){r.currentSession=null;r.currentScope.remove();return r.waiting=false});return r.showT=false};r.addU2FKey=function(){r.waiting=true;o.put(scriptname+"sfa/"+q+"/"+r.currentSession.id+"?Key=U2F").then(function(s){r.currentSession=null;r.currentScope.remove();return r.waiting=false},function(s){r.currentSession=null;r.currentScope.remove();return r.waiting=false});return r.showT=false};r.addTOTPKey=function(){r.waiting=true;o.put(scriptname+"sfa/"+q+"/"+r.currentSession.id+"?Key=TOTP").then(function(s){r.currentSession=null;r.currentScope.remove();return r.waiting=false},function(s){r.currentSession=null;r.currentScope.remove();return r.waiting=false});return r.showT=false};r.verifyU2FKey=function(){r.waiting=true;o.post(scriptname+"sfa/"+q+"/"+r.currentSession.id+"?Key=U2F").then(function(s){r.currentSession=null;r.currentScope.remove();return r.waiting=false},function(s){r.currentSession=null;r.currentScope.remove();return r.waiting=false});return r.showT=true};r.verifyTOTPKey=function(){r.waiting=true;o.post(scriptname+"sfa/"+q+"/"+r.currentSession.id+"?Key=TOTP").then(function(s){r.currentSession=null;r.currentScope.remove();return r.waiting=false},function(s){r.currentSession=null;r.currentScope.remove();return r.waiting=false});return r.showT=true};r.stoggle=function(s){var t;t=s.$modelValue;if(t.nodes.length===0){r.updateTree(t.value,t.nodes,t.level,t.over,t.query,t.count)}return s.toggle()};r.displaySession=function(t){var u,s;s=function(v){var A,C,G,E,J,L,D,K,Q,I,M,z,y,H,w,B,P,O,x,N,F;C=function(R){return R};A=function(U,W){var S,T,R,V;R=[];T=new RegExp(U);for(S in v){V=v[S];if(S.match(T)&&V){R.push({title:S,value:V});delete v[S]}}if(R.length>0){return P.push({title:W,nodes:R})}};x=v._utime;D=v._session_id;for(Q in v){F=v[Q];if(!F){delete v[Q]}else{if(typeof v==="string"&&F.match(/; /)){v[Q]=F.split("; ")}if(typeof v[Q]!=="object"){if(f.match(new RegExp("\b"+Q+"\b"))){v[Q]="********"}else{if(Q.match(/^(_utime|_lastAuthnUTime|_lastSeen|notification)$/)){v[Q]=r.localeDate(F)}else{if(Q.match(/^(_startTime|_updateTime)$/)){v[Q]=C(F)}else{if(Q.match(/^(_u2fKeyHandle|_u2fUserKey|_totp2fSecret)$/)){v[Q]="##########"}}}}}}}P=[];for(J in c){E=c[J];O=[];for(L=0,M=E.length;L0){P.push({title:"__"+J+"__",nodes:O})}}A("^openid","OpenID");A("^notification_(.+)","__notificationsDone__");if(v._loginHistory){N=[];if(v._loginHistory.successLogin){w=v._loginHistory.successLogin;for(K=0,z=w.length;KR.title){return 1}else{if(S.titleh&&e[r.type]){if(v=e[r.type](r.type,A,s,x,z)){x++;y=v;s=s-1}else{x=0}}else{x=0}return o.get(scriptname+"sfa/"+q+"?"+y).then(function(C){var F,D,B,G,E;F=C.data;if(F.result){E=F.values;for(D=0,B=E.length;D