app = angular.module('kim', ['chart.js','ngSanitize', 'angular-bind-html-compile']); app.config(['$locationProvider', function($locationProvider) { $locationProvider.html5Mode({ enabled: true, requireBase: false, rewriteLinks: false }); }]); app.controller("scanner_input", function($scope, $http, $location, $rootScope, $sce, $interval, $timeout) { }); Date.prototype.copyTimeComponent = function(_source, _includeMs) { this.setHours(_source ? _source.getHours() : 0); this.setMinutes(_source ? _source.getMinutes() : 0); this.setSeconds(_source ? _source.getSeconds() : 0); this.setMilliseconds(_source && _includeMs ? _source.getMilliseconds() : 0); }; Date.prototype.sameDateAs = function(_compare) { return _compare && _compare.getFullYear() == this.getFullYear() && _compare.getMonth() == this.getMonth() && _compare.getDate() == this.getDate(); }; String.prototype.replaceAll = function(_old, _new) { if (_old === _new) { return this; } var temp = this; var index = temp.indexOf(_old); while (index != -1) { temp = temp.replace(_old, _new); index = temp.indexOf(_old); } return temp; }; function replaceRelationFields(_scope, _string) { var replacedFields = []; var toProcess = _string || ""; do { var match = toProcess.match(/\<[^\>]*\>/); if (match) { toProcess = toProcess.replace(/\<[^\>]*\>/, (field) => { //Arguments, raw var arguments = field.replace("<","").replace(">","").split(","); var fieldName = arguments.shift(); if (fieldName.startsWith("$scope.")) { var f = new Function("$scope", "return " + fieldName); return JSON.stringify(f(_scope)); } else { replacedFields.push(fieldName); return arguments.includes("raw") ? _scope.record[fieldName] : JSON.stringify(_scope.record[fieldName] || null); } }); } } while(match); return { output: toProcess, replacedFields: replacedFields.distinct() }; } function scrollToElement(_id, _parentId) { var scrollTo = document.getElementById(_id); if (_parentId) { document.getElementById(_parentId).scrollTop = scrollTo.offsetTop; } else { scrollTo.scrollIntoView(true); } } function elementIsVisible(_id) { try { return $("#" + _id).is(":visible"); } catch (e) { return false; } } String.prototype.truncate = function(_length, _append) { _append = _append || "..."; if (!this) { return this; } return this.length > _length ? (this.substring(0, _length) + _append) : this; }; function arrayToObjectBy(_array, _property, _removeField) { var obj = {}; _array.forEach((i) => { if (typeof(i) != "object") { throw "Cannot convert array to object by " + _property + ", invalid value"; } var key = i[_property].toString(); if (Object.keys(obj).includes(key)) { throw "Cannot convert array to object by " + _property + ", duplicate key value"; } obj[key] = i; if (_removeField) { delete obj[key][_property]; } }); return obj; } function getServerTime(_http, _then) { _http.get("/api/current_time", { withCredentials: true }).then((json) => { postProcessJSON(json); if (_then) { _then(json.data); } }); } Array.prototype.distinct = function() { return this == null ? null : Array.from(new Set(this)); } Array.prototype.last = function() { if (!this || !Array.isArray(this)) { return null; } return this[this.length - 1]; }; Array.prototype.sum = function() { if (!this || !Array.isArray(this)) { return 0; } return this.reduce((sum, v) => { return sum + v; }, 0); }; Array.prototype.indexOfCondition = function(_method) { for(var i = 0; i < this.length; i++) { if (_method(this[i])) { return i; } } return -1; }; function parseDateDifference(_diff) { var diff = Math.abs((_diff == null ? 0 : _diff) / 1000); var output = { days: 0, hours: 0, minutes: 0, seconds: 0 } while(diff >= 86400) { output.days++; diff-=86400; } while(diff >= 3600) { output.hours++; diff-=3600; } while(diff >= 60) { output.minutes++; diff-=60; } while(diff >= 1) { output.seconds++; diff-=1; } return output; } function getFormattedTime(_ms) { var comps = parseDateDifference((_ms || 0)); var ds = ""; if (comps.days > 0) { ds += comps.days + " day "; } if (comps.hours > 0) { ds += comps.hours + " hrs "; } if (comps.minutes > 0) { ds += comps.minutes + " min "; } if (comps.seconds > 0) { ds += comps.seconds + " sec"; } return ds; } function collectAllRoles($scope, $http, _parentRolesOrRole, _then) { var allRoles = []; if (_parentRolesOrRole) { var parents = (Array.isArray(_parentRolesOrRole) ? _parentRolesOrRole : [_parentRolesOrRole]).distinct(); //Add parent roles allRoles.push(...parents); //Get parent roles info retrieveRecords($scope, $http, "role", { query: { _id: { $in: parents }}}, (parentsResponse) => { //Get child roles of the parent roles var children = parentsResponse.records.map((r) => { return r.contained_roles; }).flat().distinct(); if (children.length > 0) { collectAllRoles($scope, $http, children, (childRoles) => { allRoles.push(...childRoles); if (_then) { _then(allRoles.distinct()); } }); } else if (_then) { _then(allRoles.distinct()); } }); } } function getDefaultControls($scope, _model, _field) { var field = $scope.$root.models[_model].fields[_field]; return { singular_read: field ? $scope.$root.controls[field.selections ? "6023e2298989745e0939f791" : $scope.$root.kimConfig["default_singular_" + field.type + "_read_control" ]] : null, singular_write: field ? $scope.$root.controls[field.selections ? "602338ec175393570a177213" : $scope.$root.kimConfig["default_singular_" + field.type + "_write_control"]] : null, plural_read: field ? $scope.$root.controls[field.selections ? "6282388314e1110384d78db9" : $scope.$root.kimConfig["default_plural_" + field.type + "_read_control" ]] : null, plural_write: field ? $scope.$root.controls[field.selections ? "62857728fa1f641bafe08e20" : $scope.$root.kimConfig["default_plural_" + field.type + "_write_control"]] : null }; } function getScopeFromHTMLElement(_htmlElement) { return angular.element(_htmlElement).scope(); } function getSortedObject(_object, _function) { if (!_object) { return _object; } return Object.keys(_object).map((k) => { return { key: k, value: _object[k] }}).sort(_function); } function msToDuration(_ms, _maxIntervals) { var neg = _ms < 0; _ms = Math.abs(_ms); var comps = []; var intervals = [86400000, 3600000, 60000, 1000].reverse().slice(0, _maxIntervals || 9999).reverse(); for(var interval of intervals) { var iCount = 0; while(_ms >= interval) { iCount++; _ms -= interval; } comps.push(iCount.toString().padStart(2, "0")); } return (neg ? "-" : "+") + comps.join(":"); } function downloadLink(_link, _name) { let link = document.createElement("a"); link.download = _name || ""; link.href = _link; link.click(); } function formatDataSize(_bytes) { _bytes = _bytes || 0; var thresholds = { TB: 1099511627776, GB: 1073741824, MB: 1048576, KB: 1024, B: 1 }; for(var t of Object.keys(thresholds)) { if (_bytes >= thresholds[t]) { return Math.round(_bytes / thresholds[t]) + " " + t; } } } function safeApply(_scope) { var phase = _scope.$root.$$phase; if(phase == '$apply' || phase == '$digest') { } else { _scope.$apply(); } }; String.prototype.toCamelCase = function() { return this.toLowerCase().replaceAll("_", " ").split(" ").map((w, i) => { return (i == 0 ? w.charAt(0) : w.charAt(0).toUpperCase()) + w.slice(1) }).join(""); } String.prototype.toTitleCase = function() { return this.toLowerCase().replaceAll("_", " ").split(" ").map((w) => { return w.charAt(0).toUpperCase() + w.slice(1) }).join(" "); } function groupByProperty(_array, _field) { if (!_array || !_field) { return {}; } var groups = {}; for(var i of _array) { var normalizedValue = i[_field] == undefined ? null : i[_field]; if (!groups[normalizedValue]) { groups[normalizedValue] = []; } groups[normalizedValue].push(i); } return groups; } function postProcessJSON(_json) { //Since custom JSON parsing isnt yet available in HttpClient we'll need to do some client side casting to the correct types if (_json == null) { return null; } Object.keys(_json).forEach((p) => { if (_json[p] != null) { if (isValidDateString(_json[p])){ _json[p] = new Date(_json[p]); } else if (typeof(_json[p]) == "object"){ postProcessJSON(_json[p]); } } }); }; // GLOBAL METHODS /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function isValidDateString(_string) { var dateRegex = new RegExp("^\\d{4}-\\d{2}-\\d{2}T\\d{2}\:\\d{2}\:\\d{2}.\\d{3}Z$", "g"); return _string && dateRegex.test(_string); } function isValidIdString(_string) { var idRegEx = new RegExp("[0-9a-f]{24}", "g"); return _string && idRegEx.test(_string); } function getKimConfig($scope, $http, _then) { $http.get("/api/config", { withCredentials: true }).then( function(json){ postProcessJSON(json.data); _then(json.data ? json.data : {}); }, function(json) { postProcessJSON(json.data); _then(json.data ? json.data : {}); } ); } function renderTemplateToPrinter($scope, $http, _templateId, _printerId, _data, _rotate, _options, _then){ _rotate = _rotate || 0; $http.post("/api/render/template/" + _templateId + "/printer/" + _printerId + "?rotate=" + _rotate, { data: _data || {}, options: _options || {} }, { withCredentials: true }).then(() => { if (_then) { _then(true); }}); } function printLink($scope, $http, _printerId, _link, _options, _then) { _options = _options || {}; $http.post("/api/print/" + _printerId + "/" + btoa(_link), _options, { withCredentials: true }).then(() => { if (_then) { _then(true); } }); } function sendEmail($scope, $http, _to, _subject, _body, _html, _attachments, _replyTo, _then){ $http.post("/api/email", { to: _to, subject: _subject, body: _body, html: _html, attachments: _attachments, replyTo: _replyTo }, { withCredentials: true }).then(() => { if (_then) { _then(true); }}); } function sendTemplatedEmail($scope, $http, _to, _templateName, _record, _attachments, _replyTo, _then) { $http.post("/api/templatedEmail", { to: _to, template: _templateName, record: _record, attachments: _attachments, replyTo: _replyTo }, { withCredentials: true }).then(() => { if (_then) { _then(true); }}); } function getModelById($scope, _id) { return Object.values($scope.$root.models).find((model) => { return model._id == _id; }); } function getCurrentRoles($scope, $http, _then){ $http.get("/api/roles/current", { withCredentials: true }).then( function(json){ postProcessJSON(json.data); _then(json.data ? json.data : []); }, function(json) { postProcessJSON(json.data); _then(json.data ? json.data : {}); } ); } function countRecords($scope, $http, _model, _query, _then) { retrieveRecords($scope, $http, _model, { query: _query, select: ["_id"], limit: 1 }, (response) => { _then(response.total_count); }); } function retrieveRecords($scope, $http, _model, _options, _then) { _options = _options ? _options : {}; _options.query = _options.query ? _options.query : {}; var queryString = JSON.stringify(_options.query); //Check for large query if (queryString.length > 1000) { //Create a large_request_query record to avoid URL length issues insertRecord($scope, $http, "large_request_query", { query: queryString }, (response) => { if (response.success) { $http.get("/api/data/" + _model + "?query=" + "&sort=" + JSON.stringify(_options.sort || {}) + "&skip=" + JSON.stringify(_options.skip || 0) + "&limit=" + JSON.stringify(_options.limit || 999999) + "&populate=" + JSON.stringify(_options.populate || []) + "&select=" + JSON.stringify(_options.select || []) + "&large=" + response.record._id, { withCredentials: true }).then( function(json) { postProcessJSON(json.data); _then(json.data); }, function(json) { postProcessJSON(json.data); _then(json.data ? json.data : {}); } ); } else { _then({ total_count: 0, records: [], error: { errors: [{ message: "Failed to commit large request record"}]} }); } }); } else { $http.get("/api/data/" + _model + "?query=" + queryString + "&sort=" + JSON.stringify(_options.sort || {}) + "&skip=" + JSON.stringify(_options.skip || 0) + "&limit=" + JSON.stringify(_options.limit || 999999) + "&select=" + JSON.stringify(_options.select || []) + "&populate=" + JSON.stringify(_options.populate || []) + (_options.noCache ? ("&noCache=" + (new Date()).toString()) : ""), { withCredentials: true, }).then(function(json) { postProcessJSON(json.data); _then(json.data); }, function(json) { postProcessJSON(json.data); _then(json.data); } ); } } function mergeObjects(_target, _source) { if (_target == null || _source == null) { return; } if (typeof(_source) == "object") { //Check each source field Object.keys(_source).forEach((p) => { var sourceValue = _source[p]; if (typeof(sourceValue) == "object") { //Source value is an object, recursively process mergeObjects(_target[p], sourceValue); } else { //Source value is a primitive, convert the target propoerty to an objectif neccessary, then assign source value _target[p] = typeof(_target[p]) == "object" ? _target[p] : {}; _target[p] = sourceValue; } }); } } //Deprecated function getRecords($scope, $http, _model, _query, _populate, _sort, _skip, _limit, _then){ console.log("Deprecated function used: getRecords"); retrieveRecords($scope, $http, _model, { query: _query, populate: _populate, sort: _sort, skip: _skip, limit: _limit }, _then); } function retrieveRecord($scope, $http, _model, _options, _then){ _options.limit = 1; retrieveRecords($scope, $http, _model, _options, (data) => { _then((data.error || data.records.length < 1) ? null : data.records[0]); }); } function getRecord($scope, $http, _model, _query, _populate, _then){ console.log("Deprecated function used: getRecord"); retrieveRecord($scope, $http, _model, { query: _query, populate: _populate }, _then); } function getCurrentUser($scope, $http, _then){ $http.get("/api/auth/current", { withCredentials: true }).then( function(json) { _then(json.data); }, function(json) { postProcessJSON(json.data); _then(json.data ? json.data : {}); } ); } function logOut($scope, $http, _then) { $http.post("/api/auth/logout", null, { withCredentials: true }).then(function(json){ if (_then) {_then(json.data);} }); } function logIn($scope, $http, _username, _password, _then) { $http.post("/api/auth/", { username: _username, password: _password }).then(function(json){ if (_then) {_then(json.data);} }); } function deleteRecord($scope, $http, _model, _id, _then){ //Note: query is in body for DELETEs $http.delete("/api/data/" + _model + "/" + _id, { withCredentials: true }).then(function(json){ if (_then) {_then(json.data);} }); } function deleteRecords($scope, $http, _model, _query, _then){ postProcessJSON(_query); //Note: query is in body for DELETEs $http.delete("/api/data/" + _model + "?query=" + JSON.stringify(_query), { withCredentials: true }).then(function(json){ if (_then) {_then(json.data);} }); } function updateRecord($scope, $http, _model, _id, _data, _then){ $http.post("/api/data/" + _model + "?_id=" + _id, _data, { withCredentials: true }).then(function(json){ if (_then) {_then(json.data);} }); } function updateRecords($scope, $http, _model, _idsAndData, _onFinalUpdate, _onEachUpdate, _originalCount) { if (_idsAndData && typeof(_idsAndData) == "object" && Object.keys(_idsAndData).length > 0 ) { _originalCount = _originalCount == null ? Object.keys(_idsAndData).length : _originalCount; var id = Object.keys(_idsAndData)[0]; $http.post("/api/data/" + _model + "?_id=" + id, _idsAndData[id], { withCredentials: true }).then(function(json){ var newIdsAndData = cloneObject(_idsAndData); delete newIdsAndData[id]; if (_onEachUpdate) { _onEachUpdate({ id: id, progress: 1 - (Object.keys(newIdsAndData).length / _originalCount) }); } updateRecords($scope, $http, _model, newIdsAndData, _onFinalUpdate, _onEachUpdate, _originalCount); }); } else if (_onFinalUpdate) { _onFinalUpdate(); } } function insertRecord($scope, $http, _model, _data, _then){ $http.post("/api/data/" + _model + "?insert=true", _data, { withCredentials: true }).then(function(json){ if (_then) { _then(json.data); } }); } function getModels($scope, $http, _then){ $http.get("/api/models", { withCredentials: true }).then( function(json){ _then(json.data); }, function(json) { _then(json.data ? json.data : {}); }); } function getApps($scope, $http, _then){ $http.get("/api/apps", { withCredentials: true }).then( function(json){ _then(json.data); }, function(json) { _then(json.data ? json.data : {}); }); } function getURIParameters() { if (!window.location.href.includes("?")) { return {};} var params = {}; window.location.href.split("?")[1].split("&").forEach(function(param) { var paramQuals = param.split("="); params[paramQuals[0]] = paramQuals[1]; }); return params; } function getPageName() { if (!window.location.href.includes("/")) {return null;} var comps = window.location.href.split("/"); return comps[comps.length - 1].split("?")[0]; } function mapObjectValues(_object, _func) { if (_object == null) { return null; } var m = {}; Object.keys(_object).forEach((k) => { m[k] = _func([_object.k], k); }); return m; } function cancelTask($scope, $http, _executionId, _then) { updateRecord($scope, $http, "task_execution", _executionId, { state: "cancel_pending" }, _then); } function executeTask($scope, $http, _task, _options, _init, _complete) { _options = _options || {}; _options.parameters = _options.parameters || {}; _options.data = _options.data || {}; _options.type = _options.type || "task_execution"; var data = _options.data; data.task = _task, data.parameters = _options.parameters; insertRecord($scope, $http, _options.type, data, (response) => { if (_init) { _init(response.record); } if (_complete) { var cbInterval = setInterval(() => { retrieveRecord($scope, $http, _options.type, { query: { _id: response.record._id }}, (execution) => { if (["succeeded", "failed", "cancelled"].includes(execution.state)) { clearInterval(cbInterval); return _complete(execution); } }); }, 2500); } }); } /* DEP VERSION function executeTask($scope, $http, _task, _params, _init, _complete) { insertRecord($scope, $http, _task._type || "task_execution", { task: _task, parameters: _params }, (response) => { if (_init) { _init(response.record); } if (_complete) { var cbInterval = setInterval(() => { retrieveRecord($scope, $http, "task_execution", { query: { _id: response.record._id }}, (execution) => { if (["succeeded", "failed"].includes(execution.state)) { clearInterval(cbInterval); return _complete(execution); } }); }, 2500); } }); } */ function searchFullScope(_scope, _field) { var scope = _scope; while (scope.$parent){ if (scope.hasOwnProperty(_field)) { return scope[_field]; } scope = scope.$parent; } return null; }; function cloneObject(_obj) { return _obj == null ? null : JSON.parse(JSON.stringify(_obj)); } function createUniqueTag() { return btoa(Math.random().toString().replace(".","")).split("=")[0]; } function clearBaseData() { window.sessionStorage.clear(); } function loadBaseData(_scope, _http, _then) { _scope.$root.recordCache = _scope.$root.recordCache || {}; var cachedBaseData = window.sessionStorage.getItem("baseData"); if (cachedBaseData) { //Exists, is it valid? cachedBaseData = JSON.parse(cachedBaseData); postProcessJSON(cachedBaseData); if (cachedBaseData.roles) { //Valid _scope.$root.serverTimeOffset = cachedBaseData.serverTime - (new Date()); _scope.$root.kimConfig = cachedBaseData.kimConfig; _scope.$root.currentUser = cachedBaseData.user; _scope.$root.layouts = cachedBaseData.layouts; _scope.$root.models = cachedBaseData.models; _scope.$root.segments = cachedBaseData.segments; _scope.$root.roles = cachedBaseData.roles; _scope.$root.controls = cachedBaseData.controls; _scope.$root.menu_containers = cachedBaseData.menu_containers; _scope.$root.client_ip = cachedBaseData.client_ip; _scope.$root.client_ci = cachedBaseData.client_ci; _scope.$root.globalFields = cachedBaseData.globalFields; _scope.$root.globalControls = cachedBaseData.global_controls; _scope.$root.fieldTypes = cachedBaseData.field_types; _scope.$root.sysadmin = _scope.$root.roles.some((r) => { return r._id == "5d44d5351747c171a2639ca3"; }); linkControlsToLayouts(_scope.$root); _scope.$root.baseDataLoaded = true; if (_then) { _then(); } return ; } } //Missing or invalid, reload _scope.$root.baseDataLoaded = false; _http.get("/basedata", { withCredentials: true }).then( function(json) { postProcessJSON(json.data); window.sessionStorage.setItem("baseData", JSON.stringify(json.data)); loadBaseData(_scope, _http, _then); }, function(json) { _then(json.data ? json.data : {}); } ); } function linkControlsToLayouts(_root) { for(var layout of _root.layouts) { for(var field of layout.fields) { field.control = typeof(field.control) == 'object' ? field.control : _root.controls[field.control]; } } } function loadCurrentUser(_scope, _http, _then) { getCurrentUser(_scope, _http, (user) => { _scope.$root.currentUser = user; if (_then) { _then(); } }); } function loadAllLayouts(_scope, _http, _then) { if (_scope.$root.layouts) { if (_then) { _then(); } } else { getRecords(_scope, _http, "layout", {}, ["fields.control"], {}, null, null, (response) => { _scope.$root.layouts = response.records; if (_then) { _then(); } }); } } function loadAllModels(_scope, _http, _then) { if (_scope.$root.models) { if (_then) { _then(); } } else { getModels(_scope, _http, (models) => { _scope.$root.models = models; if (_then) { _then(); } }); } } function loadCurrentRoles(_scope, _http, _then) { if (_scope.$root.roles) { if (_then) { _then(); } } else { getCurrentRoles(_scope, _http, (roles) => { _scope.$root.roles = roles; if (_then) { _then(); } }); } } function getCIsPoweredBy(_scope, _http, _id, _then) { _http.get("/api/cmdb/powered_by/" + _id, { withCredentials: true }).then(function(json){ _then(json.data); }); } function getCIsConnectedTo(_scope, _http, _id, _then) { _http.get("/api/cmdb/connected_to/" + _id, { withCredentials: true }).then(function(json){ _then(json.data); }); } function claimEnumeration(_scope, _http, _id, _then) { _http.get("/api/enumerator/" + _id + "?claim=true", { withCredentials: true }).then( function(json){ _then(json.data); }, function(json) { _then(json.data ? json.data : {}); }); } function waitForElement(_id, _then) { setTimeout(() => { var element = document.getElementById(_id); if (element) { _then(element); } else { waitForElement(_id, _then); } }, 100); } function encodeHtml(_html) { return btoa(unescape(encodeURIComponent(_html))); } function decodeHtml(_encoded) { try { return decodeURIComponent(escape(atob(_encoded))); } catch(e) { return null; } } function getDistinct(_array) { var o = []; (_array || []).forEach((e) => { if (!o.includes(e)) { o.push(e); } }); return o; } function setUrl(_location, _url) { _location.url(_url).replace(); } function getRootScope(_scope) { if (_scope.$id == 0) { return _scope; } else if (_scope.$parent) { return getRootScope(_scope.$parent); } else if (_scope.$root) { return _scope.$root; } else { return null; } } function hashCode(_string) { let hash = 0; for (let i = 0, len = _string.length; i < len; i++) { let chr = _string.charCodeAt(i); hash = (hash << 5) - hash + chr; hash |= 0; } return hash; }