environments/ppa-mbqj77/deployments/1
parent
7284d0308f
commit
71b4c96ef5
@ -1,473 +0,0 @@ |
||||
### |
||||
# 2ndFA Session explorer |
||||
### |
||||
|
||||
|
||||
setMsg = (msg, level) -> |
||||
$('#msg').html window.translate msg |
||||
$('#color').removeClass 'message-positive message-warning alert-success alert-warning' |
||||
$('#color').addClass "message-#{level}" |
||||
level = 'success' if level == 'positive' |
||||
$('#color').addClass "alert-#{level}" |
||||
|
||||
displayError = (j, status, err) -> |
||||
console.log 'Error', err |
||||
res = JSON.parse j.responseText |
||||
if res and res.error |
||||
res = res.error.replace /.* /, '' |
||||
console.log 'Returned error', res |
||||
setMsg res, 'warning' |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Max number of session to display (see overScheme) |
||||
max = 25 |
||||
|
||||
# Queries to do each type of display: each array item corresponds to the depth |
||||
# of opened nodes in the tree |
||||
schemes = |
||||
_whatToTrace: [ |
||||
(t,v) -> |
||||
"groupBy=substr(#{t},1)" |
||||
(t,v) -> |
||||
"#{t}=#{v}*&groupBy=#{t}" |
||||
(t,v) -> |
||||
"#{t}=#{v}" |
||||
] |
||||
_startTime: [ |
||||
(t,v) -> |
||||
"groupBy=substr(#{t},8)" |
||||
(t,v) -> |
||||
"#{t}=#{v}*&groupBy=substr(#{t},10)" |
||||
(t,v) -> |
||||
"#{t}=#{v}*&groupBy=substr(#{t},11)" |
||||
(t,v) -> |
||||
"#{t}=#{v}*&groupBy=substr(#{t},12)" |
||||
(t,v) -> |
||||
"#{t}=#{v}*&groupBy=_whatToTrace" |
||||
(t,v,q) -> |
||||
console.log t |
||||
console.log v |
||||
console.log q |
||||
q.replace(/\&groupBy.*$/, '') + "&_whatToTrace=#{v}" |
||||
] |
||||
|
||||
overScheme = |
||||
_whatToTrace: (t,v,level,over) -> |
||||
if level == 1 |
||||
"#{t}=#{v}*&groupBy=substr(#{t},#{(level+over+1)})" |
||||
else |
||||
null |
||||
ipAddr: (t,v,level,over) -> |
||||
if level > 0 and level < 4 |
||||
"#{t}=#{v}*&groupBy=net(#{t},#{16*level+4*(over+1)},2)" |
||||
else |
||||
null |
||||
|
||||
hiddenAttributes = '_password' |
||||
|
||||
# Attributes to group in session display |
||||
categories = |
||||
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'] |
||||
|
||||
# Menu entries |
||||
menu = |
||||
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: [] |
||||
|
||||
### |
||||
# 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.U2FCheck = 1 |
||||
$scope.TOTPCheck = 1 |
||||
$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 |
||||
$scope.menulinks = menulinks |
||||
$scope.staticPrefix = staticPrefix |
||||
$scope.scriptname = scriptname |
||||
$scope.formPrefix = formPrefix |
||||
$scope.availableLanguages = availableLanguages |
||||
$scope.waiting = true |
||||
$scope.showM = false |
||||
$scope.showT = true |
||||
$scope.data = [] |
||||
$scope.currentScope = null |
||||
$scope.currentSession = null |
||||
$scope.menu = menu |
||||
|
||||
# Import translations functions |
||||
$scope.translateP = $translator.translateP |
||||
$scope.translate = $translator.translate |
||||
$scope.translateTitle = (node) -> |
||||
$translator.translateField node, 'title' |
||||
sessionType = 'global' |
||||
|
||||
# Handle menu items |
||||
$scope.menuClick = (button) -> |
||||
if button.popup |
||||
window.open button.popup |
||||
else |
||||
button.action = button.title unless button.action |
||||
switch typeof button.action |
||||
when 'function' |
||||
button.action $scope.currentNode, $scope |
||||
when 'string' |
||||
$scope[button.action]() |
||||
else |
||||
console.log typeof button.action |
||||
$scope.showM = false |
||||
|
||||
# SESSIONS MANAGEMENT |
||||
# Delete U2F key |
||||
$scope.deleteU2FKey = -> |
||||
$scope.waiting = true |
||||
$http['delete']("#{scriptname}sfa/#{sessionType}/#{$scope.currentSession.id}?Key=U2F").then (response) -> |
||||
$scope.currentSession = null |
||||
$scope.currentScope.remove() |
||||
$scope.waiting = false |
||||
, (resp) -> |
||||
$scope.currentSession = null |
||||
$scope.currentScope.remove() |
||||
$scope.waiting = false |
||||
$scope.showT = false |
||||
|
||||
# Delete TOTP key |
||||
$scope.deleteTOTPKey = -> |
||||
$scope.waiting = true |
||||
$http['delete']("#{scriptname}sfa/#{sessionType}/#{$scope.currentSession.id}?Key=TOTP").then (response) -> |
||||
$scope.currentSession = null |
||||
$scope.currentScope.remove() |
||||
$scope.waiting = false |
||||
, (resp) -> |
||||
$scope.currentSession = null |
||||
$scope.currentScope.remove() |
||||
$scope.waiting = false |
||||
$scope.showT = false |
||||
|
||||
# Add U2F key |
||||
$scope.addU2FKey = -> |
||||
$scope.waiting = true |
||||
$http['put']("#{scriptname}sfa/#{sessionType}/#{$scope.currentSession.id}?Key=U2F").then (response) -> |
||||
$scope.currentSession = null |
||||
$scope.currentScope.remove() |
||||
$scope.waiting = false |
||||
, (resp) -> |
||||
$scope.currentSession = null |
||||
$scope.currentScope.remove() |
||||
$scope.waiting = false |
||||
$scope.showT = false |
||||
|
||||
# Add TOTP key |
||||
$scope.addTOTPKey = -> |
||||
$scope.waiting = true |
||||
$http['put']("#{scriptname}sfa/#{sessionType}/#{$scope.currentSession.id}?Key=TOTP").then (response) -> |
||||
$scope.currentSession = null |
||||
$scope.currentScope.remove() |
||||
$scope.waiting = false |
||||
, (resp) -> |
||||
$scope.currentSession = null |
||||
$scope.currentScope.remove() |
||||
$scope.waiting = false |
||||
$scope.showT = false |
||||
|
||||
# Verify U2F key |
||||
$scope.verifyU2FKey = -> |
||||
$scope.waiting = true |
||||
$http['post']("#{scriptname}sfa/#{sessionType}/#{$scope.currentSession.id}?Key=U2F").then (response) -> |
||||
$scope.currentSession = null |
||||
$scope.currentScope.remove() |
||||
$scope.waiting = false |
||||
, (resp) -> |
||||
$scope.currentSession = null |
||||
$scope.currentScope.remove() |
||||
$scope.waiting = false |
||||
$scope.showT = true |
||||
|
||||
# Verify TOTP key |
||||
$scope.verifyTOTPKey = -> |
||||
$scope.waiting = true |
||||
$http['post']("#{scriptname}sfa/#{sessionType}/#{$scope.currentSession.id}?Key=TOTP").then (response) -> |
||||
$scope.currentSession = null |
||||
$scope.currentScope.remove() |
||||
$scope.waiting = false |
||||
, (resp) -> |
||||
$scope.currentSession = null |
||||
$scope.currentScope.remove() |
||||
$scope.waiting = false |
||||
$scope.showT = true |
||||
|
||||
# Open node |
||||
$scope.stoggle = (scope) -> |
||||
node = scope.$modelValue |
||||
if node.nodes.length == 0 |
||||
$scope.updateTree node.value, node.nodes, node.level, node.over, node.query, node.count |
||||
scope.toggle() |
||||
|
||||
# Display selected session |
||||
$scope.displaySession = (scope) -> |
||||
|
||||
# Private functions |
||||
|
||||
# Session preparation |
||||
transformSession = (session) -> |
||||
_stToStr = (s) -> |
||||
s |
||||
_insert = (re, title) -> |
||||
tmp = [] |
||||
reg = new RegExp(re) |
||||
for key,value of session |
||||
if key.match(reg) and value |
||||
tmp.push |
||||
title: key |
||||
value: value |
||||
delete session[key] |
||||
if tmp.length > 0 |
||||
res.push |
||||
title: title |
||||
nodes: tmp |
||||
time = session._utime |
||||
id = session._session_id |
||||
|
||||
# 1. Replace values if needed |
||||
for key, value of session |
||||
unless value |
||||
delete session[key] |
||||
else |
||||
if typeof session == 'string' and value.match(/; /) |
||||
session[key] = value.split '; ' |
||||
if typeof session[key] != 'object' |
||||
if hiddenAttributes.match(new RegExp('\b' + key + '\b')) |
||||
session[key] = '********' |
||||
else if key.match /^(_utime|_lastAuthnUTime|_lastSeen|notification)$/ |
||||
session[key] = $scope.localeDate value |
||||
else if key.match /^(_startTime|_updateTime)$/ |
||||
session[key] = _stToStr value |
||||
else if key.match /^(_u2fKeyHandle|_u2fUserKey|_totp2fSecret)$/ |
||||
session[key] = '##########' |
||||
|
||||
res = [] |
||||
|
||||
# 2. Push session keys in result, grouped by categories |
||||
for category, attrs of categories |
||||
subres = [] |
||||
for attr in attrs |
||||
if session[attr] |
||||
subres.push |
||||
title: attr |
||||
value: session[attr] |
||||
delete session[attr] |
||||
if subres.length >0 |
||||
res.push |
||||
title: "__#{category}__" |
||||
nodes: subres |
||||
|
||||
# 3. Add OpenID and notifications already notified |
||||
_insert '^openid', 'OpenID' |
||||
_insert '^notification_(.+)', '__notificationsDone__' |
||||
|
||||
# 4. Add session history if exists |
||||
if session._loginHistory |
||||
tmp = [] |
||||
if session._loginHistory.successLogin |
||||
for l in session._loginHistory.successLogin |
||||
tmp.push |
||||
t: l._utime |
||||
title: $scope.localeDate l._utime |
||||
value: "Success (IP #{l.ipAddr})" |
||||
if session._loginHistory.failedLogin |
||||
for l in session._loginHistory.failedLogin |
||||
tmp.push |
||||
t: l._utime |
||||
title: $scope.localeDate l._utime |
||||
value: "#{l.error} (IP #{l.ipAddr})" |
||||
delete session._loginHistory |
||||
tmp.sort (a,b) -> |
||||
a.t - b.t |
||||
res.push |
||||
title: '__loginHistory__' |
||||
nodes: tmp |
||||
|
||||
# 5. Other keys (attributes and macros) |
||||
tmp = [] |
||||
for key, value of session |
||||
tmp.push |
||||
title: key |
||||
value: value |
||||
tmp.sort (a,b) -> |
||||
if a.title > b.title then 1 |
||||
else if a.title < b.title then -1 |
||||
else 0 |
||||
|
||||
res.push |
||||
title: '__attributesAndMacros__' |
||||
nodes: tmp |
||||
return { |
||||
_utime: time |
||||
id: id |
||||
nodes: res |
||||
} |
||||
|
||||
$scope.currentScope = scope |
||||
sessionId = scope.$modelValue.session |
||||
$http.get("#{scriptname}sfa/#{sessionType}/#{sessionId}").then (response) -> |
||||
$scope.currentSession = transformSession response.data |
||||
$scope.showT = false |
||||
|
||||
$scope.localeDate = (s) -> |
||||
d = new Date(s * 1000) |
||||
return d.toLocaleString() |
||||
|
||||
# Function to change interface language |
||||
$scope.getLanguage = (lang) -> |
||||
$scope.lang = lang |
||||
$scope.form = 'white' |
||||
$scope.init() |
||||
$scope.showM = false |
||||
|
||||
# URI local path management |
||||
pathEvent = (event, next, current) -> |
||||
n = next.match /#\/(\w+)/ |
||||
sessionType = 'global' |
||||
if n == null |
||||
$scope.type = '_whatToTrace' |
||||
else if n[1].match /^(persistent)$/ |
||||
sessionType = RegExp.$1 |
||||
$scope.type = '_session_uid' |
||||
else |
||||
$scope.type = n[1] |
||||
$scope.init() |
||||
|
||||
$scope.$on '$locationChangeSuccess', pathEvent |
||||
|
||||
# Function to update tree: download value of opened subkey |
||||
autoId = 0 |
||||
$scope.updateTree = (value, node, level, over, currentQuery, count) -> |
||||
$scope.waiting = true |
||||
|
||||
# Query scheme selection: |
||||
|
||||
# - if defined above |
||||
scheme = if schemes[$scope.type] |
||||
schemes[$scope.type] |
||||
|
||||
# - _updateTime must be displayed as startDate |
||||
else if $scope.type == '_updateTime' |
||||
schemes._startTime |
||||
|
||||
# - default to _whatToTrace scheme |
||||
else |
||||
schemes._whatToTrace |
||||
|
||||
# Build query using schemes |
||||
query = scheme[level] $scope.type, value, currentQuery |
||||
|
||||
# If number of session exceeds "max" and overScheme exists, call it |
||||
if count > max and overScheme[$scope.type] |
||||
if tmp = overScheme[$scope.type] $scope.type, value, level, over, currentQuery |
||||
over++ |
||||
query = tmp |
||||
level = level - 1 |
||||
else |
||||
over = 0 |
||||
else |
||||
over = 0 |
||||
|
||||
# Launch HTTP query |
||||
$http.get("#{scriptname}sfa/#{sessionType}?#{query}").then (response) -> |
||||
data = response.data |
||||
if data.result |
||||
for n in data.values |
||||
autoId++ |
||||
n.id = "node#{autoId}" |
||||
if level < scheme.length - 1 |
||||
n.nodes = [] |
||||
n.level = level + 1 |
||||
n.query = query |
||||
n.over = over |
||||
|
||||
# Date display in tree |
||||
if $scope.type.match /^(?:start|update)Time$/ |
||||
n.title = n.value |
||||
# 12 digits -> 12:34 |
||||
.replace(/^(\d{8})(\d{2})(\d{2})$/,'$2:$3') |
||||
# 11 digits -> 12:30 |
||||
.replace(/^(\d{8})(\d{2})(\d)$/,'$2:$30') |
||||
# 10 digits -> 12h |
||||
.replace(/^(\d{8})(\d{2})$/,'$2h') |
||||
# 8 digits -> 2016-03-15 |
||||
.replace(/^(\d{4})(\d{2})(\d{2})/,'$1-$2-$3') |
||||
node.push n |
||||
$scope.total = data.total if value == '' |
||||
$scope.waiting = false |
||||
, (resp) -> |
||||
$scope.waiting = false |
||||
|
||||
# Intialization function |
||||
# Simply set $scope.waiting to false during $translator and tree root |
||||
# initialization |
||||
$scope.init = -> |
||||
$scope.waiting = true |
||||
$scope.data = [] |
||||
$q.all [ |
||||
$translator.init $scope.lang |
||||
$scope.updateTree '', $scope.data, 0, 0 |
||||
] |
||||
.then -> |
||||
$scope.waiting = false |
||||
, (resp) -> |
||||
$scope.waiting = false |
||||
|
||||
# Query scheme initialization |
||||
# Default to '_whatToTrace' |
||||
c = $location.path().match /^\/(\w+)/ |
||||
$scope.type = if c then c[1] else '_whatToTrace' |
||||
] |
||||
|
@ -1,511 +0,0 @@ |
||||
// Generated by CoffeeScript 1.9.3
|
||||
|
||||
/* |
||||
* 2ndFA Session explorer |
||||
*/ |
||||
|
||||
(function() { |
||||
var categories, displayError, hiddenAttributes, llapp, max, menu, overScheme, schemes, setMsg; |
||||
|
||||
setMsg = function(msg, level) { |
||||
$('#msg').html(window.translate(msg)); |
||||
$('#color').removeClass('message-positive message-warning alert-success alert-warning'); |
||||
$('#color').addClass("message-" + level); |
||||
if (level === 'positive') { |
||||
level = 'success'; |
||||
} |
||||
return $('#color').addClass("alert-" + level); |
||||
}; |
||||
|
||||
displayError = function(j, status, err) { |
||||
var res; |
||||
console.log('Error', err); |
||||
res = JSON.parse(j.responseText); |
||||
if (res && res.error) { |
||||
res = res.error.replace(/.* /, ''); |
||||
console.log('Returned error', res); |
||||
return setMsg(res, 'warning'); |
||||
} |
||||
}; |
||||
|
||||
max = 25; |
||||
|
||||
schemes = { |
||||
_whatToTrace: [ |
||||
function(t, v) { |
||||
return "groupBy=substr(" + t + ",1)"; |
||||
}, function(t, v) { |
||||
return t + "=" + v + "*&groupBy=" + t; |
||||
}, function(t, v) { |
||||
return t + "=" + v; |
||||
} |
||||
], |
||||
_startTime: [ |
||||
function(t, v) { |
||||
return "groupBy=substr(" + t + ",8)"; |
||||
}, function(t, v) { |
||||
return t + "=" + v + "*&groupBy=substr(" + t + ",10)"; |
||||
}, function(t, v) { |
||||
return t + "=" + v + "*&groupBy=substr(" + t + ",11)"; |
||||
}, function(t, v) { |
||||
return t + "=" + v + "*&groupBy=substr(" + t + ",12)"; |
||||
}, function(t, v) { |
||||
return t + "=" + v + "*&groupBy=_whatToTrace"; |
||||
}, function(t, v, q) { |
||||
console.log(t); |
||||
console.log(v); |
||||
console.log(q); |
||||
return q.replace(/\&groupBy.*$/, '') + ("&_whatToTrace=" + v); |
||||
} |
||||
] |
||||
}; |
||||
|
||||
overScheme = { |
||||
_whatToTrace: function(t, v, level, over) { |
||||
if (level === 1) { |
||||
return t + "=" + v + "*&groupBy=substr(" + t + "," + (level + over + 1) + ")"; |
||||
} else { |
||||
return null; |
||||
} |
||||
}, |
||||
ipAddr: function(t, v, level, over) { |
||||
if (level > 0 && level < 4) { |
||||
return t + "=" + v + "*&groupBy=net(" + t + "," + (16 * level + 4 * (over + 1)) + ",2)"; |
||||
} else { |
||||
return null; |
||||
} |
||||
} |
||||
}; |
||||
|
||||
hiddenAttributes = '_password'; |
||||
|
||||
categories = { |
||||
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'] |
||||
}; |
||||
|
||||
menu = { |
||||
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: [] |
||||
}; |
||||
|
||||
|
||||
/* |
||||
* AngularJS applications |
||||
*/ |
||||
|
||||
llapp = angular.module('llngSessionsExplorer', ['ui.tree', 'ui.bootstrap', 'llApp']); |
||||
|
||||
llapp.controller('SessionsExplorerFilter', [ |
||||
'$scope', '$location', '$q', '$http', function($scope, $location, $q, $http) { |
||||
$scope.U2FCheck = 1; |
||||
$scope.TOTPCheck = 1; |
||||
return $scope.filter2FA = function() { |
||||
$http.get(scriptname + "sfa/persistent?groupBy=substr(_session_uid,1)&U2FCheck=" + $scope.U2FCheck + "&TOTPCheck=" + $scope.TOTPCheck).then(function(response) { |
||||
return $scope.waiting = true; |
||||
}, function(resp) { |
||||
return $scope.waiting = false; |
||||
}); |
||||
return $scope.updateTree('', $scope.data, 0, 0); |
||||
}; |
||||
} |
||||
]); |
||||
|
||||
llapp.controller('SessionsExplorerCtrl', [ |
||||
'$scope', '$translator', '$location', '$q', '$http', function($scope, $translator, $location, $q, $http) { |
||||
var autoId, c, pathEvent, sessionType; |
||||
$scope.links = links; |
||||
$scope.menulinks = menulinks; |
||||
$scope.staticPrefix = staticPrefix; |
||||
$scope.scriptname = scriptname; |
||||
$scope.formPrefix = formPrefix; |
||||
$scope.availableLanguages = availableLanguages; |
||||
$scope.waiting = true; |
||||
$scope.showM = false; |
||||
$scope.showT = true; |
||||
$scope.data = []; |
||||
$scope.currentScope = null; |
||||
$scope.currentSession = null; |
||||
$scope.menu = menu; |
||||
$scope.translateP = $translator.translateP; |
||||
$scope.translate = $translator.translate; |
||||
$scope.translateTitle = function(node) { |
||||
return $translator.translateField(node, 'title'); |
||||
}; |
||||
sessionType = 'global'; |
||||
$scope.menuClick = function(button) { |
||||
if (button.popup) { |
||||
window.open(button.popup); |
||||
} else { |
||||
if (!button.action) { |
||||
button.action = button.title; |
||||
} |
||||
switch (typeof button.action) { |
||||
case 'function': |
||||
button.action($scope.currentNode, $scope); |
||||
break; |
||||
case 'string': |
||||
$scope[button.action](); |
||||
break; |
||||
default: |
||||
console.log(typeof button.action); |
||||
} |
||||
} |
||||
return $scope.showM = false; |
||||
}; |
||||
$scope.deleteU2FKey = function() { |
||||
$scope.waiting = true; |
||||
$http['delete'](scriptname + "sfa/" + sessionType + "/" + $scope.currentSession.id + "?Key=U2F").then(function(response) { |
||||
$scope.currentSession = null; |
||||
$scope.currentScope.remove(); |
||||
return $scope.waiting = false; |
||||
}, function(resp) { |
||||
$scope.currentSession = null; |
||||
$scope.currentScope.remove(); |
||||
return $scope.waiting = false; |
||||
}); |
||||
return $scope.showT = false; |
||||
}; |
||||
$scope.deleteTOTPKey = function() { |
||||
$scope.waiting = true; |
||||
$http['delete'](scriptname + "sfa/" + sessionType + "/" + $scope.currentSession.id + "?Key=TOTP").then(function(response) { |
||||
$scope.currentSession = null; |
||||
$scope.currentScope.remove(); |
||||
return $scope.waiting = false; |
||||
}, function(resp) { |
||||
$scope.currentSession = null; |
||||
$scope.currentScope.remove(); |
||||
return $scope.waiting = false; |
||||
}); |
||||
return $scope.showT = false; |
||||
}; |
||||
$scope.addU2FKey = function() { |
||||
$scope.waiting = true; |
||||
$http['put'](scriptname + "sfa/" + sessionType + "/" + $scope.currentSession.id + "?Key=U2F").then(function(response) { |
||||
$scope.currentSession = null; |
||||
$scope.currentScope.remove(); |
||||
return $scope.waiting = false; |
||||
}, function(resp) { |
||||
$scope.currentSession = null; |
||||
$scope.currentScope.remove(); |
||||
return $scope.waiting = false; |
||||
}); |
||||
return $scope.showT = false; |
||||
}; |
||||
$scope.addTOTPKey = function() { |
||||
$scope.waiting = true; |
||||
$http['put'](scriptname + "sfa/" + sessionType + "/" + $scope.currentSession.id + "?Key=TOTP").then(function(response) { |
||||
$scope.currentSession = null; |
||||
$scope.currentScope.remove(); |
||||
return $scope.waiting = false; |
||||
}, function(resp) { |
||||
$scope.currentSession = null; |
||||
$scope.currentScope.remove(); |
||||
return $scope.waiting = false; |
||||
}); |
||||
return $scope.showT = false; |
||||
}; |
||||
$scope.verifyU2FKey = function() { |
||||
$scope.waiting = true; |
||||
$http['post'](scriptname + "sfa/" + sessionType + "/" + $scope.currentSession.id + "?Key=U2F").then(function(response) { |
||||
$scope.currentSession = null; |
||||
$scope.currentScope.remove(); |
||||
return $scope.waiting = false; |
||||
}, function(resp) { |
||||
$scope.currentSession = null; |
||||
$scope.currentScope.remove(); |
||||
return $scope.waiting = false; |
||||
}); |
||||
return $scope.showT = true; |
||||
}; |
||||
$scope.verifyTOTPKey = function() { |
||||
$scope.waiting = true; |
||||
$http['post'](scriptname + "sfa/" + sessionType + "/" + $scope.currentSession.id + "?Key=TOTP").then(function(response) { |
||||
$scope.currentSession = null; |
||||
$scope.currentScope.remove(); |
||||
return $scope.waiting = false; |
||||
}, function(resp) { |
||||
$scope.currentSession = null; |
||||
$scope.currentScope.remove(); |
||||
return $scope.waiting = false; |
||||
}); |
||||
return $scope.showT = true; |
||||
}; |
||||
$scope.stoggle = function(scope) { |
||||
var node; |
||||
node = scope.$modelValue; |
||||
if (node.nodes.length === 0) { |
||||
$scope.updateTree(node.value, node.nodes, node.level, node.over, node.query, node.count); |
||||
} |
||||
return scope.toggle(); |
||||
}; |
||||
$scope.displaySession = function(scope) { |
||||
var sessionId, transformSession; |
||||
transformSession = function(session) { |
||||
var _insert, _stToStr, attr, attrs, category, i, id, k, key, l, len, len1, len2, m, ref, ref1, res, subres, time, tmp, value; |
||||
_stToStr = function(s) { |
||||
return s; |
||||
}; |
||||
_insert = function(re, title) { |
||||
var key, reg, tmp, value; |
||||
tmp = []; |
||||
reg = new RegExp(re); |
||||
for (key in session) { |
||||
value = session[key]; |
||||
if (key.match(reg) && value) { |
||||
tmp.push({ |
||||
title: key, |
||||
value: value |
||||
}); |
||||
delete session[key]; |
||||
} |
||||
} |
||||
if (tmp.length > 0) { |
||||
return res.push({ |
||||
title: title, |
||||
nodes: tmp |
||||
}); |
||||
} |
||||
}; |
||||
time = session._utime; |
||||
id = session._session_id; |
||||
for (key in session) { |
||||
value = session[key]; |
||||
if (!value) { |
||||
delete session[key]; |
||||
} else { |
||||
if (typeof session === 'string' && value.match(/; /)) { |
||||
session[key] = value.split('; '); |
||||
} |
||||
if (typeof session[key] !== 'object') { |
||||
if (hiddenAttributes.match(new RegExp('\b' + key + '\b'))) { |
||||
session[key] = '********'; |
||||
} else if (key.match(/^(_utime|_lastAuthnUTime|_lastSeen|notification)$/)) { |
||||
session[key] = $scope.localeDate(value); |
||||
} else if (key.match(/^(_startTime|_updateTime)$/)) { |
||||
session[key] = _stToStr(value); |
||||
} else if (key.match(/^(_u2fKeyHandle|_u2fUserKey|_totp2fSecret)$/)) { |
||||
session[key] = '##########'; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
res = []; |
||||
for (category in categories) { |
||||
attrs = categories[category]; |
||||
subres = []; |
||||
for (i = 0, len = attrs.length; i < len; i++) { |
||||
attr = attrs[i]; |
||||
if (session[attr]) { |
||||
subres.push({ |
||||
title: attr, |
||||
value: session[attr] |
||||
}); |
||||
delete session[attr]; |
||||
} |
||||
} |
||||
if (subres.length > 0) { |
||||
res.push({ |
||||
title: "__" + category + "__", |
||||
nodes: subres |
||||
}); |
||||
} |
||||
} |
||||
_insert('^openid', 'OpenID'); |
||||
_insert('^notification_(.+)', '__notificationsDone__'); |
||||
if (session._loginHistory) { |
||||
tmp = []; |
||||
if (session._loginHistory.successLogin) { |
||||
ref = session._loginHistory.successLogin; |
||||
for (k = 0, len1 = ref.length; k < len1; k++) { |
||||
l = ref[k]; |
||||
tmp.push({ |
||||
t: l._utime, |
||||
title: $scope.localeDate(l._utime), |
||||
value: "Success (IP " + l.ipAddr + ")" |
||||
}); |
||||
} |
||||
} |
||||
if (session._loginHistory.failedLogin) { |
||||
ref1 = session._loginHistory.failedLogin; |
||||
for (m = 0, len2 = ref1.length; m < len2; m++) { |
||||
l = ref1[m]; |
||||
tmp.push({ |
||||
t: l._utime, |
||||
title: $scope.localeDate(l._utime), |
||||
value: l.error + " (IP " + l.ipAddr + ")" |
||||
}); |
||||
} |
||||
} |
||||
delete session._loginHistory; |
||||
tmp.sort(function(a, b) { |
||||
return a.t - b.t; |
||||
}); |
||||
res.push({ |
||||
title: '__loginHistory__', |
||||
nodes: tmp |
||||
}); |
||||
} |
||||
tmp = []; |
||||
for (key in session) { |
||||
value = session[key]; |
||||
tmp.push({ |
||||
title: key, |
||||
value: value |
||||
}); |
||||
} |
||||
tmp.sort(function(a, b) { |
||||
if (a.title > b.title) { |
||||
return 1; |
||||
} else if (a.title < b.title) { |
||||
return -1; |
||||
} else { |
||||
return 0; |
||||
} |
||||
}); |
||||
res.push({ |
||||
title: '__attributesAndMacros__', |
||||
nodes: tmp |
||||
}); |
||||
return { |
||||
_utime: time, |
||||
id: id, |
||||
nodes: res |
||||
}; |
||||
}; |
||||
$scope.currentScope = scope; |
||||
sessionId = scope.$modelValue.session; |
||||
$http.get(scriptname + "sfa/" + sessionType + "/" + sessionId).then(function(response) { |
||||
return $scope.currentSession = transformSession(response.data); |
||||
}); |
||||
return $scope.showT = false; |
||||
}; |
||||
$scope.localeDate = function(s) { |
||||
var d; |
||||
d = new Date(s * 1000); |
||||
return d.toLocaleString(); |
||||
}; |
||||
$scope.getLanguage = function(lang) { |
||||
$scope.lang = lang; |
||||
$scope.form = 'white'; |
||||
$scope.init(); |
||||
return $scope.showM = false; |
||||
}; |
||||
pathEvent = function(event, next, current) { |
||||
var n; |
||||
n = next.match(/#\/(\w+)/); |
||||
sessionType = 'global'; |
||||
if (n === null) { |
||||
$scope.type = '_whatToTrace'; |
||||
} else if (n[1].match(/^(persistent)$/)) { |
||||
sessionType = RegExp.$1; |
||||
$scope.type = '_session_uid'; |
||||
} else { |
||||
$scope.type = n[1]; |
||||
} |
||||
return $scope.init(); |
||||
}; |
||||
$scope.$on('$locationChangeSuccess', pathEvent); |
||||
autoId = 0; |
||||
$scope.updateTree = function(value, node, level, over, currentQuery, count) { |
||||
var query, scheme, tmp; |
||||
$scope.waiting = true; |
||||
scheme = schemes[$scope.type] ? schemes[$scope.type] : $scope.type === '_updateTime' ? schemes._startTime : schemes._whatToTrace; |
||||
query = scheme[level]($scope.type, value, currentQuery); |
||||
if (count > max && overScheme[$scope.type]) { |
||||
if (tmp = overScheme[$scope.type]($scope.type, value, level, over, currentQuery)) { |
||||
over++; |
||||
query = tmp; |
||||
level = level - 1; |
||||
} else { |
||||
over = 0; |
||||
} |
||||
} else { |
||||
over = 0; |
||||
} |
||||
return $http.get(scriptname + "sfa/" + sessionType + "?" + query).then(function(response) { |
||||
var data, i, len, n, ref; |
||||
data = response.data; |
||||
if (data.result) { |
||||
ref = data.values; |
||||
for (i = 0, len = ref.length; i < len; i++) { |
||||
n = ref[i]; |
||||
autoId++; |
||||
n.id = "node" + autoId; |
||||
if (level < scheme.length - 1) { |
||||
n.nodes = []; |
||||
n.level = level + 1; |
||||
n.query = query; |
||||
n.over = over; |
||||
if ($scope.type.match(/^(?:start|update)Time$/)) { |
||||
n.title = n.value.replace(/^(\d{8})(\d{2})(\d{2})$/, '$2:$3').replace(/^(\d{8})(\d{2})(\d)$/, '$2:$30').replace(/^(\d{8})(\d{2})$/, '$2h').replace(/^(\d{4})(\d{2})(\d{2})/, '$1-$2-$3'); |
||||
} |
||||
} |
||||
node.push(n); |
||||
} |
||||
if (value === '') { |
||||
$scope.total = data.total; |
||||
} |
||||
} |
||||
return $scope.waiting = false; |
||||
}, function(resp) { |
||||
return $scope.waiting = false; |
||||
}); |
||||
}; |
||||
$scope.init = function() { |
||||
$scope.waiting = true; |
||||
$scope.data = []; |
||||
return $q.all([$translator.init($scope.lang), $scope.updateTree('', $scope.data, 0, 0)]).then(function() { |
||||
return $scope.waiting = false; |
||||
}, function(resp) { |
||||
return $scope.waiting = false; |
||||
}); |
||||
}; |
||||
c = $location.path().match(/^\/(\w+)/); |
||||
return $scope.type = c ? c[1] : '_whatToTrace'; |
||||
} |
||||
]); |
||||
|
||||
}).call(this); |
File diff suppressed because one or more lines are too long
@ -1,150 +0,0 @@ |
||||
<TMPL_INCLUDE NAME="header.tpl"> |
||||
|
||||
<title>LemonLDAP::NG 2nd Factor sessions explorer</title> |
||||
</head> |
||||
|
||||
<body ng-app="llngSessionsExplorer" ng-controller="SessionsExplorerCtrl" ng-csp> |
||||
|
||||
<TMPL_INCLUDE NAME="menubar.tpl"> |
||||
|
||||
<div id="content" class="row container-fluid"> |
||||
<div id="pleaseWait" ng-show="waiting"><span trspan="waitingForDatas"></span></div> |
||||
|
||||
<!-- Tree --> |
||||
<aside id="left" class="col-lg-4 col-md-4 col-sm-5 col-xs-12 scrollable " ng-class="{'hidden-xs':!showT}" role="complementary"> |
||||
|
||||
<div class="navbar navbar-default"> |
||||
<div class="navbar-collapse"> |
||||
<ul class="nav navbar-nav" role="grid"> |
||||
<li><a id="a-persistent" role="row"><i class="glyphicon glyphicon-exclamation-sign"></i> {{translate('2faSessions')}}</a></li> |
||||
<form name="filterForm" ng-controller="SessionsExplorerFilter"> |
||||
<div class="form-check "> |
||||
<input type="checkbox" ng-model="U2FCheck" class="form-check-input" ng-true-value="'2'" ng-false-value="'1'" ng-change="filter2FA()"/> |
||||
<label class="form-check-label" for="U2FCheck">U2F</label> |
||||
<input type="checkbox" ng-model="TOTPCheck" class="form-check-input" ng-true-value="'2'" ng-false-value="'1'" ng-change="filter2FA()"/> |
||||
<label class="form-check-label" for="TOTPCheck">TOTP</label> |
||||
</div> |
||||
</form> |
||||
</ul> |
||||
</div> |
||||
</div> |
||||
<div class="text-center"><p class="badge">{{total}} <span trspan="session_s"></span></p></div> |
||||
<div class="region region-sidebar-first"> |
||||
<section id="block-superfish-1" class="block block-superfish clearfix"> |
||||
<div ui-tree data-drag-enabled="false" id="tree-root"> |
||||
<div ng-show="data.length==0" class="center"> |
||||
<span class="label label-warning" trspan="noDatas"></span> |
||||
</div> |
||||
<ol ui-tree-nodes="" ng-model="data"> |
||||
<li ng-repeat="node in data track by node.id" ui-tree-node ng-include="'nodes_renderer.html'" collapsed="true"></li> |
||||
</ol> |
||||
</div> |
||||
</section> |
||||
</div> |
||||
<div class="hresizer hidden-xs" resizer="vertical" resizer-left="#left" resizer-right="#right"></div> |
||||
</aside> |
||||
|
||||
<!-- Right(main) div --> |
||||
<div id="right" class="col-lg-8 col-md-8 col-sm-7 col-xs-12 scrollable" ng-class="{'hidden-xs':showT&&!showM}"> |
||||
<!-- Menu buttons --> |
||||
|
||||
<div ng-if="currentSession" class="lmmenu navbar navbar-default" ng-class="{'hidden-xs':!showM}"> |
||||
<div class="navbar-collapse" ng-class="{'collapse':!showM}" id="formmenu"> |
||||
<ul class="nav navbar-nav"> |
||||
<li ng-if="currentSession" ng-repeat="button in menu.delU2FKey" ng-include="'menubutton.html'"></li> |
||||
<li ng-if="currentSession" ng-repeat="button in menu.verifyU2FKey" ng-include="'menubutton.html'"></li> |
||||
<li ng-if="currentSession" ng-repeat="button in menu.addU2FKey" ng-include="'menubutton.html'"></li> |
||||
<li ng-if="currentSession===null" ng-repeat="button in menu.home" ng-include="'menubutton.html'"></li> |
||||
<li uib-dropdown class="visible-xs"> |
||||
<a id="langmenu" name="menu" uib-dropdown-toggle data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Menu <span class="caret"></span></a> |
||||
<ul uib-dropdown-menu aria-labelled-by="langmenu" role="grid"> |
||||
<li ng-repeat="link in links"><a href="{{link.target}}" role="row"><i ng-if="link.icon" class="glyphicon glyphicon-{{link.icon}}"></i> {{translate(link.title)}}</a></li> |
||||
<li ng-repeat="menulink in menulinks"><a href="{{menulink.target}}" role="row"><i ng-if="menulink.icon" class="glyphicon glyphicon-{{menulink.icon}}"></i> {{translate(menulink.title)}}</a></li> |
||||
<li ng-include="'languages.html'"></li> |
||||
</ul> |
||||
</li> |
||||
</ul> |
||||
</div> |
||||
</div> |
||||
|
||||
<div ng-if="currentSession" class="lmmenu navbar navbar-default" ng-class="{'hidden-xs':!showM}"> |
||||
<div class="navbar-collapse" ng-class="{'collapse':!showM}" id="formmenu"> |
||||
<ul class="nav navbar-nav"> |
||||
<li ng-if="currentSession" ng-repeat="button in menu.delTOTPKey" ng-include="'menubutton.html'"></li> |
||||
<li ng-if="currentSession" ng-repeat="button in menu.verifyTOTPKey" ng-include="'menubutton.html'"></li> |
||||
<li ng-if="currentSession" ng-repeat="button in menu.addTOTPKey" ng-include="'menubutton.html'"></li> |
||||
<li ng-if="currentSession===null" ng-repeat="button in menu.home" ng-include="'menubutton.html'"></li> |
||||
<li uib-dropdown class="visible-xs"> |
||||
<a id="langmenu" name="menu" uib-dropdown-toggle data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Menu <span class="caret"></span></a> |
||||
<ul uib-dropdown-menu aria-labelled-by="langmenu" role="grid"> |
||||
<li ng-repeat="link in links"><a href="{{link.target}}" role="row"><i ng-if="link.icon" class="glyphicon glyphicon-{{link.icon}}"></i> {{translate(link.title)}}</a></li> |
||||
<li ng-repeat="menulink in menulinks"><a href="{{menulink.target}}" role="row"><i ng-if="menulink.icon" class="glyphicon glyphicon-{{menulink.icon}}"></i> {{translate(menulink.title)}}</a></li> |
||||
<li ng-include="'languages.html'"></li> |
||||
</ul> |
||||
</li> |
||||
</ul> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="panel panel-default" ng-hide="currentSession===null"> |
||||
<div class="panel-heading"> |
||||
<h1 class="panel-title text-center">{{translate("sessionTitle")}} {{currentSession.id}}</h1> |
||||
</div> |
||||
<div class="panel-body"> |
||||
<div class="alert alert-info"> |
||||
<strong>{{translate("sessionStartedAt")}}</strong> |
||||
{{localeDate(currentSession._utime)}} |
||||
</div> |
||||
<div ng-model="currentSession.nodes"> |
||||
<div ng-repeat="node in currentSession.nodes" ng-include="'session_attr.html'"></div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<script type="text/ng-template" id="session_attr.html"> |
||||
<div class="panel panel-default" ng-if="node.nodes"> |
||||
<div class="panel-heading"> |
||||
<h2 class="panel-title text-center">{{translateP(node.title)}}</h2> |
||||
</div> |
||||
<table class="table table-striped" ng-model="node.nodes"> |
||||
<tr ng-repeat="node in node.nodes" ng-include="'session_attr.html'"></tr> |
||||
</table> |
||||
</div> |
||||
<div ng-if="!node.nodes"> |
||||
<th>{{translate(node.title)}}</th> |
||||
<td><tt>${{node.title}}</tt></td> |
||||
<td><span id="v-{{node.title}}">{{node.value}}</td> |
||||
</div> |
||||
</script> |
||||
|
||||
<script type="text/ng-template" id="nodes_renderer.html"> |
||||
<div ui-tree-handle class="tree-node tree-node-content panel-info" ng-class="{'bg-info':this.$modelValue===currentScope.$modelValue,'tree-node-default':this.$modelValue!==currentScope.$modelValue}"> |
||||
<span ng-if="node.value"> |
||||
<a id="a-{{node.value}}" class="btn btn-node btn-sm" ng-click="stoggle(this)"> |
||||
<span class="glyphicon" ng-class="{'glyphicon-chevron-right': collapsed,'glyphicon-chevron-down': !collapsed}"></span> |
||||
</a> |
||||
<span id="s-{{node.value}}" ng-click="stoggle(this)">{{node.title || node.value}} <span class="badge">{{node.count}}</span></span> |
||||
</span> |
||||
<span ng-if="node.session"> |
||||
<a class="btn btn-node btn-sm" ng-click="displaySession(this)"> |
||||
<span class="glyphicon glyphicon-eye-open"></span> |
||||
</a> |
||||
<span id="s-{{node.session}}" ng-click="displaySession(this)">{{localeDate(node.date)}}</span> |
||||
</span> |
||||
</div> |
||||
<ol ui-tree-nodes="" ng-model="node.nodes" ng-class="{hidden: collapsed}"> |
||||
<li ng-repeat="node in node.nodes track by node.id" ui-tree-node ng-include="'nodes_renderer.html'" collapsed="true"></li> |
||||
</ol> |
||||
</script> |
||||
|
||||
<TMPL_INCLUDE NAME="scripts.tpl"> |
||||
|
||||
<!-- //if:jsminified |
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">js/sfa.min.js"></script> |
||||
//else --> |
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">js/sfa.js"></script> |
||||
<!-- //endif --> |
||||
|
||||
<TMPL_INCLUDE NAME="footer.tpl"> |
Loading…
Reference in new issue