'use strict'; /* global angular:false */ /* global $:false */ angular.module('Application').controller('ActivityController', ['$scope', '$location', 'Client', function ($scope, $location, Client) { Client.onReady(function () { if (!Client.getUserInfo().isAtLeastAdmin) $location.path('/'); }); $scope.config = Client.getConfig(); $scope.busy = false; $scope.eventLogs = []; $scope.activeEventLog = null; // TODO sync this with the eventlog filter $scope.actions = [ { name: '-- All app events --', value: 'app.' }, { name: '-- All user events --', value: 'user.' }, { name: 'app.configure', value: 'app.configure' }, { name: 'app.install', value: 'app.install' }, { name: 'app.restore', value: 'app.restore' }, { name: 'app.uninstall', value: 'app.uninstall' }, { name: 'app.update', value: 'app.update' }, { name: 'app.update.finish', value: 'app.update.finish' }, { name: 'app.login', value: 'app.login' }, { name: 'app.oom', value: 'app.oom' }, { name: 'app.down', value: 'app.down' }, { name: 'app.up', value: 'app.up' }, { name: 'app.start', value: 'app.start' }, { name: 'app.stop', value: 'app.stop' }, { name: 'app.restart', value: 'app.restart' }, { name: 'Apptask Crash', value: 'app.task.crash' }, { name: 'backup.cleanup', value: 'backup.cleanup.start' }, { name: 'backup.cleanup.finish', value: 'backup.cleanup.finish' }, { name: 'backup.finish', value: 'backup.finish' }, { name: 'backup.start', value: 'backup.start' }, { name: 'certificate.new', value: 'certificate.new' }, { name: 'certificate.renew', value: 'certificate.renew' }, { name: 'cloudron.activate', value: 'cloudron.activate' }, { name: 'cloudron.provision', value: 'cloudron.provision' }, { name: 'cloudron.restore', value: 'cloudron.restore' }, { name: 'cloudron.start', value: 'cloudron.start' }, { name: 'cloudron.update', value: 'cloudron.update' }, { name: 'cloudron.update.finish', value: 'cloudron.update.finish' }, { name: 'dashboard.domain.update', value: 'dashboard.domain.update' }, { name: 'dyndns.update', value: 'dyndns.update' }, { name: 'domain.add', value: 'domain.add' }, { name: 'domain.update', value: 'domain.update' }, { name: 'domain.remove', value: 'domain.remove' }, { name: 'mail.enabled', value: 'mail.enabled' }, { name: 'mail.box.add', value: 'mail.box.add' }, { name: 'mail.box.update', value: 'mail.box.update' }, { name: 'mail.box.remove', value: 'mail.box.remove' }, { name: 'mail.list.add', value: 'mail.list.add' }, { name: 'mail.list.update', value: 'mail.list.update' }, { name: 'mail.list.remove', value: 'mail.list.remove' }, { name: 'support.ticket', value: 'support.ticket' }, { name: 'support.ssh', value: 'support.ssh' }, { name: 'user.add', value: 'user.add' }, { name: 'user.login', value: 'user.login' }, { name: 'user.remove', value: 'user.remove' }, { name: 'user.transfer', value: 'user.transfer' }, { name: 'user.update', value: 'user.update' }, { name: 'System Crash', value: 'system.crash' } ]; $scope.pageItemCount = [ { name: 'Show 20 per page', value: 20 }, { name: 'Show 50 per page', value: 50 }, { name: 'Show 100 per page', value: 100 } ]; $scope.currentPage = 1; $scope.pageItems = $scope.pageItemCount[0]; $scope.action = ''; $scope.selectedActions = []; $scope.search = ''; function eventLogDetails(eventLog) { var ACTION_ACTIVATE = 'cloudron.activate'; var ACTION_PROVISION = 'cloudron.provision'; var ACTION_RESTORE = 'cloudron.restore'; var ACTION_APP_CLONE = 'app.clone'; var ACTION_APP_REPAIR = 'app.repair'; var ACTION_APP_CONFIGURE = 'app.configure'; var ACTION_APP_INSTALL = 'app.install'; var ACTION_APP_RESTORE = 'app.restore'; var ACTION_APP_UNINSTALL = 'app.uninstall'; var ACTION_APP_UPDATE = 'app.update'; var ACTION_APP_UPDATE_FINISH = 'app.update.finish'; var ACTION_APP_LOGIN = 'app.login'; var ACTION_APP_OOM = 'app.oom'; var ACTION_APP_UP = 'app.up'; var ACTION_APP_DOWN = 'app.down'; var ACTION_APP_START = 'app.start'; var ACTION_APP_STOP = 'app.stop'; var ACTION_APP_RESTART = 'app.restart'; var ACTION_BACKUP_FINISH = 'backup.finish'; var ACTION_BACKUP_START = 'backup.start'; var ACTION_BACKUP_CLEANUP_START = 'backup.cleanup.start'; var ACTION_BACKUP_CLEANUP_FINISH = 'backup.cleanup.finish'; var ACTION_CERTIFICATE_NEW = 'certificate.new'; var ACTION_CERTIFICATE_RENEWAL = 'certificate.renew'; var ACTION_DASHBOARD_DOMAIN_UPDATE = 'dashboard.domain.update'; var ACTION_DOMAIN_ADD = 'domain.add'; var ACTION_DOMAIN_UPDATE = 'domain.update'; var ACTION_DOMAIN_REMOVE = 'domain.remove'; var ACTION_START = 'cloudron.start'; var ACTION_UPDATE = 'cloudron.update'; var ACTION_UPDATE_FINISH = 'cloudron.update.finish'; var ACTION_USER_ADD = 'user.add'; var ACTION_USER_LOGIN = 'user.login'; var ACTION_USER_REMOVE = 'user.remove'; var ACTION_USER_UPDATE = 'user.update'; var ACTION_USER_TRANSFER = 'user.transfer'; var ACTION_MAIL_ENABLED = 'mail.enabled'; var ACTION_MAIL_DISABLED = 'mail.disabled'; var ACTION_MAIL_MAILBOX_ADD = 'mail.box.add'; var ACTION_MAIL_MAILBOX_UPDATE = 'mail.box.update'; var ACTION_MAIL_MAILBOX_REMOVE = 'mail.box.remove'; var ACTION_MAIL_LIST_ADD = 'mail.list.add'; var ACTION_MAIL_LIST_UPDATE = 'mail.list.update'; var ACTION_MAIL_LIST_REMOVE = 'mail.list.remove'; var ACTION_SUPPORT_TICKET = 'support.ticket'; var ACTION_SUPPORT_SSH = 'support.ssh'; var ACTION_DYNDNS_UPDATE = 'dyndns.update'; var ACTION_SYSTEM_CRASH = 'system.crash'; var data = eventLog.data; var errorMessage = data.errorMessage; var details, app; function appName(app) { return (app.label || app.fqdn || app.location) + ' (' + app.manifest.title + ')'; } switch (eventLog.action) { case ACTION_ACTIVATE: return 'Cloudron was activated'; case ACTION_PROVISION: return 'Cloudron was setup'; case ACTION_RESTORE: return 'Cloudron was restored using backup ' + data.backupId; case ACTION_APP_CONFIGURE: { if (!data.app) return ''; app = data.app; var q = function (x) { return '"' + x + '"'; }; if ('accessRestriction' in data) { // since it can be null return 'Access restriction of ' + appName(app) + ' was changed'; } else if (data.label) { return 'Label of ' + appName(app) + ' was set to ' + q(data.label); } else if (data.tags) { return 'Tags of ' + appName(app) + ' was set to ' + q(data.tags.join(',')); } else if (data.icon) { return 'Icon of ' + appName(app) + ' was changed'; } else if (data.memoryLimit) { return 'Memory limit of ' + appName(app) + ' was set to ' + data.memoryLimit; } else if (data.cpuShares) { return 'CPU shares of ' + appName(app) + ' was set to ' + Math.round((data.cpuShares * 100)/1024) + '%'; } else if (data.env) { return 'Env vars of ' + appName(app) + ' was changed'; } else if ('debugMode' in data) { // since it can be null if (data.debugMode) { return appName(app) + ' was placed in repair mode'; } else { return appName(app) + ' was taken out of repair mode'; } } else if ('enableBackup' in data) { return 'Automatic backups of ' + appName(app) + ' was ' + (data.enableBackup ? 'enabled' : 'disabled'); } else if ('enableAutomaticUpdate' in data) { return 'Automatic updates of ' + appName(app) + ' was ' + (data.enableAutomaticUpdate ? 'enabled' : 'disabled'); } else if ('reverseProxyConfig' in data) { return 'Reverse proxy configuration of ' + appName(app) + ' was updated'; } else if ('cert' in data) { if (data.cert) { return 'Custom certificate was set for ' + appName(app); } else { return 'Certificate of ' + appName(app) + ' was reset'; } } else if (data.location) { if (data.fqdn !== data.app.fqdn) { return 'Location of ' + appName(app) + ' was changed to ' + data.fqdn; } else if (!angular.equals(data.alternateDomains, data.app.alternateDomains)) { var altFqdns = data.alternateDomains.map(function (a) { return a.fqdn; }); return 'Alternate domains of ' + appName(app) + ' was ' + (altFqdns.length ? 'set to ' + altFqdns.join(', ') : 'reset'); } else if (!angular.equals(data.portBindings, data.app.portBindings)) { return 'Port bindings of ' + appName(app) + ' was changed'; } } else if ('dataDir' in data) { if (data.dataDir) { return 'Data directory of ' + appName(app) + ' was set ' + data.dataDir; } else { return 'Data directory of ' + appName(app) + ' was reset'; } } else if ('icon' in data) { if (data.icon) { return 'Icon of ' + appName(app) + ' was set'; } else { return 'Icon of ' + appName(app) + ' was reset'; } } else if (('mailboxName' in data) && data.mailboxName !== data.app.mailboxName) { if (data.mailboxName) { return 'Mailbox of ' + appName(app) + ' was set to ' + q(data.mailboxName); } else { return 'Mailbox of ' + appName(app) + ' was reset'; } } return appName(app) + ' was re-configured'; } case ACTION_APP_INSTALL: if (!data.app) return ''; return data.app.manifest.title + ' (package v' + data.app.manifest.version + ') was installed at ' + (data.app.fqdn || data.app.location); case ACTION_APP_RESTORE: if (!data.app) return ''; details = data.app.manifest.title + ' was restored at ' + (data.app.fqdn || data.app.location); // older versions (<3.5) did not have these fields if (data.fromManifest) details += ' from version ' + data.fromManifest.version; if (data.toManifest) details += ' to version ' + data.toManifest.version; if (data.backupId) details += ' using backup ' + data.backupId; return details; case ACTION_APP_UNINSTALL: if (!data.app) return ''; return data.app.manifest.title + ' (package v' + data.app.manifest.version + ') was uninstalled at ' + (data.app.fqdn || data.app.location); case ACTION_APP_UPDATE: if (!data.app) return ''; return 'Update of ' + data.app.manifest.title + ' at ' + (data.app.fqdn || data.app.location) + ' started from v' + data.fromManifest.version + ' to v' + data.toManifest.version; case ACTION_APP_UPDATE_FINISH: if (!data.app) return ''; return data.app.manifest.title + ' at ' + (data.app.fqdn || data.app.location) + ' was updated to v' + data.app.manifest.version; case ACTION_APP_CLONE: return data.newApp.manifest.title + ' at ' + (data.newApp.fqdn || data.newApp.location) + ' was cloned from ' + (data.oldApp.fqdn || data.oldApp.location) + ' using backup ' + data.backupId + ' with v' + data.oldApp.manifest.version; case ACTION_APP_REPAIR: return 'App ' + appName(data.app) + ' was repaired'; case ACTION_APP_LOGIN: { app = Client.getCachedAppSync(data.appId); if (!app) return ''; return 'App ' + app.fqdn + ' logged in'; } case ACTION_APP_OOM: if (!data.app) return ''; return appName(data.app) + ' ran out of memory'; case ACTION_APP_DOWN: if (!data.app) return ''; return appName(data.app) + ' is down'; case ACTION_APP_UP: if (!data.app) return ''; return appName(data.app) + ' is back online'; case ACTION_APP_START: if (!data.app) return ''; return appName(data.app) + ' was started'; case ACTION_APP_STOP: if (!data.app) return ''; return appName(data.app) + ' was stopped'; case ACTION_APP_RESTART: if (!data.app) return ''; return appName(data.app) + ' was restarted'; case ACTION_BACKUP_START: return 'Backup started'; case ACTION_BACKUP_FINISH: if (!errorMessage) { return 'Cloudron backup created with Id ' + data.backupId; } else { return 'Cloudron backup errored with error: ' + errorMessage; } case ACTION_BACKUP_CLEANUP_START: return 'Backup cleaner started'; case ACTION_BACKUP_CLEANUP_FINISH: return data.errorMessage ? 'Backup cleaner errored: ' + data.errorMessage : 'Backup cleaner removed ' + data.removedBoxBackups.length + ' backups'; case ACTION_CERTIFICATE_NEW: return 'Certificate install for ' + data.domain + (errorMessage ? ' failed' : ' succeeded'); case ACTION_CERTIFICATE_RENEWAL: return 'Certificate renewal for ' + data.domain + (errorMessage ? ' failed' : ' succeeded'); case ACTION_DASHBOARD_DOMAIN_UPDATE: return 'Dashboard domain set to ' + data.fqdn; case ACTION_DOMAIN_ADD: return 'Domain ' + data.domain + ' with ' + data.provider + ' provider was added'; case ACTION_DOMAIN_UPDATE: return 'Domain ' + data.domain + ' with ' + data.provider + ' provider was updated'; case ACTION_DOMAIN_REMOVE: return 'Domain ' + data.domain + ' was removed'; case ACTION_MAIL_ENABLED: return 'Cloudron Mail was enabled for domain ' + data.domain; case ACTION_MAIL_DISABLED: return 'Cloudron Mail was disabled for domain ' + data.domain; case ACTION_MAIL_MAILBOX_ADD: return 'Mailbox with name ' + data.name + ' was added in domain ' + data.domain; case ACTION_MAIL_MAILBOX_UPDATE: return 'Mailbox with name ' + data.name + ' was updated in domain ' + data.domain; case ACTION_MAIL_MAILBOX_REMOVE: return 'Mailbox with name ' + data.name + ' was removed in domain ' + data.domain; case ACTION_MAIL_LIST_ADD: return 'Mail list with name ' + data.name + ' was added in domain ' + data.domain; case ACTION_MAIL_LIST_UPDATE: return 'Mail list with name ' + data.name + ' was updated in domain ' + data.domain; case ACTION_MAIL_LIST_REMOVE: return 'Mail list with name ' + data.name + ' was removed in domain ' + data.domain; case ACTION_START: return 'Cloudron started with version ' + data.version; case ACTION_UPDATE: return 'Cloudron update to version ' + data.boxUpdateInfo.version + ' was started'; case ACTION_UPDATE_FINISH: if (data.errorMessage) { return 'Cloudron update errored. Error: ' + data.errorMessage; } else { return 'Cloudron updated to version ' + data.newVersion; } case ACTION_USER_ADD: return data.email + (data.user.username ? ' (' + data.user.username + ')' : '') + ' was added'; case ACTION_USER_UPDATE: return (data.user ? (data.user.email + (data.user.username ? ' (' + data.user.username + ')' : '')) : data.userId) + ' was updated'; case ACTION_USER_REMOVE: return (data.user ? (data.user.email + (data.user.username ? ' (' + data.user.username + ')' : '')) : data.userId) + ' was removed'; case ACTION_USER_TRANSFER: return 'Apps of ' + data.oldOwnerId + ' was transferred to ' + data.newOwnerId; case ACTION_USER_LOGIN: return (data.user ? data.user.username : data.userId) + ' logged in'; case ACTION_DYNDNS_UPDATE: return 'DNS was updated from ' + data.fromIp + ' to ' + data.toIp; case ACTION_SUPPORT_SSH: return 'Remote Support was ' + (data.enable ? 'enabled' : 'disabled'); case ACTION_SUPPORT_TICKET: return 'Support ticket was created'; case ACTION_SYSTEM_CRASH: return 'A system process crashed'; default: return eventLog.action; } } function eventLogSource(eventLog) { var source = eventLog.source; var line = ''; line = source.username || source.userId || source.mailboxId || source.authType || 'system'; if (source.appId) { var app = Client.getCachedAppSync(source.appId); line += ' - ' + (app ? app.fqdn : source.appId); } else if (source.ip) { line += ' - ' + source.ip; } return line; } function fetchEventLogs() { $scope.busy = true; var actions = $scope.selectedActions.map(function (a) { return a.value; }).join(', '); Client.getEventLogs(actions, $scope.search || null, $scope.currentPage, $scope.pageItems.value, function (error, result) { $scope.busy = false; if (error) return console.error(error); $scope.eventLogs = []; result.forEach(function (e) { $scope.eventLogs.push({ raw: e, details: eventLogDetails(e), source: eventLogSource(e) }); }); }); } $scope.showNextPage = function () { $scope.currentPage++; fetchEventLogs(); }; $scope.showPrevPage = function () { if ($scope.currentPage > 1) $scope.currentPage--; else $scope.currentPage = 1; fetchEventLogs(); }; $scope.updateFilter = function (fresh) { if (fresh) $scope.currentPage = 1; fetchEventLogs(); }; $scope.showEventLogDetails = function (eventLog) { if ($scope.activeEventLog === eventLog) $scope.activeEventLog = null; else $scope.activeEventLog = eventLog; }; Client.onReady(function () { fetchEventLogs(); }); $('.modal-backdrop').remove(); }]);