// Generated by CoffeeScript 1.12.8

/*
 * Sessions explorer
 */

(function() {
  var categories, hiddenAttributes, llapp, max, menu, overScheme, schemes;

  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;
      }
    ],
    ipAddr: [
      function(t, v) {
        return "groupBy=net(" + t + ",16,1)";
      }, function(t, v) {
        if (!v.match(/:/)) {
          v = v + '.';
        }
        return t + "=" + v + "*&groupBy=net(" + t + ",32,2)";
      }, function(t, v) {
        if (!v.match(/:/)) {
          v = v + '.';
        }
        return t + "=" + v + "*&groupBy=net(" + t + ",48,3)";
      }, function(t, v) {
        if (!v.match(/:/)) {
          v = v + '.';
        }
        return t + "=" + v + "*&groupBy=net(" + t + ",128,4)";
      }, function(t, v) {
        return t + "=" + v + "&groupBy=_whatToTrace";
      }, function(t, v, q) {
        return q.replace(/\&groupBy.*$/, '') + ("&_whatToTrace=" + 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);
      }
    ],
    doubleIp: [
      function(t, v) {
        return t;
      }, function(t, v) {
        return "_whatToTrace=" + v + "&groupBy=ipAddr";
      }, function(t, v, q) {
        return q.replace(/\&groupBy.*$/, '') + ("&ipAddr=" + v);
      }
    ],
    _session_uid: [
      function(t, v) {
        return "groupBy=substr(" + t + ",1)";
      }, function(t, v) {
        return t + "=" + v + "*&groupBy=" + t;
      }, function(t, v) {
        return t + "=" + v;
      }
    ]
  };

  overScheme = {
    _whatToTrace: function(t, v, level, over) {
      console.log('overScheme => level', level, 'over', over);
      if (level === 1 && v.length > over) {
        return t + "=" + v + "*&groupBy=substr(" + t + "," + (level + over + 1) + ")";
      } else {
        return null;
      }
    },
    ipAddr: function(t, v, level, over) {
      console.log('overScheme => level', level, 'over', over);
      if (level > 0 && level < 4 && !v.match(/^\d+\.\d/) && over < 2) {
        return t + "=" + v + "*&groupBy=net(" + t + "," + (16 * level + 4 * (over + 1)) + "," + (1 + level + over) + ")";
      } else {
        return null;
      }
    },
    _startTime: function(t, v, level, over) {
      console.log('overScheme => level', level, 'over', over);
      if (level > 3) {
        return t + "=" + v + "*&groupBy=substr(" + t + "," + (10 + level + over) + ")";
      } else {
        return null;
      }
    },
    _session_uid: function(t, v, level, over) {
      console.log('overScheme => level', level, 'over', over);
      if (level === 1 && v.length > over) {
        return t + "=" + v + "*&groupBy=substr(" + t + "," + (level + over + 1) + ")";
      } 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'],
    OpenIDConnect: ['_oidc_id_token', '_oidc_OP', '_oidc_access_token'],
    sfaTitle: ['_2fDevices'],
    oidcConsents: ['_oidcConsents']
  };

  menu = {
    session: [
      {
        title: 'deleteSession',
        icon: 'trash'
      }
    ],
    home: []
  };


  /*
   * AngularJS application
   */

  llapp = angular.module('llngSessionsExplorer', ['ui.tree', 'ui.bootstrap', 'llApp']);

  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.impPrefix = impPrefix;
      $scope.sessionTTL = sessionTTL;
      $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.deleteOIDCConsent = function(rp, epoch) {
        var items;
        items = document.querySelectorAll(".data-" + epoch);
        $scope.waiting = true;
        $http['delete'](scriptname + "sessions/OIDCConsent/" + sessionType + "/" + $scope.currentSession.id + "?rp=" + rp + "&epoch=" + epoch).then(function(response) {
          var e, i, len, results;
          $scope.waiting = false;
          results = [];
          for (i = 0, len = items.length; i < len; i++) {
            e = items[i];
            results.push(e.remove());
          }
          return results;
        }, function(resp) {
          return $scope.waiting = false;
        });
        return $scope.showT = false;
      };
      $scope.deleteSession = function() {
        $scope.waiting = true;
        return $http['delete'](scriptname + "sessions/" + sessionType + "/" + $scope.currentSession.id).then(function(response) {
          $scope.currentSession = null;
          $scope.currentScope.remove();
          return $scope.waiting = false;
        }, function(resp) {
          return $scope.waiting = false;
        });
      };
      $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, array, attr, attrs, category, cv, element, epoch, i, j, k, key, l, len, len1, len2, len3, len4, len5, m, name, o, oidcConsent, p, real, ref, ref1, res, sfDevice, spoof, subres, tab, time, title, tmp, value;
          _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;
          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] = $scope.strToLocaleDate(value);
                }
              }
            }
          }
          res = [];
          for (category in categories) {
            attrs = categories[category];
            subres = [];
            for (i = 0, len = attrs.length; i < len; i++) {
              attr = attrs[i];
              if (session[attr]) {
                if (session[attr].toString().match(/"type":\s*"(?:TOTP|U2F|UBK)"/)) {
                  subres.push({
                    title: "type",
                    value: "name",
                    epoch: "date",
                    td: "0"
                  });
                  array = JSON.parse(session[attr]);
                  for (j = 0, len1 = array.length; j < len1; j++) {
                    sfDevice = array[j];
                    for (key in sfDevice) {
                      value = sfDevice[key];
                      if (key === 'type') {
                        title = value;
                      }
                      if (key === 'name') {
                        name = value;
                      }
                      if (key === 'epoch') {
                        epoch = value;
                      }
                    }
                    subres.push({
                      title: title,
                      value: name,
                      epoch: epoch,
                      td: "1"
                    });
                  }
                  delete session[attr];
                } else if (session[attr].toString().match(/"rp":\s*"[\w-]+"/)) {
                  subres.push({
                    title: "RP",
                    value: "scope",
                    epoch: "date",
                    td: "0"
                  });
                  array = JSON.parse(session[attr]);
                  for (k = 0, len2 = array.length; k < len2; k++) {
                    oidcConsent = array[k];
                    for (key in oidcConsent) {
                      value = oidcConsent[key];
                      if (key === 'rp') {
                        title = value;
                      }
                      if (key === 'scope') {
                        name = value;
                      }
                      if (key === 'epoch') {
                        epoch = value;
                      }
                    }
                    subres.push({
                      title: title,
                      value: name,
                      epoch: epoch,
                      td: "2"
                    });
                  }
                  delete session[attr];
                } else if (session[attr].toString().match(/\w+/)) {
                  subres.push({
                    title: attr,
                    value: session[attr],
                    epoch: ''
                  });
                  delete session[attr];
                } else {
                  delete session[attr];
                }
              } else {
                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 (m = 0, len3 = ref.length; m < len3; m++) {
                l = ref[m];
                cv = "";
                for (key in l) {
                  value = l[key];
                  if (!key.match(/^(_utime|ipAddr|error)$/)) {
                    cv += ", " + key + " : " + value;
                  }
                }
                tab = cv.split(', ');
                tab.sort();
                cv = tab.join(', ');
                tmp.push({
                  t: l._utime,
                  title: $scope.localeDate(l._utime),
                  value: ("Success (IP " + l.ipAddr + ")") + cv
                });
              }
            }
            if (session._loginHistory.failedLogin) {
              ref1 = session._loginHistory.failedLogin;
              for (o = 0, len4 = ref1.length; o < len4; o++) {
                l = ref1[o];
                cv = "";
                for (key in l) {
                  value = l[key];
                  if (!key.match(/^(_utime|ipAddr|error)$/)) {
                    cv += ", " + key + " : " + value;
                  }
                }
                tab = cv.split(', ');
                tab.sort();
                cv = tab.join(', ');
                tmp.push({
                  t: l._utime,
                  title: $scope.localeDate(l._utime),
                  value: ("Error " + l.error + " (IP " + l.ipAddr + ")") + cv
                });
              }
            }
            delete session._loginHistory;
            tmp.sort(function(a, b) {
              return b.t - a.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;
            }
          });
          real = [];
          spoof = [];
          for (p = 0, len5 = tmp.length; p < len5; p++) {
            element = tmp[p];
            if (element.title.match(new RegExp('^' + $scope.impPrefix + '.+$'))) {
              console.log(element, '-> real attribute');
              real.push(element);
            } else {
              spoof.push(element);
            }
          }
          tmp = spoof.concat(real);
          res.push({
            title: '__attributesAndMacros__',
            nodes: tmp
          });
          return {
            _utime: time,
            nodes: res
          };
        };
        $scope.currentScope = scope;
        sessionId = scope.$modelValue.session;
        $http.get(scriptname + "sessions/" + sessionType + "/" + sessionId).then(function(response) {
          $scope.currentSession = transformSession(response.data);
          return $scope.currentSession.id = sessionId;
        });
        return $scope.showT = false;
      };
      $scope.localeDate = function(s) {
        var d;
        d = new Date(s * 1000);
        return d.toLocaleString();
      };
      $scope.isValid = function(epoch, type) {
        var isValid, now, path;
        path = $location.path();
        now = Date.now() / 1000;
        console.log("Path", path);
        console.log("Session epoch", epoch);
        console.log("Current date", now);
        console.log("Session TTL", sessionTTL);
        isValid = now - epoch < sessionTTL || $location.path().match(/^\/persistent/);
        if (type === 'msg') {
          console.log("Return msg");
          if (isValid) {
            return "info";
          } else {
            return "warning";
          }
        } else if (type === 'style') {
          console.log("Return style");
          if (isValid) {
            return {};
          } else {
            return {
              'color': '#627990',
              'font-style': 'italic'
            };
          }
        } else {
          console.log("Return isValid");
          return isValid;
        }
      };
      $scope.strToLocaleDate = function(s) {
        var arrayDate, d;
        arrayDate = s.match(/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/);
        if (!arrayDate.length) {
          return s;
        }
        d = new Date(arrayDate[1] + "-" + arrayDate[2] + "-" + arrayDate[3] + "T" + arrayDate[4] + ":" + arrayDate[5] + ":" + arrayDate[6]);
        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|offline)$/)) {
          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;
        }
        $http.get(scriptname + "sessions/" + 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;
        });
        console.log("Selection", sessionType);
        $scope.navssoStyle = {
          color: '#777'
        };
        $scope.offlineStyle = {
          color: '#777'
        };
        $scope.persistentStyle = {
          color: '#777'
        };
        if (sessionType === 'global') {
          $scope.navssoStyle = {
            color: '#333'
          };
        }
        if (sessionType === 'offline') {
          $scope.offlineStyle = {
            color: '#333'
          };
        }
        if (sessionType === 'persistent') {
          return $scope.persistentStyle = {
            color: '#333'
          };
        }
      };
      $scope.init = function() {
        $scope.waiting = true;
        $scope.data = [];
        $scope.currentScope = null;
        $scope.currentSession = null;
        $q.all([$translator.init($scope.lang), $scope.updateTree('', $scope.data, 0, 0)]).then(function() {
          return $scope.waiting = false;
        }, function(resp) {
          return $scope.waiting = false;
        });
        $scope.activeModule = "sessions";
        return $scope.myStyle = {
          color: '#ffb84d'
        };
      };
      c = $location.path().match(/^\/(\w+)/);
      return $scope.type = c ? c[1] : '_whatToTrace';
    }
  ]);

}).call(this);
